// 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 <algorithm>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#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 = "<stdin>";
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" );
}
}
syntax highlighted by Code2HTML, v. 0.9.1