// gencharset.cpp // Revision 31-jul-2004 #include #include #include #include #include // bitset in gcc 2.95 uses min whithout defining it. // Then we include something that does. #include #include using std::istream; using std::ostream; using std::cerr; using std::endl; using std::string; using std::runtime_error; void gencharset (const string & fin, const string & fout, const std::string & name); void readcharset (istream & in); void writecharset (ostream & out, const std::string & name); size_t linenumber= 0; int main (int argc, char * * argv) { try { string fin, fout, name; if (argc > 1) fin= argv [1]; if (argc > 2) fout= argv [2]; if (argc > 3) name= argv [3]; gencharset (fin, fout, name); } catch (std::exception & e) { cerr << e.what (); if (linenumber != 0) cerr << " in line " << linenumber; cerr << endl; } } typedef unsigned char chardata [8]; chardata default_data; bool default_defined= false; chardata data [256]; bool data_defined [256]= { false }; void gencharset (const string & fin, const string & fout, const std::string & name) { istream * pin; if (fin.empty () ) pin= & std::cin; else { std::ifstream * pinf= new std::ifstream (fin.c_str () ); if (! pinf->is_open () ) throw runtime_error ("File not found"); pin= pinf; } readcharset (* pin); if (! fin.empty () ) delete pin; linenumber= 0; ostream * pout; if (fout.empty () ) pout= & std::cout; else { std::ofstream * poutf= new std::ofstream (fout.c_str () ); if (! poutf->is_open () ) throw runtime_error ("Cannot create output file"); pout= poutf; } writecharset (* pout, name); if (! fout.empty () ) delete pout; } bool readline (istream & in, string & str) { do { std::getline (in, str); if (! in) return false; ++ linenumber; string::size_type l= str.size (); if (l > 0 && str [l - 1] == '\r') str= str.substr (0, l - 1); } while (str.empty () || str [0] == '#'); return true; } void readchar (istream & in, chardata & chd) { string str; bool invert= false; for (int i= 0; i < 8; ++i) { if (! readline (in, str) ) throw runtime_error ("Unexpected eof"); if (str == "INVERT") { invert= true; if (! readline (in, str) ) throw runtime_error ("Unexpected eof"); } std::bitset <8> b (str); unsigned long l= b.to_ulong (); if (invert) l= ~ l; chd [i]= static_cast (l); } } unsigned char getcharcode (const string & str) { if (str.size () == 1) return str [0]; std::istringstream iss (str); unsigned int u; iss >> u; if (! iss) throw runtime_error ("Syntax error"); char c; iss >> c; if (! iss.eof () ) throw runtime_error ("Syntax error"); if (u > 255) throw runtime_error ("Invalid char number"); return static_cast (u); } void readcharset (istream & in) { string str; while (readline (in, str) ) { //cerr << str << endl; if (str == "DEFAULT") { if (default_defined) throw runtime_error ("Default already defined"); //cerr << "Defining default" << endl; readchar (in, default_data); default_defined= true; } else { unsigned char ch= getcharcode (str); //cerr << "Defining char: "; //if (ch >= 32) cerr << ch; //else cerr << static_cast (ch); //cerr << endl; if (data_defined [ch] ) throw runtime_error ("Char already defined"); readchar (in, data [ch] ); data_defined [ch]= true; } } } void writecharset (ostream & out, const std::string & name) { if (name.empty () ) out << "// charset.cpp\n"; else out << "// charset_" << name << ".cpp\n"; out << "// Automatically generated, do not edit.\n" "\n" "#include \"charset.h\"\n" "\n" "const charset::chardataset charset::"; if (name.empty () ) out << "default"; else out << name; out << "_data= {\n" ; for (int i= 0; i < 256; ++i) { out << "\t// char " << i << "\n\t{ "; chardata * pdata; if (data_defined [i] ) pdata= & data [i]; else pdata= & default_data; for (int j= 0; j < 8; ++j) { out << static_cast ( (* pdata) [j] ); if (j < 7) out << ", "; } out << " },\n"; } out << "};\n" "\n" "//End of charset.cpp\n" ; } // End of gencharset.cpp