/* Csound Include Expander Anthony Kozar March 24, 2006 I am releasing this code into the public domain. Do whatever you wish with it. */ #include #include #include #include //#include #include #include using namespace std; /* Global Declarations */ /* Function Prototypes */ void ExpandIncludes( const std::string& filename); bool AnyNonWhitespace( const std::string& s ); void ReadString(istream& sin, string& str); void SkipWhiteSpace( istream& source ); void ReadUntil( istream& source, string& result, const string& delimiters, bool eat_delimiter ); /* Main Program Starts */ int main(int argc, char** argv) { string filename; /* Usage: programname [inputfile] > outputfile */ if (argc < 2) { cerr << "Enter your csd/orc/sco file name: "; getline( cin, filename ); } else filename = argv[1]; ExpandIncludes(filename); return EXIT_SUCCESS; } void ExpandIncludes( const std::string& filename) { ifstream fin; bool atEOF = false; if (filename.empty()) return; fin.open( filename.c_str() ); if ( !fin ) { cerr << "Error opening the file: " << filename << endl; return; } /* Read in one line at a time and look for #include */ while ( fin.good() ) { stringstream ss; string line; bool printline; printline = true; getline( fin, line ); if ( !fin.fail() ) { if ( AnyNonWhitespace(line) ) { // if line is not blank ss.str(line); string word; string includename; ss >> word; // get first whitespace-separated word if (word.compare("#include") == 0) { ReadString(ss, includename); ExpandIncludes(includename); // recursively expand #Includes printline = false; } } if (printline) cout << line << endl; // output goes to stdout } } return; } bool AnyNonWhitespace( const std::string& s ) { std::string::size_type len = s.length(); for ( std::string::size_type pos = 0; pos < len; ++pos ) if ( ! isspace( s.at(pos) ) ) return true; return false; } void ReadString(istream& sin, string& str) { string delimiter; SkipWhiteSpace(sin); delimiter += sin.get(); ReadUntil(sin, str, delimiter, true); return; } /* SkipWhiteSpace() Read characters from an istream (could be ifstream file or stringstream) until it encounters a non-whitespace character. */ void SkipWhiteSpace( istream& source ) { char next; while ( source.good() ) { if ( (next = source.peek()) != EOF ) { if ( isspace(next) ) { source.ignore(); } else { break; } } else source.setstate( ios_base::failbit ); // set failbit of stream source } return; } /* ReadUntil() Read characters from an istream (could be ifstream file or stringstream) until it encounters one of the characters listed in the string "delimiters". Returns the input string as "result". The delimiter is discarded if "eat_delimiter" is true. */ void ReadUntil( istream& source, string& result, const string& delimiters, bool eat_delimiter ) { char next; result = ""; while ( source.good() ) { if ( (next = source.peek()) != EOF ) { if ( delimiters.find(next) != string::npos) { // found one of the delimiters if ( eat_delimiter ) { source.ignore(); } break; } else { result += source.get(); } } else source.setstate( ios_base::failbit ); // set failbit of stream source } return; }