summaryrefslogtreecommitdiff
path: root/ACE/apps/mkcsregdb/mkcsregdb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/apps/mkcsregdb/mkcsregdb.cpp')
-rw-r--r--ACE/apps/mkcsregdb/mkcsregdb.cpp328
1 files changed, 328 insertions, 0 deletions
diff --git a/ACE/apps/mkcsregdb/mkcsregdb.cpp b/ACE/apps/mkcsregdb/mkcsregdb.cpp
new file mode 100644
index 00000000000..2dc87b85bce
--- /dev/null
+++ b/ACE/apps/mkcsregdb/mkcsregdb.cpp
@@ -0,0 +1,328 @@
+/* $Id$
+ *
+ * To populate the registry_db, construct a codeset registry text file based
+ * on the OSF's Character and Code Set Registry. See DCE RFC 40.1 for details
+ * on obtaining the full text for the current registry. Once you have composed
+ * a text file containing all the desired codeset information, build and run
+ * mkcsregdb. The source is in $ACE_ROOT/apps/mkcsregdb. It will generate a new
+ * copy of this file, with the registry_db_ array properly initialized.
+ */
+
+// FUZZ: disable check_for_streams_include
+#include "ace/streams.h"
+
+#include "ace/Codeset_Registry.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_sys_stat.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+
+class csdb_generator : public ACE_Codeset_Registry
+{
+public:
+ csdb_generator ();
+ int read_from (const char *source);
+ int init_output (const char *srcfile);
+ int write_entry ();
+ int fini_output (const char *target);
+ int read_line ();
+ void write_dummy_entry();
+ void fail(const char *msg);
+private:
+ static const char * tags_[];
+ static int max_line_;
+ int count_;
+ int in_entry_;
+ registry_entry entry_;
+ int linecounter_;
+ char *source_line_;
+ char *line_data_;
+ ifstream *inf_;
+ FILE *outf_;
+ char *tempfilename_;
+ char *ace_src_;
+};
+
+int csdb_generator::max_line_ = 1024;
+const char * csdb_generator::tags_[] = {
+ "start",
+ "end",
+ "description ",
+ "loc_name ",
+ "rgy_value ",
+ "char_values ",
+ "max_bytes ",
+ 0
+};
+
+csdb_generator::csdb_generator ()
+ :count_(0),
+ in_entry_(0),
+ linecounter_(0),
+ source_line_ (new char[max_line_]),
+ line_data_ (0),
+ inf_ (0),
+ outf_ (0)
+{
+ ace_src_ = ACE_OS::getenv("ACE_ROOT");
+}
+
+void
+csdb_generator::fail (const char *msg)
+{
+ ACE_ERROR ((LM_ERROR,"Error, line %d: %s\n",linecounter_,msg));
+ ACE_OS::fclose (outf_);
+ ACE_OS::unlink (tempfilename_);
+ ACE_OS::exit (-1);
+}
+
+int
+csdb_generator::read_line()
+{
+ inf_->getline (source_line_,max_line_);
+ line_data_ = 0;
+ char *cpos = ACE_OS::strchr (source_line_,'#');
+ if (cpos == 0)
+ cpos = source_line_ + ACE_OS::strlen(source_line_);
+ while (cpos > source_line_ && ACE_OS::strchr(" \t",*(cpos - 1))) cpos--;
+ *cpos = 0;
+ if (cpos == source_line_)
+ return 0;
+ for (int i = 0; tags_[i]; i++)
+ {
+ cpos = ACE_OS::strstr (source_line_,tags_[i]);
+ if (cpos == 0) // not found
+ continue;
+ if (cpos > source_line_) // make sure it's first token
+ {
+ char *tpos = cpos-1;
+ while (tpos > source_line_ && ACE_OS::strchr(" \t",*tpos)) tpos--;
+ if (tpos > source_line_)
+ continue;
+ }
+ if (i == 0 && in_entry_)
+ fail ("\"start\" encountered twice before \"end\"");
+ if (i > 0 && !in_entry_)
+ {
+ char *emsg = new char[100];
+ ACE_OS::sprintf (emsg,"\"%s\" encountered before \"start\"",tags_[i]);
+ fail (emsg);
+ }
+ if (i > 1)
+ {
+ line_data_ = cpos + ACE_OS::strlen(tags_[i]);
+ while (*line_data_ && ACE_OS::strchr(" \t",(*line_data_)))
+ line_data_++;
+ }
+ return i+1;
+ }
+ return -1;
+}
+
+int
+csdb_generator::read_from (const char *srcfile)
+{
+ inf_ = new ifstream(srcfile);
+ char *ptr;
+ while (inf_->good() && !inf_->eof()) {
+ linecounter_++;
+ switch (read_line ()) {
+ case -1: // bogus line
+ fail ("unknown field tag");
+ break;
+ case 0: // comment or blank line
+ break;
+ case 1: // start
+ entry_.desc_ = 0;
+ entry_.loc_name_ = 0;
+ entry_.codeset_id_ = 0;
+ entry_.num_sets_ = 0;
+ entry_.max_bytes_ = 0;
+ in_entry_ = 1;
+ break;
+ case 2: // end
+ if (entry_.codeset_id_ == 0)
+ fail ("entry missing rgy_value");
+ if (entry_.num_sets_ == 0)
+ fail ("entry does not include at least one char_value");
+ if (entry_.max_bytes_ == 0)
+ fail ("entry does not define max_bytes");
+ write_entry ();
+ delete [] const_cast<char *> (entry_.desc_);
+ delete [] const_cast<char *> (entry_.loc_name_);
+ count_++;
+ in_entry_ = 0;
+ break;
+ case 3: // description
+ if (entry_.desc_ != 0)
+ fail ("duplicate description");
+ entry_.desc_ = ACE_OS::strdup(line_data_);
+ break;
+ case 4: // loc_name
+ if (entry_.loc_name_ != 0)
+ fail ("duplicate loc_name");
+ entry_.loc_name_ = ACE_OS::strdup(line_data_);
+ break;
+ case 5: // rgy_value
+ if (entry_.codeset_id_ != 0)
+ fail ("duplicate rgy_value");
+ entry_.codeset_id_ = ACE_OS::strtoul(line_data_,&ptr,16);
+ if (*ptr != 0 || entry_.codeset_id_ == 0)
+ {
+ char emsg [100];
+ ACE_OS::sprintf (emsg,"invalid rgy_value, '%s'",line_data_);
+ fail (emsg);
+ }
+ break;
+ case 6: // char_values
+ if (entry_.num_sets_ != 0)
+ fail ("duplicate char_values");
+ ptr = line_data_;
+ do {
+ if (*ptr == ':')
+ ptr++;
+ ACE_CDR::UShort tmp =
+ static_cast<ACE_CDR::UShort> (ACE_OS::strtoul(ptr,&ptr,16));
+ if (*ptr != 0 && *ptr != ':')
+ {
+ char *emsg = new char [100];
+ ACE_OS::sprintf (emsg,"invalid symbol \'%c\' in char_values",*ptr);
+ fail (emsg);
+ }
+ if (entry_.num_sets_ < max_charsets_)
+ entry_.char_sets_[entry_.num_sets_++] = tmp;
+ else entry_.num_sets_++;
+ } while (*ptr == ':');
+ if (entry_.num_sets_ > max_charsets_)
+ {
+ char *emsg = new char [200];
+ ACE_OS::sprintf (emsg,"max of %d char_values exceeded.\nIncrease ACE_Codeset_Registry::max_charsets_ to at least %d and rebuild mkcsregdb",max_charsets_,entry_.num_sets_);
+ fail (emsg);
+ }
+ break;
+ case 7: // max_bytes
+ if (entry_.max_bytes_ != 0)
+ fail ("duplicate max_bytes");
+ entry_.max_bytes_ =
+ static_cast<ACE_CDR::UShort> (ACE_OS::strtol(line_data_,&ptr,10));
+ if (*ptr != 0)
+ fail ("invalid max_bytes");
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+csdb_generator::init_output (const char *srcfile)
+{
+ ACE_stat buf;
+ if (ACE_OS::stat (srcfile,&buf) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"Unable to open %s\n",srcfile),-1);
+
+ if (ace_src_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,"You must first set $ACE_ROOT\n"),-1);
+
+ time_t now = ACE_OS::time();
+ tempfilename_ = ACE_OS::tempnam (ace_src_,"csdb");
+ outf_ = ACE_OS::fopen (tempfilename_,"w");
+ if (outf_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR, "Unable to open output file, %s\n",tempfilename_),-1);
+
+ ACE_OS::fprintf (outf_,"// $ID: $\n");
+ ACE_OS::fprintf (outf_,"/*\n * Codeset registry DB, generated %s * source: %s\n",
+ ACE_OS::asctime (ACE_OS::localtime(&now)),
+ srcfile);
+ ACE_OS::fprintf (outf_," *\n * To populate the registry_db, construct a codeset registry text file based \n");
+ ACE_OS::fprintf (outf_," * on the OSF's Character and Code Set Registry. See DCE RFC 40.1 for details\n");
+ ACE_OS::fprintf (outf_," * on obtaining the full text for the current registry. Once you have composed\n");
+ ACE_OS::fprintf (outf_," * a text file containing all the desired codeset information, build and run\n");
+ ACE_OS::fprintf (outf_," * mkcsregdb. The source is in $ACE_ROOT/apps/mkcsregdb. It will generate a new\n");
+ ACE_OS::fprintf (outf_," * copy of this file, with the registry_db_ array properly initialized.\n */\n");
+ ACE_OS::fprintf (outf_,"\n#include \"ace/Codeset_Registry.h\"\n\n%s\n%s\n{\n",
+ "ACE_Codeset_Registry::registry_entry const",
+ "ACE_Codeset_Registry::registry_db_[] =");
+ return 0;
+}
+
+int
+csdb_generator::write_entry ()
+{
+ if (count_)
+ ACE_OS::fprintf (outf_,",\n");
+ ACE_OS::fprintf (outf_," {\"%s\",\"%s\",0x%08x,%d,{",
+ entry_.desc_,
+ entry_.loc_name_,
+ entry_.codeset_id_,
+ entry_.num_sets_);
+ for (ACE_CDR::UShort j = 0; j < entry_.num_sets_; j++)
+ if (j+1 < entry_.num_sets_)
+ ACE_OS::fprintf (outf_,"0x%04x,",entry_.char_sets_[j]);
+ else
+ ACE_OS::fprintf (outf_,"0x%04x",entry_.char_sets_[j]);
+ ACE_OS::fprintf (outf_,"},%d}",entry_.max_bytes_);
+ return 0;
+}
+
+void
+csdb_generator::write_dummy_entry()
+{
+ entry_.desc_ = "No codesets defined";
+ entry_.loc_name_ = "NONE";
+ entry_.codeset_id_ = 0;
+ entry_.num_sets_ = 1;
+ entry_.char_sets_[0] = 0;
+ entry_.max_bytes_ = 0;
+ write_entry();
+}
+
+int
+csdb_generator::fini_output (const char *tgt)
+{
+ char *target = new char [ACE_OS::strlen(ace_src_) + ACE_OS::strlen(tgt) + 6];
+ ACE_OS::sprintf (target,"%s/ace/%s",ace_src_,tgt);
+ if (count_ == 0)
+ write_dummy_entry();
+ ACE_OS::fprintf (outf_,"\n};\n\nsize_t const ACE_Codeset_Registry::num_registry_entries_ = %d;\n\n",count_);
+ ACE_OS::fclose (outf_);
+ ACE_stat buf;
+ if (ACE_OS::stat (target,&buf) == 0)
+ {
+ char fname[200];
+ int result = 0;
+ for (int i = 0; result == 0; i++)
+ {
+ ACE_OS::sprintf (fname,"%s.%03d",target,i);
+ result = ACE_OS::stat(fname,&buf);
+ }
+ ACE_DEBUG ((LM_DEBUG,"Moving $ACE_ROOT/ace/%s to $ACE_ROOT/ace%s\n",
+ tgt,ACE_OS::strrchr(fname,'/')));
+ if (ACE_OS::rename (target,fname) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"Could not create %s\n, output stored in %s",
+ fname,tempfilename_),-1);
+ }
+ ACE_DEBUG ((LM_DEBUG,"writing $ACE_ROOT/ace/%s\n",tgt));
+ if (ACE_OS::rename (tempfilename_,target) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,"Could not create %s\n, output stored in %s",
+ target,tempfilename_),-1);
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ ACE_CString srcname;
+ if (argc > 1)
+ srcname.set(argv[1]);
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,"Usage: %s <source_file>\nwhere source file is the full path to a code set registry text file.\n",argv[0]),-1);
+ csdb_generator csdb;
+ if (csdb.init_output(srcname.c_str()) == -1)
+ return 0;
+ if (csdb.read_from (srcname.c_str()) == 0)
+ csdb.fini_output ("Codeset_Registry_db.cpp");
+ return 0;
+}