1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 /*
20 * $Id$
21 */
22
23
24 // ---------------------------------------------------------------------------
25 // This program is designed to parse an XML file which holds error text
26 // data. It will build a DOM tree from that source file and can output it
27 // a number of different formats.
28 //
29 // In order to drastically simplify the program, it is designed only to run
30 // on platforms/compilers that understand Unicode. It can output the data
31 // in whatever format is required, so it can handle outputting for other
32 // platforms. This also simplifies bootstrapping new releases up on other
33 // platforms. Once the Win32 version is working, it can generate output for
34 // the other platforms so that they can have loadable text from day one.
35 // ---------------------------------------------------------------------------
36
37
38 // ---------------------------------------------------------------------------
39 // Includes
40 // ---------------------------------------------------------------------------
41 #include "Xlat.hpp"
42
43
44 // ---------------------------------------------------------------------------
45 // Static data
46 //
47 // gRelativeInputPath
48 // This is the path, relative to the given input source root, to the
49 // input file. The given local suffix must also be added to it.
50 // ---------------------------------------------------------------------------
51 XMLCh* gRelativeInputPath = 0;
52
53
54 // ---------------------------------------------------------------------------
55 // Global data
56 // ---------------------------------------------------------------------------
57 XMLCh* typePrefixes[MsgTypes_Count];
58
59 // ---------------------------------------------------------------------------
60 // temporary variables/conversion utility functions
61 // We need different temps depending on treatment of wide characters
62 // ---------------------------------------------------------------------------
63 #ifdef longChars
64 char* fTmpStr = 0;
65 #else
66 wchar_t fTmpWStr[256];
67 #endif
68
69 // ---------------------------------------------------------------------------
70 // Local data
71 //
72 // gLocale
73 // This is the locale suffix, e.g. US_EN, that is used to find the
74 // correct file and can be used on output files as well. Its set via
75 // the /Locale= parameter.
76 //
77 // gOutFormat
78 // This is the output format, which is given on the command line as
79 // /OutFmt= Its mapped to the internal enum which is stored here.
80 //
81 // gOutPath
82 // This is the path to the output path, which is given on the command
83 // line as /OutPath=. Its just the path, not a name, since the output
84 // might consist of multiple output files. They will all be based on
85 // the base part of the input name.
86 //
87 // gSrcRoot
88 // This the path to the root of the build tree. The input files needed
89 // are found in known places relative to it.
90 // ---------------------------------------------------------------------------
91 const XMLCh* gLocale = 0;
92 OutFormats gOutFormat = OutFormat_Unknown;
93 const XMLCh* gOutPath = 0;
94 const XMLCh* gSrcRoot = 0;
95
96
97 // ---------------------------------------------------------------------------
98 // Local utility methods
99 // ---------------------------------------------------------------------------
100
101 // Initialize the global "constants" (that really require use of the transcoder)
init_Globals(void)102 void init_Globals(void)
103 {
104 typePrefixes[0] = XMLString::transcode("W_");
105 typePrefixes[1] = XMLString::transcode("E_");
106 typePrefixes[2] = XMLString::transcode("F_");
107 gRelativeInputPath = XMLString::transcode("src/xercesc/NLS/");
108 }
109
110 // Release the global "constants" (that really require use of the transcoder)
release_Globals(void)111 void release_Globals(void)
112 {
113 for(int i=0; i<3; i++)
114 {
115 XMLString::release(&typePrefixes[i]);
116 }
117 XMLString::release(&gRelativeInputPath);
118 }
119
120 //
121 // This method is called to parse the parameters. They must be in this
122 // order and format, for simplicity:
123 //
124 // /SrcRoot=xxx /OutPath=xxx /OutFmt=xxx /Locale=xxx
125 //
126 //static bool parseParms(const int argC, XMLCh** argV)
parseParms(const int argC,XMLCh ** argV)127 bool parseParms(const int argC, XMLCh** argV)
128 {
129 if (argC < 5)
130 return false;
131
132 unsigned int curParm = 1;
133 XMLCh *tmpXMLStr = XMLString::transcode("/SrcRoot=");
134 if (XMLString::startsWith(argV[curParm], tmpXMLStr))
135 {
136 gSrcRoot = &argV[curParm][9];
137 }
138 else
139 {
140 wprintf(L"\nExpected /SrcRoot=xxx. Got: %s\n", argV[curParm]);
141 XMLString::release(&tmpXMLStr);
142 return false;
143 }
144 XMLString::release(&tmpXMLStr);
145
146 curParm++;
147 tmpXMLStr = XMLString::transcode("/OutPath=");
148 if (XMLString::startsWith(argV[curParm], tmpXMLStr ))
149 {
150 gOutPath = &argV[curParm][9];
151 }
152 else
153 {
154 wprintf(L"\nExpected /OutPath=xxx. Got: %s\n", argV[curParm]);
155 XMLString::release(&tmpXMLStr);
156 return false;
157 }
158 XMLString::release(&tmpXMLStr);
159
160
161 curParm++;
162 tmpXMLStr = XMLString::transcode("/OutFmt=");
163 if (XMLString::startsWith(argV[curParm], tmpXMLStr ))
164 {
165 XMLString::release(&tmpXMLStr);
166 const XMLCh* tmpFmt = &argV[curParm][8];
167 tmpXMLStr = XMLString::transcode("ResBundle");
168 XMLCh *tmpXMLStr2 = XMLString::transcode("Win32RC");
169 XMLCh *tmpXMLStr3 = XMLString::transcode("CppSrc");
170 XMLCh *tmpXMLStr4 = XMLString::transcode("MsgCat");
171 if (!XMLString::compareIString(tmpFmt, tmpXMLStr ))
172 gOutFormat = OutFormat_ResBundle;
173 else if (!XMLString::compareIString(tmpFmt, tmpXMLStr2 ))
174 gOutFormat = OutFormat_Win32RC;
175 else if (!XMLString::compareIString(tmpFmt, tmpXMLStr3 ))
176 gOutFormat = OutFormat_CppSrc;
177 else if (!XMLString::compareIString(tmpFmt, tmpXMLStr4 ))
178 gOutFormat = OutFormat_MsgCatalog;
179 else
180 {
181 wprintf(L"\n'%s' is not a legal output format\n", tmpFmt);
182 XMLString::release(&tmpXMLStr);
183 XMLString::release(&tmpXMLStr2);
184 XMLString::release(&tmpXMLStr3);
185 XMLString::release(&tmpXMLStr4);
186 return false;
187 }
188 XMLString::release(&tmpXMLStr);
189 XMLString::release(&tmpXMLStr2);
190 XMLString::release(&tmpXMLStr3);
191 XMLString::release(&tmpXMLStr4);
192 }
193 else
194 {
195 wprintf(L"\nExpected /OutFmt=xxx. Got: %s\n", argV[curParm]);
196 XMLString::release(&tmpXMLStr);
197 return false;
198 }
199
200 curParm++;
201 tmpXMLStr = XMLString::transcode("/Locale=");
202 if (XMLString::startsWith(argV[curParm], tmpXMLStr ))
203 {
204 gLocale = &argV[curParm][8];
205 }
206 else
207 {
208 wprintf(L"\nExpected /Locale=xxx. Got: %s\n", argV[curParm]);
209 XMLString::release(&tmpXMLStr);
210 return false;
211 }
212 XMLString::release(&tmpXMLStr);
213
214 return true;
215 }
216
217
218 //static void parseError(const XMLException& toCatch)
parseError(const XMLException & toCatch)219 void parseError(const XMLException& toCatch)
220 {
221 wprintf
222 (
223 L"Exception\n (Line.File):%d.%s\n ERROR: %s\n\n"
224 , toCatch.getSrcLine()
225 , toCatch.getSrcFile()
226 , toCatch.getMessage()
227 );
228 throw ErrReturn_ParseErr;
229 }
230
231
232 //static void parseError(const SAXParseException& toCatch)
parseError(const SAXParseException & toCatch)233 void parseError(const SAXParseException& toCatch)
234 {
235 wprintf
236 (
237 L"SAX Parse Error:\n (Line.Col.SysId): %d.%d.%s\n ERROR: %s\n\n"
238 , toCatch.getLineNumber()
239 , toCatch.getColumnNumber()
240 , toCatch.getSystemId()
241 , toCatch.getMessage()
242 );
243 throw ErrReturn_ParseErr;
244 }
245
246
247 //static void
248 void
enumMessages(const DOMElement * srcElem,XlatFormatter * const toCall,FILE * const headerFl,const MsgTypes msgType,unsigned int & count)249 enumMessages( const DOMElement* srcElem
250 , XlatFormatter* const toCall
251 , FILE* const headerFl
252 , const MsgTypes msgType
253 , unsigned int& count)
254 {
255 fwprintf
256 (
257 headerFl
258 , L" , %s%-30s = %d\n"
259 , xmlStrToPrintable(typePrefixes[msgType])
260 , longChars("LowBounds")
261 , count++
262 );
263 releasePrintableStr
264
265 //
266 // We just run through each of the child elements, each of which is
267 // a Message element. Each one represents a message to output. We keep
268 // a count so that we can output a const value afterwards.
269 //
270 DOMNode* curNode = srcElem->getFirstChild();
271 while (curNode)
272 {
273 // Skip over text nodes or comment nodes ect...
274 if (curNode->getNodeType() != DOMNode::ELEMENT_NODE)
275 {
276 curNode = curNode->getNextSibling();
277 continue;
278 }
279
280 // Convert it to an element node
281 const DOMElement* curElem = (const DOMElement*)curNode;
282
283 // Ok, this should be a Message node
284 XMLCh *tmpXMLStr = XMLString::transcode("Message");
285 if (XMLString::compareString(curElem->getTagName(), tmpXMLStr ))
286 {
287 wprintf(L"Expected a Message node\n\n");
288 XMLString::release(&tmpXMLStr);
289 throw ErrReturn_SrcFmtError;
290 }
291 XMLString::release(&tmpXMLStr);
292
293 //
294 // Ok, lets pull out the id, text value, and message type. These are
295 // to be passed to the formatter. We have to translate the message
296 // type into one of the offical enum values.
297 //
298 tmpXMLStr = XMLString::transcode("Text");
299 const XMLCh* msgText = curElem->getAttribute(tmpXMLStr );
300 XMLString::release(&tmpXMLStr);
301 tmpXMLStr = XMLString::transcode("Id");
302 const XMLCh* msgId = curElem->getAttribute(tmpXMLStr );
303 XMLString::release(&tmpXMLStr);
304
305 //
306 // Write out an entry to the target header file. These are enums, so
307 // we use the id as the enum name.
308 //
309
310 if (XMLString::stringLen(msgText) >= 128) {
311 wprintf(L"Message text '%s' is too long (%d chars), 128 character limit\n\n", xmlStrToPrintable(msgText),XMLString::stringLen(msgText));
312 throw ErrReturn_SrcFmtError;
313 }
314
315
316 fwprintf(headerFl, L" , %-32s = %d\n", xmlStrToPrintable(msgId), count);
317 releasePrintableStr
318
319 // And tell the formatter about this one
320 toCall->nextMessage
321 (
322 msgText
323 , msgId
324 , count
325 , count
326 );
327
328 // Bump the counter, which is also the id assigner
329 count++;
330
331 // Move to the next child of the source element
332 curNode = curNode->getNextSibling();
333 }
334
335 // Write out an upper range bracketing id for this type of error
336 fwprintf
337 (
338 headerFl
339 , L" , %s%-30s = %d\n"
340 , xmlStrToPrintable(typePrefixes[msgType])
341 , longChars("HighBounds")
342 , count++
343 );
344 releasePrintableStr
345 }
346
347
348
349 // ---------------------------------------------------------------------------
350 // Program entry point
351 // ---------------------------------------------------------------------------
352
353 //
354 // This is the program entry point. It checks the parms, parses the input
355 // file to get a DOM tree, then passes the DOM tree to the appropriate
356 // output method to output the info in a particular format.
357 //
358 int Xlat_main(int argC, XMLCh** argV);
main(int argC,char ** argV)359 int main (int argC, char** argV) {
360 try
361 {
362 XMLPlatformUtils::Initialize();
363 }
364
365 catch(const XMLException& toCatch)
366 {
367 wprintf(L"Parser init error.\n ERROR: %s\n\n", toCatch.getMessage());
368 return ErrReturn_ParserInit;
369 }
370
371 int i;
372 XMLCh** newArgV = new XMLCh*[argC];
373 for(i=0;i<argC; i++)
374 {
375 newArgV[i] = XMLString::transcode(argV[i]);
376 }
377 int toReturn = (Xlat_main(argC,newArgV));
378 for (i=0; i<argC; i++)
379 {
380 XMLString::release(&newArgV[i]);
381 }
382 delete [] newArgV;
383
384 XMLPlatformUtils::Terminate();
385
386 return toReturn;
387 }
388
Xlat_main(int argC,XMLCh ** argV)389 int Xlat_main(int argC, XMLCh** argV)
390 {
391 init_Globals();
392
393 //
394 // Lets check the parameters and save them away in globals for use by
395 // the processing code.
396 //
397 if (!parseParms(argC, argV))
398 {
399 wprintf(L"Usage:\n NLSXlat /SrcRoot=xx /OutPath=xx /OutFmt=xx /Locale=xx\n\n");
400 return ErrReturn_BadParameters;
401 }
402
403 {
404 // Nest entire code in an inner block.
405
406 DOMDocument* srcDoc;
407 const unsigned int bufSize = 4095;
408 XMLCh *tmpFileBuf = new XMLCh [bufSize + 1];
409 tmpFileBuf[0] = 0;
410 XMLCh *tmpXMLStr = XMLString::transcode("/XMLErrList_");
411 XMLCh *tmpXMLStr2 = XMLString::transcode(".Xml");
412 try
413 {
414 try
415 {
416 // Build the input file name
417 XMLString::catString(tmpFileBuf, gSrcRoot);
418 XMLString::catString(tmpFileBuf, gRelativeInputPath);
419 XMLString::catString(tmpFileBuf, gLocale);
420 XMLString::catString(tmpFileBuf, tmpXMLStr );
421 XMLString::catString(tmpFileBuf, gLocale);
422 XMLString::catString(tmpFileBuf, tmpXMLStr2 );
423 XMLString::release(&tmpXMLStr);
424 XMLString::release(&tmpXMLStr2);
425
426 //
427 // Ok, lets invoke the DOM parser on the input file and build
428 // a DOM tree. Turn on validation when we do this.
429 //
430 XercesDOMParser parser;
431 parser.setValidationScheme(AbstractDOMParser::Val_Always);
432 XlatErrHandler errHandler;
433 parser.setErrorHandler(&errHandler);
434 parser.parse(tmpFileBuf);
435 srcDoc = parser.adoptDocument();
436 }
437
438 catch(const XMLException& toCatch)
439 {
440 parseError(toCatch);
441 }
442 delete tmpFileBuf;
443
444 //
445 // Use the output format parm to create the correct kind of output
446 // formatter.
447 //
448 XlatFormatter* formatter = 0;
449 switch(gOutFormat)
450 {
451 case OutFormat_CppSrc :
452 formatter = new CppSrcFormatter;
453 break;
454
455 case OutFormat_Win32RC :
456 formatter = new Win32RCFormatter;
457 break;
458
459 case OutFormat_MsgCatalog :
460 formatter = new MsgCatFormatter;
461 break;
462
463 case OutFormat_ResBundle:
464 formatter = new ICUResBundFormatter;
465 break;
466
467 default :
468 wprintf(L"Unknown formatter type enum\n\n");
469 throw ErrReturn_Internal;
470 }
471
472 //
473 // Lets handle the root element stuff first. This one holds any over
474 // all information.
475 //
476 DOMElement* rootElem = srcDoc->getDocumentElement();
477 tmpXMLStr = XMLString::transcode("Locale");
478 const XMLCh* localeStr = rootElem->getAttribute(tmpXMLStr);
479 XMLString::release(&tmpXMLStr);
480
481 // Make sure that the locale matches what we were given
482 if (XMLString::compareString(localeStr, gLocale))
483 {
484 wprintf(L"The file's locale does not match the target locale\n");
485 throw ErrReturn_LocaleErr;
486 }
487
488 //
489 // Get a list of all the MsgDomain children. These each hold one of
490 // the sets of (potentially separately) loadable messages. More
491 // importantly they all have their own error id space.
492 //
493 tmpXMLStr = XMLString::transcode("MsgDomain");
494 DOMNodeList* msgSetList = rootElem->getElementsByTagName(tmpXMLStr);
495 XMLString::release(&tmpXMLStr);
496
497 //
498 // Loop through them and look for the domains that we know are
499 // supposed to be there.
500 //
501 const XMLSize_t count = msgSetList->getLength();
502
503 //
504 // Normalize locale string
505 //
506 // locale = ll[[_CC][_VARIANT]]
507 // where ll is language code
508 // CC is country code
509 // VARIANT is variant code
510 //
511 XMLCh normalizedLocale[256];
512
513 normalizedLocale[0] = localeStr[0];
514 normalizedLocale[1] = localeStr[1];
515 normalizedLocale[2] = 0;
516 XMLString::lowerCase(normalizedLocale);
517
518 if (XMLString::stringLen(localeStr) > 2)
519 {
520 XMLString::catString(&(normalizedLocale[2]), &(localeStr[2]));
521 XMLString::upperCase(&(normalizedLocale[2]));
522 }
523
524 //
525 // Ok, its good enough to get started. So lets call the start output
526 // method on the formatter.
527 //
528
529 formatter->startOutput(normalizedLocale, gOutPath);
530
531 //
532 // For each message domain element, we call start and end domain
533 // events bracketed around the loop that sends out each message
534 // in that domain.
535 //
536 // Within each domain, we check for the Warning, Error, and Validity
537 // subelements, and then iterate all the messages in each one.
538 //
539 for (unsigned int index = 0; index < count; index++)
540 {
541 // We know its a DOM Element, so go ahead and cast it
542 DOMNode* curNode = msgSetList->item(index);
543 const DOMElement* curElem = (const DOMElement*)curNode;
544
545 //
546 // Get some of the attribute strings that we need, and transcode
547 // couple that need to be in local format.
548 //
549 tmpXMLStr = XMLString::transcode("Domain");
550 const XMLCh* domainStr = curElem->getAttribute(tmpXMLStr );
551 XMLString::release(&tmpXMLStr);
552
553 //
554 // Look at the domain and set up our application specific info
555 // that is on a per-domain basis. We need to indicate what the
556 // name of the header is and what the namespace is that they
557 // codes will go into
558 //
559 XMLCh* headerName = 0;
560 XMLCh* errNameSpace = 0;
561 if (!XMLString::compareString(domainStr, XMLUni::fgXMLErrDomain))
562 {
563 headerName = XMLString::transcode("XMLErrorCodes.hpp");
564 errNameSpace = XMLString::transcode("XMLErrs");
565 }
566 else if (!XMLString::compareString(domainStr, XMLUni::fgValidityDomain))
567 {
568 headerName = XMLString::transcode("XMLValidityCodes.hpp");
569 errNameSpace = XMLString::transcode("XMLValid");
570 }
571 else if (!XMLString::compareString(domainStr, XMLUni::fgExceptDomain))
572 {
573 headerName = XMLString::transcode("XMLExceptMsgs.hpp");
574 errNameSpace = XMLString::transcode("XMLExcepts");
575 }
576 else if (!XMLString::compareString(domainStr, XMLUni::fgXMLDOMMsgDomain))
577 {
578 headerName = XMLString::transcode("XMLDOMMsg.hpp");
579 errNameSpace = XMLString::transcode("XMLDOMMsg");
580 }
581 else
582 {
583 // Not one of ours, so skip it
584 continue;
585 }
586
587 //
588 // Lets try to create the header file that was indicated for
589 // this domain.
590 //
591 tmpFileBuf = new XMLCh [bufSize + 1];
592 tmpFileBuf[0] = 0;
593 XMLString::catString(tmpFileBuf, gOutPath);
594 XMLString::catString(tmpFileBuf, headerName);
595 char *tmpFileBufCh = XMLString::transcode(tmpFileBuf);
596 FILE* outHeader = fopen(tmpFileBufCh, "wt+");
597 XMLString::release(&tmpFileBufCh);
598 if ((!outHeader) || (fwide(outHeader, 1) < 0))
599 {
600 wprintf(L"Could not open domain header file: %s\n\n", xmlStrToPrintable(tmpFileBuf));
601 releasePrintableStr
602 XMLString::release(&tmpFileBuf);
603 XMLString::release(&headerName);
604 XMLString::release(&errNameSpace);
605 throw ErrReturn_OutFileOpenFailed;
606 }
607 delete tmpFileBuf;
608
609 //
610 // Write out the opening of the class they are nested within, and
611 // the header protection define.
612 //
613 fwprintf(outHeader, L"// This file is generated, don't edit it!!\n\n");
614 fwprintf(outHeader, L"#if !defined(XERCESC_INCLUDE_GUARD_ERRHEADER_%s)\n", xmlStrToPrintable(errNameSpace) );
615 releasePrintableStr
616 fwprintf(outHeader, L"#define XERCESC_INCLUDE_GUARD_ERRHEADER_%s\n\n", xmlStrToPrintable(errNameSpace) );
617 releasePrintableStr
618
619 // If its not the exception domain, then we need a header included
620 if (XMLString::compareString(domainStr, XMLUni::fgExceptDomain))
621 fwprintf(outHeader, L"#include <xercesc/framework/XMLErrorReporter.hpp>\n");
622
623 // Write out the namespace declaration
624 fwprintf(outHeader, L"#include <xercesc/util/XercesDefs.hpp>\n");
625 fwprintf(outHeader, L"#include <xercesc/dom/DOMError.hpp>\n\n");
626 fwprintf(outHeader, L"XERCES_CPP_NAMESPACE_BEGIN\n\n");
627
628 // Now the message codes
629 fwprintf(outHeader, L"class %s\n{\npublic :\n enum Codes\n {\n", xmlStrToPrintable(errNameSpace) );
630 releasePrintableStr
631
632 // Tell the formatter that a new domain is starting
633 formatter->startDomain
634 (
635 domainStr
636 , errNameSpace
637 );
638
639 //
640 // Force out the first message, which is always implicit and is
641 // the 'no error' entry for that domain.
642 //
643 unsigned int count = 0;
644 fwprintf(outHeader, L" %-32s = %d\n", longChars("NoError"), count++);
645
646 //
647 // Loop through the children of this node, which should take us
648 // through the optional Warning, Error, and Validity subsections.
649 //
650 DOMNode* typeNode = curElem->getFirstChild();
651 bool typeGotten[3] = { false, false, false };
652 while (typeNode)
653 {
654 // Skip over text nodes or comment nodes ect...
655 if (typeNode->getNodeType() != DOMNode::ELEMENT_NODE)
656 {
657 typeNode = typeNode->getNextSibling();
658 continue;
659 }
660
661 // Convert it to an element node
662 const DOMElement* typeElem = (const DOMElement*)typeNode;
663
664 // Now get its tag name and convert that to a message type enum
665 const XMLCh* typeName = typeElem->getTagName();
666
667 MsgTypes type;
668 tmpXMLStr = XMLString::transcode("Warning");
669 XMLCh* tmpXMLStr2 = XMLString::transcode("Error");
670 XMLCh* tmpXMLStr3 =XMLString::transcode("FatalError");
671 if (!XMLString::compareString(typeName, tmpXMLStr ))
672 {
673 type = MsgType_Warning;
674 typeGotten[0] = true;
675 }
676 else if (!XMLString::compareString(typeName, tmpXMLStr2 ))
677 {
678 type = MsgType_Error;
679 typeGotten[1] = true;
680 }
681 else if (!XMLString::compareString(typeName, tmpXMLStr3 ))
682 {
683 type = MsgType_FatalError;
684 typeGotten[2] = true;
685 }
686 else
687 {
688 wprintf(L"Expected a Warning, Error, or FatalError node\n\n");
689 XMLString::release(&tmpXMLStr);
690 XMLString::release(&tmpXMLStr2);
691 XMLString::release(&tmpXMLStr3);
692 throw ErrReturn_SrcFmtError;
693 }
694 XMLString::release(&tmpXMLStr);
695 XMLString::release(&tmpXMLStr2);
696 XMLString::release(&tmpXMLStr3);
697
698 // Call the start message type event
699 formatter->startMsgType(type);
700
701 // Enumerate the messages under this subsection
702 enumMessages
703 (
704 typeElem
705 , formatter
706 , outHeader
707 , type
708 , count
709 );
710
711 // Call the end message type event
712 formatter->endMsgType(type);
713
714 // Move to the next child of the source element
715 typeNode = typeNode->getNextSibling();
716 }
717
718 //
719 // For any that we did not get, spit out faux boundary
720 // values for it.
721 //
722 for (unsigned int subIndex = 0; subIndex < 3; subIndex++)
723 {
724 if (!typeGotten[subIndex])
725 {
726 fwprintf
727 (
728 outHeader
729 , L" , %s%-30s = %d\n"
730 , xmlStrToPrintable(typePrefixes[subIndex])
731 , longChars("LowBounds")
732 , count++
733 );
734 releasePrintableStr
735 fwprintf
736 (
737 outHeader
738 , L" , %s%-30s = %d\n"
739 , xmlStrToPrintable(typePrefixes[subIndex])
740 , longChars("HighBounds")
741 , count++
742 );
743 releasePrintableStr
744 }
745 }
746
747 // Tell the formatter that this domain is ending
748 formatter->endDomain(domainStr, count);
749
750 // Close out the enum declaration
751 fwprintf(outHeader, L" };\n\n");
752
753 //
754 // Generate the code that creates the simple static methods
755 // for testing the error types. We don't do this for the
756 // exceptions header.
757 //
758 if (XMLString::compareString(domainStr, XMLUni::fgExceptDomain))
759 {
760 fwprintf
761 (
762 outHeader
763 , L" static bool isFatal(const %s::Codes toCheck)\n"
764 L" {\n"
765 L" return ((toCheck >= F_LowBounds) && (toCheck <= F_HighBounds));\n"
766 L" }\n\n"
767 , xmlStrToPrintable(errNameSpace)
768 );
769 releasePrintableStr
770
771 fwprintf
772 (
773 outHeader
774 , L" static bool isWarning(const %s::Codes toCheck)\n"
775 L" {\n"
776 L" return ((toCheck >= W_LowBounds) && (toCheck <= W_HighBounds));\n"
777 L" }\n\n"
778 , xmlStrToPrintable(errNameSpace)
779 );
780 releasePrintableStr
781
782 fwprintf
783 (
784 outHeader
785 , L" static bool isError(const %s::Codes toCheck)\n"
786 L" {\n"
787 L" return ((toCheck >= E_LowBounds) && (toCheck <= E_HighBounds));\n"
788 L" }\n\n"
789 , xmlStrToPrintable(errNameSpace)
790 );
791 releasePrintableStr
792
793 fwprintf
794 (
795 outHeader
796 , L" static XMLErrorReporter::ErrTypes errorType(const %s::Codes toCheck)\n"
797 L" {\n"
798 L" if ((toCheck >= W_LowBounds) && (toCheck <= W_HighBounds))\n"
799 L" return XMLErrorReporter::ErrType_Warning;\n"
800 L" else if ((toCheck >= F_LowBounds) && (toCheck <= F_HighBounds))\n"
801 L" return XMLErrorReporter::ErrType_Fatal;\n"
802 L" else if ((toCheck >= E_LowBounds) && (toCheck <= E_HighBounds))\n"
803 L" return XMLErrorReporter::ErrType_Error;\n"
804 L" return XMLErrorReporter::ErrTypes_Unknown;\n"
805 L" }\n"
806 , xmlStrToPrintable(errNameSpace)
807 );
808 releasePrintableStr
809
810 fwprintf
811 (
812 outHeader
813 , L" static DOMError::ErrorSeverity DOMErrorType(const %s::Codes toCheck)\n"
814 L" {\n"
815 L" if ((toCheck >= W_LowBounds) && (toCheck <= W_HighBounds))\n"
816 L" return DOMError::DOM_SEVERITY_WARNING;\n"
817 L" else if ((toCheck >= F_LowBounds) && (toCheck <= F_HighBounds))\n"
818 L" return DOMError::DOM_SEVERITY_FATAL_ERROR;\n"
819 L" else return DOMError::DOM_SEVERITY_ERROR;\n"
820 L" }\n"
821 , xmlStrToPrintable(errNameSpace)
822 );
823 releasePrintableStr
824
825 }
826
827 // the private default ctor
828 fwprintf(outHeader, L"\n");
829 fwprintf(outHeader, L"private:\n");
830 fwprintf(outHeader, L" // -----------------------------------------------------------------------\n");
831 fwprintf(outHeader, L" // Unimplemented constructors and operators\n");
832 fwprintf(outHeader, L" // -----------------------------------------------------------------------\n");
833 fwprintf(outHeader, L" %s();\n", xmlStrToPrintable(errNameSpace));
834 releasePrintableStr
835
836 // And close out the class declaration, the namespace declaration and the header file
837 fwprintf(outHeader, L"};\n\n");
838 fwprintf(outHeader, L"XERCES_CPP_NAMESPACE_END\n\n");
839 fwprintf(outHeader, L"#endif\n\n");
840 fclose(outHeader);
841 XMLString::release(&headerName);
842 XMLString::release(&errNameSpace);
843 }
844
845 // Ok, we are done so call the end output method
846 formatter->endOutput();
847
848 // And clean up the stuff we allocated
849 delete formatter;
850 }
851
852 catch(const ErrReturns retVal)
853 {
854 // And call the termination method
855 if(srcDoc)
856 delete srcDoc;
857 return retVal;
858 }
859
860 delete srcDoc;
861 }
862
863 // And call the termination method
864 release_Globals();
865
866 // Went ok, so return success
867 return ErrReturn_Success;
868 }
869
870
871
872 // -----------------------------------------------------------------------
873 // XlatErrHandler: Implementation of the error handler interface
874 // -----------------------------------------------------------------------
warning(const SAXParseException & toCatch)875 void XlatErrHandler::warning(const SAXParseException& toCatch)
876 {
877 parseError(toCatch);
878 }
879
error(const SAXParseException & toCatch)880 void XlatErrHandler::error(const SAXParseException& toCatch)
881 {
882 parseError(toCatch);
883 }
884
fatalError(const SAXParseException & toCatch)885 void XlatErrHandler::fatalError(const SAXParseException& toCatch)
886 {
887 parseError(toCatch);
888 }
889
resetErrors()890 void XlatErrHandler::resetErrors()
891 {
892 }
893
894 // if longChars is a macro, don't bother
895 #ifndef longChars
longChars(const char * str)896 wchar_t* longChars(const char *str)
897 {
898 mbstowcs(fTmpWStr, str, 255);
899 return (fTmpWStr);
900 }
901 #endif
902
903