aboutsummaryrefslogtreecommitdiffstats
path: root/gencharset.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gencharset.cpp')
-rw-r--r--gencharset.cpp221
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
Un proyecto texto-plano.xyz