NetBSD-5.0.2/dist/atf/tests/atf/formats/h_parser.cpp

//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

extern "C" {
#include <fcntl.h>
}

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

extern "C" {
#include "atf-c/object.h"
}

#include "atf-c++/formats.hpp"
#include "atf-c++/io.hpp"
#include "atf-c++/parser.hpp"
#include "atf-c++/sanity.hpp"

class atffile_reader : protected atf::formats::atf_atffile_reader {
    void
    got_conf(const std::string& name, const std::string& val)
    {
        std::cout << "got_conf(" << name << ", " << val << ")" << std::endl;
    }

    void
    got_prop(const std::string& name, const std::string& val)
    {
        std::cout << "got_prop(" << name << ", " << val << ")" << std::endl;
    }

    void
    got_tp(const std::string& name, bool isglob)
    {
        std::cout << "got_tp(" << name << ", " << (isglob ? "true" : "false")
                  << ")" << std::endl;
    }

    void
    got_eof(void)
    {
        std::cout << "got_eof()" << std::endl;
    }

public:
    atffile_reader(std::istream& is) :
        atf::formats::atf_atffile_reader(is)
    {
    }

    void
    read(const std::string& outname, const std::string& errname)
    {
        atf_atffile_reader::read();
    }
};

class config_reader : protected atf::formats::atf_config_reader {
    void
    got_var(const std::string& name, const std::string& val)
    {
        std::cout << "got_var(" << name << ", " << val << ")" << std::endl;
    }

    void
    got_eof(void)
    {
        std::cout << "got_eof()" << std::endl;
    }

public:
    config_reader(std::istream& is) :
        atf::formats::atf_config_reader(is)
    {
    }

    void
    read(const std::string& outname, const std::string& errname)
    {
        atf_config_reader::read();
    }
};

class tcs_reader : protected atf::formats::atf_tcs_reader {
    void
    got_ntcs(size_t ntcs)
    {
        std::cout << "got_ntcs(" << ntcs << ")" << std::endl;
    }

    void
    got_tc_start(const std::string& tcname)
    {
        std::cout << "got_tc_start(" << tcname << ")" << std::endl;
    }

    void
    got_tc_end(const atf::tests::tcr& tcr)
    {
        std::string r;
        if (tcr.get_state() == atf::tests::tcr::passed_state)
            r = "passed";
        else if (tcr.get_state() == atf::tests::tcr::failed_state)
            r = "failed, " + tcr.get_reason();
        else if (tcr.get_state() == atf::tests::tcr::skipped_state)
            r = "skipped, " + tcr.get_reason();
        else
            UNREACHABLE;

        std::cout << "got_tc_end(" << r << ")" << std::endl;
    }

    void
    got_stdout_line(const std::string& line)
    {
        std::cout << "got_stdout_line(" << line << ")" << std::endl;
    }

    void
    got_stderr_line(const std::string& line)
    {
        std::cout << "got_stderr_line(" << line << ")" << std::endl;
    }

    void
    got_eof(void)
    {
        std::cout << "got_eof()" << std::endl;
    }

public:
    tcs_reader(std::istream& is) :
        atf::formats::atf_tcs_reader(is)
    {
    }

    void
    read(const std::string& outname, const std::string& errname)
    {
        int outfd = ::open(outname.c_str(), O_RDONLY);
        if (outfd == -1)
            throw std::runtime_error("Failed to open " + outname);
        atf::io::file_handle outfh(outfd);

        int errfd = ::open(errname.c_str(), O_RDONLY);
        if (errfd == -1)
            throw std::runtime_error("Failed to open " + errname);
        atf::io::file_handle errfh(errfd);

        atf::io::unbuffered_istream outin(outfh);
        atf::io::unbuffered_istream errin(errfh);
        atf_tcs_reader::read(outin, errin);
    }
};

class tps_reader : protected atf::formats::atf_tps_reader {
    void
    got_info(const std::string& what, const std::string& val)
    {
        std::cout << "got_info(" << what << ", " << val << ")" << std::endl;
    }

    void
    got_ntps(size_t ntps)
    {
        std::cout << "got_ntps(" << ntps << ")" << std::endl;
    }

    void
    got_tp_start(const std::string& tpname, size_t ntcs)
    {
        std::cout << "got_tp_start(" << tpname << ", " << ntcs << ")"
                  << std::endl;
    }

    void
    got_tp_end(const std::string& reason)
    {
        std::cout << "got_tp_end(" << reason << ")" << std::endl;
    }

    void
    got_tc_start(const std::string& tcname)
    {
        std::cout << "got_tc_start(" << tcname << ")" << std::endl;
    }

    void
    got_tc_end(const atf::tests::tcr& tcr)
    {
        std::string r;
        if (tcr.get_state() == atf::tests::tcr::passed_state)
            r = "passed";
        else if (tcr.get_state() == atf::tests::tcr::failed_state)
            r = "failed, " + tcr.get_reason();
        else if (tcr.get_state() == atf::tests::tcr::skipped_state)
            r = "skipped, " + tcr.get_reason();
        else
            UNREACHABLE;

        std::cout << "got_tc_end(" << r << ")" << std::endl;
    }

    void
    got_tc_stdout_line(const std::string& line)
    {
        std::cout << "got_tc_stdout_line(" << line << ")" << std::endl;
    }

    void
    got_tc_stderr_line(const std::string& line)
    {
        std::cout << "got_tc_stderr_line(" << line << ")" << std::endl;
    }

    void
    got_eof(void)
    {
        std::cout << "got_eof()" << std::endl;
    }

public:
    tps_reader(std::istream& is) :
        atf::formats::atf_tps_reader(is)
    {
    }

    void
    read(const std::string& outname, const std::string& errname)
    {
        atf_tps_reader::read();
    }
};

template< class R >
void
process(const std::string& file, const std::string& outname = "",
        const std::string& errname = "")
{
    try {
        std::ifstream is(file.c_str());
        if (!is)
            throw std::runtime_error("Cannot open `" + file + "'");
        R reader(is);
        reader.read(outname, errname);
    } catch (const atf::parser::parse_errors& pes) {
        std::cerr << pes.what();
    } catch (const atf::parser::parse_error& pe) {
        std::cerr << "LONELY PARSE ERROR: " << pe.first << ": "
                  << pe.second << std::endl;
    }
}

int
main(int argc, char* argv[])
{
    atf_init_objects();

    try {
        if (argc < 3) {
            std::cerr << "Missing arguments" << std::endl;
            return EXIT_FAILURE;
        }
        std::string format(argv[1]);
        std::string file(argv[2]);

        if (format == std::string("application/X-atf-atffile")) {
            process< atffile_reader >(file);
        } else if (format == std::string("application/X-atf-config")) {
            process< config_reader >(file);
        } else if (format == std::string("application/X-atf-tcs")) {
            if (argc < 5) {
                std::cerr << "Missing arguments" << std::endl;
                return EXIT_FAILURE;
            }
            process< tcs_reader >(file, argv[3], argv[4]);
        } else if (format == std::string("application/X-atf-tps")) {
            process< tps_reader >(file);
        } else {
            std::cerr << "Unknown format " << format << std::endl;
        }
    } catch (const atf::formats::format_error& e) {
        std::cerr << "Header format error: " << e.what() << std::endl;
    } catch (const std::runtime_error& e) {
        std::cerr << "UNEXPECTED ERROR: " << e.what() << std::endl;
    } catch (...) {
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}