// Clint - Source code checker for C++ // Copyright (C) 2001 David Pashley // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "input.h" #include "config.h" #include #ifdef HAVE_SSTREAM #include #else #include #endif // HAVE_SSTREAM namespace clint { Input * Input::m_instance = 0; Input * Input::instance() { if ( m_instance == 0 ) { m_instance = new Input; } return m_instance; } Input::Input() { m_cur_file.input = &std::cin; m_cur_file.file = ""; m_cur_file.line = 0; m_input_set = false; } void Input::set_input(std::string filename) { if (not m_input_set) { m_cur_file.file = filename; m_cur_file.input = new std::ifstream( filename.c_str() ); m_input_set = true; } } const Pair Input::getline() { Pair temp; // prevent changing the input if we have started to read lines if (not m_input_set) { m_input_set = true; } std::string line; std::getline(*m_cur_file.input, line); temp.first = line; //line = parse_cpp(line); m_cur_file.line++; temp.second = line; return temp; } // Use a recursive decent parser for cpp std::string Input::parse_cpp(std::string line) { if (line[0] == '#') { #ifdef HAVE_SSTREAM std::istringstream in(line); #else istrstream in(line.c_str()); #endif // HAVE_SSTREAM in.get(); // remove '#' std::string command; while (isalnum(in.peek()) && not in.eof()){ command+=in.get(); } std::cerr << "line = \"" << line << "\" command = \"" << command << "\" "; if (command == std::string("include") ) { } else if ( command == "define" ) { } else if ( command == "undef" ) { } else if ( command == "if" ) { } else if ( command == "ifdef" ) { } else if ( command == "ifndef" ) { } else if ( command == "else" ) { } else if ( command == "elif" ) { } else if ( command == "endif" ) { } else if ( command == "line" ) { } else if ( command == "error" ) { // Should we have a message? } else if ( command == "warning" ) { // This isn't in the C++ grammar // Should we have a message? } else if ( command == "pragma" ) { // Ignore this } else if ( command == "" ) { // Apparently this is valid // Ignore this } else { std::cerr << "Unknown preprocessor macro" << std::endl; } } return line; } const int Input::line() const { return m_cur_file.line; } const std::string Input::file() const { return m_cur_file.file; } bool Input::eof() const { return ( ( 0 == m_file_status.size() ) and m_cur_file.input->eof() ); } void Input::add_include(std::string include) { m_includes.push_back(include); } void Input::add_define(std::string define, std::string value) { m_defines[define] = value; } bool Input::is_system_header() const { std::string directory(m_cur_file.file, 0, m_cur_file.file.rfind('/')); std::cerr << directory << std::endl; return is_header() and ( find( m_includes.begin(), m_includes.end(), directory ) != m_includes.end() ); } bool Input::is_header() const { std::string extension(m_cur_file.file, m_cur_file.file.rfind('.') + 1, std::string::npos); return ( extension == "h" or extension == "hxx" or extension == "hpp" ); } }