diff options
Diffstat (limited to 'gencharset.cpp')
-rw-r--r-- | gencharset.cpp | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/gencharset.cpp b/gencharset.cpp new file mode 100644 index 0000000..716c2ac --- /dev/null +++ b/gencharset.cpp @@ -0,0 +1,221 @@ +// gencharset.cpp +// Revision 31-jul-2004 + +#include <iostream> +#include <fstream> +#include <string> +#include <stdexcept> +#include <sstream> +// bitset in gcc 2.95 uses min whithout defining it. +// Then we include something that does. +#include <algorithm> +#include <bitset> + +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 <unsigned char> (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 <unsigned char> (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 <unsigned int> (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 <unsigned int> ( (* pdata) [j] ); + if (j < 7) out << ", "; + } + out << " },\n"; + } + out << + +"};\n" +"\n" +"//End of charset.cpp\n" + ; +} + +// End of gencharset.cpp |