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.
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
27 int read_from (const char *source
);
28 int init_output (const char *srcfile
);
30 int fini_output (const char *target
);
32 void write_dummy_entry();
33 void fail(const char *msg
);
35 static const char * tags_
[];
39 registry_entry entry_
;
45 char tempfilename_
[MAXPATHLEN
];
49 int csdb_generator::max_line_
= 1024;
50 const char * csdb_generator::tags_
[] = {
61 csdb_generator::csdb_generator ()
65 source_line_ (new char[max_line_
]),
70 ace_src_
= ACE_OS::getenv("ACE_ROOT");
71 tempfilename_
[0] = '\0';
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_
);
84 csdb_generator::read_line()
86 inf_
->getline (source_line_
,max_line_
);
88 char *cpos
= ACE_OS::strchr (source_line_
,'#');
90 cpos
= source_line_
+ ACE_OS::strlen(source_line_
);
91 while (cpos
> source_line_
&& ACE_OS::strchr(" \t",*(cpos
- 1))) cpos
--;
93 if (cpos
== source_line_
)
95 for (int i
= 0; tags_
[i
]; i
++)
97 cpos
= ACE_OS::strstr (source_line_
,tags_
[i
]);
98 if (cpos
== 0) // not found
100 if (cpos
> source_line_
) // make sure it's first token
103 while (tpos
> source_line_
&& ACE_OS::strchr(" \t",*tpos
)) tpos
--;
104 if (tpos
> source_line_
)
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
]);
117 line_data_
= cpos
+ ACE_OS::strlen(tags_
[i
]);
118 while (*line_data_
&& ACE_OS::strchr(" \t",(*line_data_
)))
127 csdb_generator::read_from (const char *srcfile
)
129 inf_
= new ifstream(srcfile
);
131 while (inf_
->good() && !inf_
->eof()) {
133 switch (read_line ()) {
134 case -1: // bogus line
135 fail ("unknown field tag");
137 case 0: // comment or blank line
141 entry_
.loc_name_
= 0;
142 entry_
.codeset_id_
= 0;
143 entry_
.num_sets_
= 0;
144 entry_
.max_bytes_
= 0;
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");
155 delete [] const_cast<char *> (entry_
.desc_
);
156 delete [] const_cast<char *> (entry_
.loc_name_
);
160 case 3: // description
161 if (entry_
.desc_
!= 0)
162 fail ("duplicate description");
163 entry_
.desc_
= ACE_OS::strdup(line_data_
);
166 if (entry_
.loc_name_
!= 0)
167 fail ("duplicate loc_name");
168 entry_
.loc_name_
= ACE_OS::strdup(line_data_
);
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)
177 ACE_OS::sprintf (emsg
,"invalid rgy_value, '%s'",line_data_
);
181 case 6: // char_values
182 if (entry_
.num_sets_
!= 0)
183 fail ("duplicate char_values");
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
);
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_
);
208 if (entry_
.max_bytes_
!= 0)
209 fail ("duplicate max_bytes");
211 static_cast<ACE_CDR::UShort
> (ACE_OS::strtol(line_data_
,&ptr
,10));
213 fail ("invalid max_bytes");
221 csdb_generator::init_output (const char *srcfile
)
224 if (ACE_OS::stat (srcfile
,&buf
) != 0)
225 ACE_ERROR_RETURN ((LM_ERROR
,"Unable to open %s\n",srcfile
),-1);
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_
,
236 ACE_DIRECTORY_SEPARATOR_STR
,
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",
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
)),
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_[] =");
267 csdb_generator::write_entry ()
270 ACE_OS::fprintf (outf_
,",\n");
271 ACE_OS::fprintf (outf_
," {\"%s\",\"%s\",0x%08x,%d,{",
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
]);
280 ACE_OS::fprintf (outf_
,"0x%04x",entry_
.char_sets_
[j
]);
281 ACE_OS::fprintf (outf_
,"},%d}",entry_
.max_bytes_
);
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;
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
);
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_
);
307 if (ACE_OS::stat (target
,&buf
) == 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);
330 ACE_TMAIN(int argc
, ACE_TCHAR
*argv
[])
334 srcname
.set(argv
[1]);
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);
338 if (csdb
.init_output(srcname
.c_str()) == -1)
340 if (csdb
.read_from (srcname
.c_str()) == 0)
341 csdb
.fini_output ("Codeset_Registry_db.cpp");