Cleanup ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE, all platforms support it so far as I can...
[ACE_TAO.git] / ACE / apps / mkcsregdb / mkcsregdb.cpp
blobafc194e3eb90e31c75edad7a478b903d64ce657d
1 /*
3 * To populate the registry_db, construct a codeset registry text file based
4 * on the OSF's Character and Code Set Registry. See DCE RFC 40.1 for details
5 * on obtaining the full text for the current registry. Once you have composed
6 * a text file containing all the desired codeset information, build and run
7 * mkcsregdb. The source is in $ACE_ROOT/apps/mkcsregdb. It will generate a new
8 * copy of this file, with the registry_db_ array properly initialized.
9 */
11 // FUZZ: disable check_for_streams_include
12 #include "ace/streams.h"
14 #include "ace/Codeset_Registry.h"
15 #include "ace/Log_Msg.h"
16 #include "ace/OS_NS_sys_stat.h"
17 #include "ace/OS_NS_time.h"
18 #include "ace/OS_NS_stdio.h"
19 #include "ace/OS_NS_stdlib.h"
20 #include "ace/OS_NS_string.h"
21 #include "ace/OS_NS_unistd.h"
23 class csdb_generator : public ACE_Codeset_Registry
25 public:
26 csdb_generator ();
27 int read_from (const char *source);
28 int init_output (const char *srcfile);
29 int write_entry ();
30 int fini_output (const char *target);
31 int read_line ();
32 void write_dummy_entry();
33 void fail(const char *msg);
34 private:
35 static const char * tags_[];
36 static int max_line_;
37 int count_;
38 int in_entry_;
39 registry_entry entry_;
40 int linecounter_;
41 char *source_line_;
42 char *line_data_;
43 ifstream *inf_;
44 FILE *outf_;
45 char tempfilename_[MAXPATHLEN];
46 char *ace_src_;
49 int csdb_generator::max_line_ = 1024;
50 const char * csdb_generator::tags_[] = {
51 "start",
52 "end",
53 "description ",
54 "loc_name ",
55 "rgy_value ",
56 "char_values ",
57 "max_bytes ",
61 csdb_generator::csdb_generator ()
62 :count_(0),
63 in_entry_(0),
64 linecounter_(0),
65 source_line_ (new char[max_line_]),
66 line_data_ (0),
67 inf_ (0),
68 outf_ (0)
70 ace_src_ = ACE_OS::getenv("ACE_ROOT");
71 tempfilename_[0] = '\0';
74 void
75 csdb_generator::fail (const char *msg)
77 ACE_ERROR ((LM_ERROR,"Error, line %d: %s\n",linecounter_,msg));
78 ACE_OS::fclose (outf_);
79 ACE_OS::unlink (tempfilename_);
80 ACE_OS::exit (-1);
83 int
84 csdb_generator::read_line()
86 inf_->getline (source_line_,max_line_);
87 line_data_ = 0;
88 char *cpos = ACE_OS::strchr (source_line_,'#');
89 if (cpos == 0)
90 cpos = source_line_ + ACE_OS::strlen(source_line_);
91 while (cpos > source_line_ && ACE_OS::strchr(" \t",*(cpos - 1))) cpos--;
92 *cpos = 0;
93 if (cpos == source_line_)
94 return 0;
95 for (int i = 0; tags_[i]; i++)
97 cpos = ACE_OS::strstr (source_line_,tags_[i]);
98 if (cpos == 0) // not found
99 continue;
100 if (cpos > source_line_) // make sure it's first token
102 char *tpos = cpos-1;
103 while (tpos > source_line_ && ACE_OS::strchr(" \t",*tpos)) tpos--;
104 if (tpos > source_line_)
105 continue;
107 if (i == 0 && in_entry_)
108 fail ("\"start\" encountered twice before \"end\"");
109 if (i > 0 && !in_entry_)
111 char *emsg = new char[100];
112 ACE_OS::sprintf (emsg,"\"%s\" encountered before \"start\"",tags_[i]);
113 fail (emsg);
115 if (i > 1)
117 line_data_ = cpos + ACE_OS::strlen(tags_[i]);
118 while (*line_data_ && ACE_OS::strchr(" \t",(*line_data_)))
119 line_data_++;
121 return i+1;
123 return -1;
127 csdb_generator::read_from (const char *srcfile)
129 inf_ = new ifstream(srcfile);
130 char *ptr;
131 while (inf_->good() && !inf_->eof()) {
132 linecounter_++;
133 switch (read_line ()) {
134 case -1: // bogus line
135 fail ("unknown field tag");
136 break;
137 case 0: // comment or blank line
138 break;
139 case 1: // start
140 entry_.desc_ = 0;
141 entry_.loc_name_ = 0;
142 entry_.codeset_id_ = 0;
143 entry_.num_sets_ = 0;
144 entry_.max_bytes_ = 0;
145 in_entry_ = 1;
146 break;
147 case 2: // end
148 if (entry_.codeset_id_ == 0)
149 fail ("entry missing rgy_value");
150 if (entry_.num_sets_ == 0)
151 fail ("entry does not include at least one char_value");
152 if (entry_.max_bytes_ == 0)
153 fail ("entry does not define max_bytes");
154 write_entry ();
155 delete [] const_cast<char *> (entry_.desc_);
156 delete [] const_cast<char *> (entry_.loc_name_);
157 count_++;
158 in_entry_ = 0;
159 break;
160 case 3: // description
161 if (entry_.desc_ != 0)
162 fail ("duplicate description");
163 entry_.desc_ = ACE_OS::strdup(line_data_);
164 break;
165 case 4: // loc_name
166 if (entry_.loc_name_ != 0)
167 fail ("duplicate loc_name");
168 entry_.loc_name_ = ACE_OS::strdup(line_data_);
169 break;
170 case 5: // rgy_value
171 if (entry_.codeset_id_ != 0)
172 fail ("duplicate rgy_value");
173 entry_.codeset_id_ = ACE_OS::strtoul(line_data_,&ptr,16);
174 if (*ptr != 0 || entry_.codeset_id_ == 0)
176 char emsg [100];
177 ACE_OS::sprintf (emsg,"invalid rgy_value, '%s'",line_data_);
178 fail (emsg);
180 break;
181 case 6: // char_values
182 if (entry_.num_sets_ != 0)
183 fail ("duplicate char_values");
184 ptr = line_data_;
185 do {
186 if (*ptr == ':')
187 ptr++;
188 ACE_CDR::UShort tmp =
189 static_cast<ACE_CDR::UShort> (ACE_OS::strtoul(ptr,&ptr,16));
190 if (*ptr != 0 && *ptr != ':')
192 char *emsg = new char [100];
193 ACE_OS::sprintf (emsg,"invalid symbol \'%c\' in char_values",*ptr);
194 fail (emsg);
196 if (entry_.num_sets_ < max_charsets_)
197 entry_.char_sets_[entry_.num_sets_++] = tmp;
198 else entry_.num_sets_++;
199 } while (*ptr == ':');
200 if (entry_.num_sets_ > max_charsets_)
202 char *emsg = new char [200];
203 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_);
204 fail (emsg);
206 break;
207 case 7: // max_bytes
208 if (entry_.max_bytes_ != 0)
209 fail ("duplicate max_bytes");
210 entry_.max_bytes_ =
211 static_cast<ACE_CDR::UShort> (ACE_OS::strtol(line_data_,&ptr,10));
212 if (*ptr != 0)
213 fail ("invalid max_bytes");
214 break;
217 return 0;
221 csdb_generator::init_output (const char *srcfile)
223 ACE_stat buf;
224 if (ACE_OS::stat (srcfile,&buf) != 0)
225 ACE_ERROR_RETURN ((LM_ERROR,"Unable to open %s\n",srcfile),-1);
227 if (ace_src_ == 0)
228 ACE_ERROR_RETURN ((LM_ERROR,"You must first set $ACE_ROOT\n"),-1);
230 time_t now = ACE_OS::time();
231 if (ACE_OS::strlen(ace_src_) > 0)
233 ACE_OS::sprintf (tempfilename_,
234 "%s%s%s",
235 ace_src_,
236 ACE_DIRECTORY_SEPARATOR_STR,
237 "csdbXXXXXX");
239 else
241 ACE_OS::strcpy (tempfilename_, "csdbXXXXXX");
243 ACE_HANDLE fd = ACE_OS::mkstemp (tempfilename_);
244 if (fd == ACE_INVALID_HANDLE)
245 ACE_ERROR_RETURN ((LM_ERROR,
246 "Unable to open output file, %p\n",
247 tempfilename_),
248 -1);
249 outf_ = ACE_OS::fdopen (fd, "w");
251 ACE_OS::fprintf (outf_,"/*\n * Codeset registry DB, generated %s * source: %s\n",
252 ACE_OS::asctime (ACE_OS::localtime(&now)),
253 srcfile);
254 ACE_OS::fprintf (outf_," *\n * To populate the registry_db, construct a codeset registry text file based\n");
255 ACE_OS::fprintf (outf_," * on the OSF's Character and Code Set Registry. See DCE RFC 40.1 for details\n");
256 ACE_OS::fprintf (outf_," * on obtaining the full text for the current registry. Once you have composed\n");
257 ACE_OS::fprintf (outf_," * a text file containing all the desired codeset information, build and run\n");
258 ACE_OS::fprintf (outf_," * mkcsregdb. The source is in $ACE_ROOT/apps/mkcsregdb. It will generate a new\n");
259 ACE_OS::fprintf (outf_," * copy of this file, with the registry_db_ array properly initialized.\n */\n");
260 ACE_OS::fprintf (outf_,"\n#include \"ace/Codeset_Registry.h\"\n\nACE_BEGIN_VERSIONED_NAMESPACE_DECL\n\n%s\n%s\n{\n",
261 "ACE_Codeset_Registry::registry_entry const",
262 "ACE_Codeset_Registry::registry_db_[] =");
263 return 0;
267 csdb_generator::write_entry ()
269 if (count_)
270 ACE_OS::fprintf (outf_,",\n");
271 ACE_OS::fprintf (outf_," {\"%s\",\"%s\",0x%08x,%d,{",
272 entry_.desc_,
273 entry_.loc_name_,
274 entry_.codeset_id_,
275 entry_.num_sets_);
276 for (ACE_CDR::UShort j = 0; j < entry_.num_sets_; j++)
277 if (j+1 < entry_.num_sets_)
278 ACE_OS::fprintf (outf_,"0x%04x,",entry_.char_sets_[j]);
279 else
280 ACE_OS::fprintf (outf_,"0x%04x",entry_.char_sets_[j]);
281 ACE_OS::fprintf (outf_,"},%d}",entry_.max_bytes_);
282 return 0;
285 void
286 csdb_generator::write_dummy_entry()
288 entry_.desc_ = "No codesets defined";
289 entry_.loc_name_ = "NONE";
290 entry_.codeset_id_ = 0;
291 entry_.num_sets_ = 1;
292 entry_.char_sets_[0] = 0;
293 entry_.max_bytes_ = 0;
294 write_entry();
298 csdb_generator::fini_output (const char *tgt)
300 char *target = new char [ACE_OS::strlen(ace_src_) + ACE_OS::strlen(tgt) + 6];
301 ACE_OS::sprintf (target,"%s/ace/%s",ace_src_,tgt);
302 if (count_ == 0)
303 write_dummy_entry();
304 ACE_OS::fprintf (outf_,"\n};\n\nsize_t const ACE_Codeset_Registry::num_registry_entries_ = %d;\n\nACE_END_VERSIONED_NAMESPACE_DECL\n",count_);
305 ACE_OS::fclose (outf_);
306 ACE_stat buf;
307 if (ACE_OS::stat (target,&buf) == 0)
309 char fname[200];
310 int result = 0;
311 for (int i = 0; result == 0; i++)
313 ACE_OS::sprintf (fname,"%s.%03d",target,i);
314 result = ACE_OS::stat(fname,&buf);
316 ACE_DEBUG ((LM_DEBUG,"Moving $ACE_ROOT/ace/%s to $ACE_ROOT/ace%s\n",
317 tgt,ACE_OS::strrchr(fname,'/')));
318 if (ACE_OS::rename (target,fname) == -1)
319 ACE_ERROR_RETURN ((LM_ERROR,"Could not create %s\n, output stored in %s",
320 fname,tempfilename_),-1);
322 ACE_DEBUG ((LM_DEBUG,"writing $ACE_ROOT/ace/%s\n",tgt));
323 if (ACE_OS::rename (tempfilename_,target) == -1)
324 ACE_ERROR_RETURN ((LM_ERROR,"Could not create %s\n, output stored in %s",
325 target,tempfilename_),-1);
326 return 0;
330 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
332 ACE_CString srcname;
333 if (argc > 1)
334 srcname.set(argv[1]);
335 else
336 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);
337 csdb_generator csdb;
338 if (csdb.init_output(srcname.c_str()) == -1)
339 return 0;
340 if (csdb.read_from (srcname.c_str()) == 0)
341 csdb.fini_output ("Codeset_Registry_db.cpp");
342 return 0;