Xlat.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:26k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  * 
  4.  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  * 
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer. 
  13.  * 
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  * 
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:  
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  * 
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written 
  29.  *    permission, please contact apache@apache.org.
  30.  * 
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  * 
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  * 
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Log: Xlat.cpp,v $
  58.  * Revision 1.8  2001/05/03 19:09:36  knoaman
  59.  * Support Warning/Error/FatalError messaging.
  60.  * Validity constraints errors are treated as errors, with the ability by user to set
  61.  * validity constraints as fatal errors.
  62.  *
  63.  * Revision 1.7  2000/03/18 00:00:58  roddey
  64.  * Improved error reporting
  65.  *
  66.  * Revision 1.6  2000/03/03 01:29:36  roddey
  67.  * Added a scanReset()/parseReset() method to the scanner and
  68.  * parsers, to allow for reset after early exit from a progressive parse.
  69.  * Added calls to new Terminate() call to all of the samples. Improved
  70.  * documentation in SAX and DOM parsers.
  71.  *
  72.  * Revision 1.5  2000/03/02 19:55:52  roddey
  73.  * This checkin includes many changes done while waiting for the
  74.  * 1.1.0 code to be finished. I can't list them all here, but a list is
  75.  * available elsewhere.
  76.  *
  77.  * Revision 1.4  2000/02/14 19:25:44  roddey
  78.  * Fixed some small bugs in how it used strings returned from DOM calls.
  79.  *
  80.  * Revision 1.3  2000/02/06 07:48:41  rahulj
  81.  * Year 2K copyright swat.
  82.  *
  83.  * Revision 1.2  2000/01/05 20:24:58  roddey
  84.  * Some changes to simplify life for the Messge Catalog message loader. The formatter
  85.  * for the message loader now spits out a simple header of ids that allows the loader to
  86.  * be independent of hard coded set numbers.
  87.  *
  88.  * Revision 1.1.1.1  1999/11/09 01:01:12  twl
  89.  * Initial checkin
  90.  *
  91.  * Revision 1.5  1999/11/08 20:42:04  rahul
  92.  * Swat for adding in Product name and CVS comment log variable.
  93.  *
  94.  */
  95. // ---------------------------------------------------------------------------
  96. //  This program is designed to parse an XML file which holds error text
  97. //  data. It will build a DOM tree from that source file and can output it
  98. //  a number of different formats.
  99. //
  100. //  In order to drastically simplify the program, it is designed only to run
  101. //  on platforms/compilers that understand Unicode. It can output the data
  102. //  in whatever format is required, so it can handle outputting for other
  103. //  platforms. This also simplifies bootstrapping new releases up on other
  104. //  platforms. Once the Win32 version is working, it can generate output for
  105. //  the other platforms so that they can have loadable text from day one.
  106. // ---------------------------------------------------------------------------
  107. // ---------------------------------------------------------------------------
  108. //  Includes 
  109. // ---------------------------------------------------------------------------
  110. #include "Xlat.hpp"
  111. // ---------------------------------------------------------------------------
  112. //  Static data
  113. //
  114. //  gRelativeInputPath
  115. //      This is the path, relative to the given input source root, to the
  116. //      input file. The given local suffix must also be added to it.
  117. // ---------------------------------------------------------------------------
  118. static XMLCh* const     gRelativeInputPath  = L"src/NLS/";
  119. // ---------------------------------------------------------------------------
  120. //  Global data
  121. // ---------------------------------------------------------------------------
  122. const XMLCh* typePrefixes[MsgTypes_Count] = 
  123. {
  124.     L"W_"
  125.     , L"E_"
  126.     , L"F_"
  127. };
  128. // ---------------------------------------------------------------------------
  129. //  Local data
  130. //
  131. //  gLocale
  132. //      This is the locale suffix, e.g. US_EN, that is used to find the
  133. //      correct file and can be used on output files as well. Its set via
  134. //      the /Locale= parameter.
  135. //
  136. //  gOutFormat
  137. //      This is the output format, which is given on the command line as
  138. //      /OutFmt= Its mapped to the internal enum which is stored here.
  139. //
  140. //  gOutPath
  141. //      This is the path to the output path, which is given on the command
  142. //      line as /OutPath=. Its just the path, not a name, since the output
  143. //      might consist of multiple output files. They will all be based on
  144. //      the base part of the input name.
  145. //
  146. //  gSrcRoot
  147. //      This the path to the root of the build tree. The input files needed
  148. //      are found in known places relative to it.
  149. // ---------------------------------------------------------------------------
  150. const XMLCh*    gLocale = 0;
  151. OutFormats      gOutFormat = OutFormat_Unknown;
  152. const XMLCh*    gOutPath = 0;
  153. const XMLCh*    gSrcRoot = 0;
  154. // ---------------------------------------------------------------------------
  155. //  Local utility methods
  156. // ---------------------------------------------------------------------------
  157. //
  158. //  This method is called to parse the parameters. They must be in this
  159. //  order and format, for simplicity:
  160. //
  161. //  /SrcRoot=xxx /OutPath=xxx /OutFmt=xxx /Locale=xxx
  162. //
  163. static bool parseParms(const int argC, XMLCh** argV)
  164. {
  165.     if (argC < 5)
  166.         return false;
  167.     unsigned int curParm = 1;
  168.     if (XMLString::startsWith(argV[curParm], L"/SrcRoot="))
  169.     {
  170.         gSrcRoot = &argV[curParm][9];
  171.     }
  172.      else
  173.     {
  174.         wprintf(L"nExpected /SrcRoot=xxx. Got: %sn", argV[curParm]);
  175.         return false;
  176.     }
  177.     curParm++;
  178.     if (XMLString::startsWith(argV[curParm], L"/OutPath="))
  179.     {
  180.         gOutPath = &argV[curParm][9];
  181.     }
  182.      else
  183.     {
  184.         wprintf(L"nExpected /OutPath=xxx. Got: %sn", argV[curParm]);
  185.         return false;
  186.     }
  187.     curParm++;
  188.     if (XMLString::startsWith(argV[curParm], L"/OutFmt="))
  189.     {
  190.         const XMLCh* tmpFmt = &argV[curParm][8];
  191.         if (!XMLString::compareIString(tmpFmt, L"ResBundle"))
  192.             gOutFormat = OutFormat_ResBundle;
  193.         else if (!XMLString::compareIString(tmpFmt, L"Win32RC"))
  194.             gOutFormat = OutFormat_Win32RC;
  195.         else if (!XMLString::compareIString(tmpFmt, L"CppSrc"))
  196.             gOutFormat = OutFormat_CppSrc;
  197.         else if (!XMLString::compareIString(tmpFmt, L"MsgCat"))
  198.             gOutFormat = OutFormat_MsgCatalog;
  199.         else
  200.         {
  201.             wprintf(L"n'%s' is not a legal output formatn", tmpFmt);
  202.             return false;
  203.         }
  204.     }
  205.      else
  206.     {
  207.         wprintf(L"nExpected /OutFmt=xxx. Got: %sn", argV[curParm]);
  208.         return false;
  209.     }
  210.     curParm++;
  211.     if (XMLString::startsWith(argV[curParm], L"/Locale="))
  212.     {
  213.         gLocale = &argV[curParm][8];
  214.     }
  215.      else
  216.     {
  217.         wprintf(L"nExpected /Locale=xxx. Got: %sn", argV[curParm]);
  218.         return false;
  219.     }
  220.     return true;
  221. }
  222. static void parseError(const XMLException& toCatch)
  223. {
  224.     wprintf
  225.     (
  226.         L"Exceptionn   (Line.File):%d.%sn   ERROR: %snn"
  227.         , toCatch.getSrcLine()
  228.         , toCatch.getSrcFile()
  229.         , toCatch.getMessage()
  230.     );
  231.     throw ErrReturn_ParseErr;
  232. }
  233. static void parseError(const SAXParseException& toCatch)
  234. {
  235.     wprintf
  236.     (
  237.         L"SAX Parse Error:n   (Line.Col.SysId): %d.%d.%sn   ERROR: %snn"
  238.         , toCatch.getLineNumber()
  239.         , toCatch.getColumnNumber()
  240.         , toCatch.getSystemId()
  241.         , toCatch.getMessage()
  242.     );
  243.     throw ErrReturn_ParseErr;
  244. }
  245. static void
  246. enumMessages(   const   DOM_Element             srcElem
  247.                 ,       XlatFormatter* const    toCall
  248.                 ,       FILE* const             headerFl
  249.                 , const MsgTypes                msgType
  250.                 ,       unsigned int&           count)
  251. {
  252.     fwprintf
  253.     (
  254.         headerFl
  255.         , L"      , %s%-30s   = %dn"
  256.         , typePrefixes[msgType]
  257.         , L"LowBounds"
  258.         , count++
  259.     );
  260.     //
  261.     //  We just run through each of the child elements, each of which is
  262.     //  a Message element. Each one represents a message to output. We keep
  263.     //  a count so that we can output a const value afterwards.
  264.     //
  265.     DOM_Node curNode = srcElem.getFirstChild();
  266.     while (!curNode.isNull())
  267.     {
  268.         // Skip over text nodes or comment nodes ect...
  269.         if (curNode.getNodeType() != DOM_Node::ELEMENT_NODE)
  270.         {
  271.             curNode = curNode.getNextSibling();
  272.             continue;
  273.         }
  274.         // Convert it to an element node
  275.         const DOM_Element& curElem = (const DOM_Element&)curNode;
  276.         // Ok, this should be a Message node
  277.         if (!curElem.getTagName().equals(L"Message"))
  278.         {
  279.             wprintf(L"Expected a Message nodenn");
  280.             throw ErrReturn_SrcFmtError;
  281.         }
  282.         //
  283.         //  Ok, lets pull out the id, text value, and message type. These are
  284.         //  to be passed to the formatter. We have to translate the message
  285.         //  type into one of the offical enum values.
  286.         //
  287.         DOMString msgText = curElem.getAttribute(L"Text");
  288.         DOMString msgId   = curElem.getAttribute(L"Id");
  289.         //
  290.         //  Write out an entry to the target header file. These are enums, so
  291.         //  we use the id as the enum name.
  292.         //
  293.         fwprintf(headerFl, L"      , %-32s   = %dn", msgId.rawBuffer(), count);
  294.         // And tell the formatter about this one
  295.         toCall->nextMessage
  296.         (
  297.             msgText.rawBuffer()
  298.             , msgId.rawBuffer()
  299.             , count
  300.             , count
  301.         );
  302.         // Bump the counter, which is also the id assigner
  303.         count++;
  304.         // Move to the next child of the source element
  305.         curNode = curNode.getNextSibling();
  306.     }
  307.     // Write out an upper range bracketing id for this type of error
  308.     fwprintf
  309.     (
  310.         headerFl
  311.         , L"      , %s%-30s   = %dn"
  312.         , typePrefixes[msgType]
  313.         , L"HighBounds"
  314.         , count++
  315.     );
  316. }
  317. // ---------------------------------------------------------------------------
  318. //  Program entry point
  319. // ---------------------------------------------------------------------------
  320. //
  321. //  This is the program entry point. It checks the parms, parses the input
  322. //  file to get a DOM tree, then passes the DOM tree to the appropriate
  323. //  output method to output the info in a particular format.
  324. //
  325. extern "C" int wmain(int argC, XMLCh** argV)
  326. {
  327.     try
  328.     {
  329.         XMLPlatformUtils::Initialize();
  330.     }
  331.     catch(const XMLException& toCatch)
  332.     {
  333.         wprintf(L"Parser init error.n  ERROR: %snn", toCatch.getMessage());
  334.         return ErrReturn_ParserInit;
  335.     }
  336.     //
  337.     //  Lets check the parameters and save them away in globals for use by
  338.     //  the processing code.
  339.     //
  340.     if (!parseParms(argC, argV))
  341.     {
  342.         wprintf(L"Usage:n  NLSXlat /SrcRoot=xx /OutPath=xx /OutFmt=xx /Locale=xxnn");
  343.         return ErrReturn_BadParameters;
  344.     }
  345.     DOM_Document srcDoc;
  346.     const unsigned int bufSize = 4095;
  347.     XMLCh tmpFileBuf[bufSize + 1];
  348.     try
  349.     {
  350.         try
  351.         {
  352.             // Build the input file name
  353.             swprintf
  354.             (
  355.                 tmpFileBuf
  356.                 , L"%s%s%s/XMLErrList_%s.Xml"
  357.                 , gSrcRoot
  358.                 , gRelativeInputPath
  359.                 , gLocale
  360.                 , gLocale
  361.             );
  362.             //
  363.             //  Ok, lets invoke the DOM parser on the input file and build
  364.             //  a DOM tree. Turn on validation when we do this.
  365.             //
  366.             DOMParser parser;
  367.             parser.setDoValidation(true);
  368.             XlatErrHandler errHandler;
  369.             parser.setErrorHandler(&errHandler);
  370.             parser.parse(tmpFileBuf);
  371.             srcDoc = parser.getDocument();
  372.         }
  373.         catch(const XMLException& toCatch)
  374.         {
  375.             parseError(toCatch);
  376.         }
  377.         //
  378.         //  Use the output format parm to create the correct kind of output
  379.         //  formatter.
  380.         //
  381.         XlatFormatter* formatter = 0;
  382.         switch(gOutFormat)
  383.         {
  384.             case OutFormat_CppSrc :
  385.                 formatter = new CppSrcFormatter;
  386.                 break;
  387.             case OutFormat_Win32RC :
  388.                 formatter = new Win32RCFormatter;
  389.                 break;
  390.             case OutFormat_MsgCatalog :
  391.                 formatter = new MsgCatFormatter;
  392.                 break;
  393.             default :
  394.                 wprintf(L"Uknown formatter type enumnn");
  395.                 throw ErrReturn_Internal;
  396.         }
  397.         //
  398.         //  Lets handle the root element stuff first. This one holds any over
  399.         //  all information.
  400.         //
  401.         DOM_Element rootElem = srcDoc.getDocumentElement();
  402.         DOMString localeStr = rootElem.getAttribute(L"Locale");
  403.         // Make sure that the locale matches what we were given
  404.         if (XMLString::compareString(localeStr.rawBuffer(), gLocale))
  405.         {
  406.             wprintf(L"The file's locale does not match the target localen");
  407.             throw ErrReturn_LocaleErr;
  408.         }
  409.         //
  410.         //  Get a list of all the MsgDomain children. These each hold one of
  411.         //  the sets of (potentially separately) loadable messages. More
  412.         //  importantly they all have their own error id space.
  413.         //
  414.         DOM_NodeList msgSetList = rootElem.getElementsByTagName(L"MsgDomain");
  415.         //
  416.         //  Loop through them and look for the domains that we know are
  417.         //  supposed to be there.
  418.         //
  419.         const unsigned int count = msgSetList.getLength();
  420.         //
  421.         //  Ok, its good enough to get started. So lets call the start output
  422.         //  method on the formatter.
  423.         //
  424.         formatter->startOutput(localeStr.rawBuffer(), gOutPath);
  425.         //
  426.         //  For each message domain element, we call start and end domain
  427.         //  events bracketed around the loop that sends out each message
  428.         //  in that domain.
  429.         //
  430.         //  Within each domain, we check for the Warning, Error, and Validity
  431.         //  subelements, and then iterate all the messages in each one.
  432.         //
  433.         for (unsigned int index = 0; index < count; index++)
  434.         {
  435.             // We know its a DOM Element, so go ahead and cast it
  436.             DOM_Node curNode = msgSetList.item(index);
  437.             const DOM_Element& curElem = (const DOM_Element&)curNode;
  438.             //
  439.             //  Get some of  the attribute strings that we need, and transcode
  440.             //  couple that need to be in local format.
  441.             //
  442.             DOMString domainStr = curElem.getAttribute(L"Domain");
  443.             //
  444.             //  Look at the domain and set up our application specific info
  445.             //  that is on a per-domain basis. We need to indicate what the
  446.             //  name of the header is and what the namespace is that they
  447.             //  codes will go into
  448.             //
  449.             const XMLCh* headerName = 0;
  450.             const XMLCh* errNameSpace = 0;
  451.             if (!XMLString::compareString(domainStr.rawBuffer(), XMLUni::fgXMLErrDomain))
  452.             {
  453.                 headerName = L"XMLErrorCodes.hpp";
  454.                 errNameSpace = L"XMLErrs";
  455.             }
  456.              else if (!XMLString::compareString(domainStr.rawBuffer(), XMLUni::fgValidityDomain))
  457.             {
  458.                 headerName = L"XMLValidityCodes.hpp";
  459.                 errNameSpace = L"XMLValid";
  460.             }
  461.              else if (!XMLString::compareString(domainStr.rawBuffer(), XMLUni::fgExceptDomain))
  462.             {
  463.                 headerName = L"XMLExceptMsgs.hpp";
  464.                 errNameSpace = L"XMLExcepts";
  465.             }
  466.              else
  467.             {
  468.                 // Not one of ours, so skip it
  469.                 continue;
  470.             }
  471.             //
  472.             //  Lets try to create the header file that was indicated for
  473.             //  this domain.
  474.             //
  475.             swprintf
  476.             (
  477.                 tmpFileBuf
  478.                 , L"%s%s"
  479.                 , gOutPath
  480.                 , headerName
  481.             );
  482.             FILE* outHeader = _wfopen(tmpFileBuf, L"wt+");
  483.             if (!outHeader)
  484.             {
  485.                 wprintf(L"Could not open domain header file: %snn", tmpFileBuf);
  486.                 throw ErrReturn_OutFileOpenFailed;
  487.             }
  488.             //
  489.             //  Write out the opening of the class they are nested within, and
  490.             //  the header protection define.
  491.             //
  492.             fwprintf(outHeader, L"// This file is generated, don't edit it!!nn");
  493.             fwprintf(outHeader, L"#if !defined(ERRHEADER_%s)n", errNameSpace);
  494.             fwprintf(outHeader, L"#define ERRHEADER_%snn", errNameSpace);
  495.             // If its not the exception domain, then we need a header included
  496.             if (XMLString::compareString(domainStr.rawBuffer(), XMLUni::fgExceptDomain))
  497.                 fwprintf(outHeader, L"#include <framework/XMLErrorReporter.hpp>nn");
  498.             fwprintf(outHeader, L"class %sn{npublic :n    enum Codesn    {n", errNameSpace);
  499.             // Tell the formatter that a new domain is starting
  500.             formatter->startDomain
  501.             (
  502.                 domainStr.rawBuffer()
  503.                 , errNameSpace
  504.             );
  505.             //
  506.             //  Force out the first message, which is always implicit and is
  507.             //  the 'no error' entry for that domain.
  508.             //
  509.             unsigned int count = 0;
  510.             fwprintf(outHeader, L"        %-32s   = %dn", L"NoError", count++);
  511.             //
  512.             //  Loop through the children of this node, which should take us
  513.             //  through the optional Warning, Error, and Validity subsections.
  514.             //
  515.             DOM_Node typeNode = curElem.getFirstChild();
  516.             bool typeGotten[3] = { false, false, false };
  517.             while (!typeNode.isNull())
  518.             {
  519.                 // Skip over text nodes or comment nodes ect...
  520.                 if (typeNode.getNodeType() != DOM_Node::ELEMENT_NODE)
  521.                 {
  522.                     typeNode = typeNode.getNextSibling();
  523.                     continue;
  524.                 }
  525.                 // Convert it to an element node
  526.                 const DOM_Element& typeElem = (const DOM_Element&)typeNode;
  527.                 // Now get its tag name and convert that to a message type enum
  528.                 DOMString typeName = typeElem.getTagName();
  529.                 MsgTypes type;
  530.                 if (typeName.equals(L"Warning"))
  531.                 {
  532.                     type = MsgType_Warning;
  533.                     typeGotten[0] = true;
  534.                 }
  535.                  else if (typeName.equals(L"Error"))
  536.                 {
  537.                     type = MsgType_Error;
  538.                     typeGotten[1] = true;
  539.                 }
  540.                  else if (typeName.equals(L"FatalError"))
  541.                 {
  542.                     type = MsgType_FatalError;
  543.                     typeGotten[2] = true;
  544.                 }
  545.                  else
  546.                 {
  547.                     wprintf(L"Expected a Warning, Error, or FatalError nodenn");
  548.                     throw ErrReturn_SrcFmtError;
  549.                 }
  550.                 // Call the start message type event
  551.                 formatter->startMsgType(type);
  552.                 // Enumerate the messages under this subsection
  553.                 enumMessages
  554.                 (
  555.                     typeElem
  556.                     , formatter
  557.                     , outHeader
  558.                     , type
  559.                     , count
  560.                 );
  561.                 // Call the end message type event
  562.                 formatter->endMsgType(type);
  563.                 // Move to the next child of the source element
  564.                 typeNode = typeNode.getNextSibling();
  565.             }
  566.             //
  567.             //  For any that we did not get, spit out faux boundary
  568.             //  values for it.
  569.             //
  570.             for (unsigned int subIndex = 0; subIndex < 3; subIndex++)
  571.             {
  572.                 if (!typeGotten[subIndex])
  573.                 {
  574.                     fwprintf
  575.                     (
  576.                         outHeader
  577.                         , L"      , %s%-30s   = %dn"
  578.                         , typePrefixes[subIndex]
  579.                         , L"LowBounds"
  580.                         , count++
  581.                     );
  582.                     fwprintf
  583.                     (
  584.                         outHeader
  585.                         , L"      , %s%-30s   = %dn"
  586.                         , typePrefixes[subIndex]
  587.                         , L"HighBounds"
  588.                         , count++
  589.                     );
  590.                 }
  591.             }
  592.             // Tell the formatter that this domain is ending
  593.             formatter->endDomain(domainStr.rawBuffer(), count);
  594.             // Close out the enum declaration
  595.             fwprintf(outHeader, L"    };nn");
  596.             //
  597.             //  Generate the code that creates the simple static methods
  598.             //  for testing the error types. We don't do this for the
  599.             //  exceptions header.
  600.             //
  601.             if (XMLString::compareString(domainStr.rawBuffer(), XMLUni::fgExceptDomain))
  602.             {
  603.                 fwprintf
  604.                 (
  605.                     outHeader
  606.                     , L"    static bool isFatal(const %s::Codes toCheck)n"
  607.                       L"    {n"
  608.                       L"        return ((toCheck >= F_LowBounds) && (toCheck <= F_HighBounds));n"
  609.                       L"    }nn"
  610.                     , errNameSpace
  611.                 );
  612.                 fwprintf
  613.                 (
  614.                     outHeader
  615.                     , L"    static bool isWarning(const %s::Codes toCheck)n"
  616.                       L"    {n"
  617.                       L"        return ((toCheck >= W_LowBounds) && (toCheck <= W_HighBounds));n"
  618.                       L"    }nn"
  619.                     , errNameSpace
  620.                 );
  621.                 fwprintf
  622.                 (
  623.                     outHeader
  624.                     , L"    static bool isError(const %s::Codes toCheck)n"
  625.                       L"    {n"
  626.                       L"        return ((toCheck >= E_LowBounds) && (toCheck <= E_HighBounds));n"
  627.                       L"    }nn"
  628.                     , errNameSpace
  629.                 );
  630.                 fwprintf
  631.                 (
  632.                     outHeader
  633.                     , L"    static XMLErrorReporter::ErrTypes errorType(const %s::Codes toCheck)n"
  634.                       L"    {n"
  635.                       L"       if ((toCheck >= W_LowBounds) && (toCheck <= W_HighBounds))n"
  636.                       L"           return XMLErrorReporter::ErrType_Warning;n"
  637.                       L"       else if ((toCheck >= F_LowBounds) && (toCheck <= F_HighBounds))n"
  638.                       L"            return XMLErrorReporter::ErrType_Fatal;n"
  639.                       L"       else if ((toCheck >= E_LowBounds) && (toCheck <= E_HighBounds))n"
  640.                       L"            return XMLErrorReporter::ErrType_Error;n"
  641.                       L"       return XMLErrorReporter::ErrTypes_Unknown;n"
  642.                       L"    }n"
  643.                     , errNameSpace
  644.                 );
  645.             }
  646.             // And close out the class declaration and the header file
  647.             fwprintf(outHeader, L"};n#endifnn");
  648.             fclose(outHeader);
  649.         }
  650.         // Ok, we are done so call the end output method
  651.         formatter->endOutput();
  652.         // And clean up the stuff we allocated
  653.         delete formatter;
  654.     }
  655.     catch(const ErrReturns retVal)
  656.     {
  657.         // And call the termination method
  658.         XMLPlatformUtils::Terminate();
  659.         return retVal;
  660.     }
  661.     // And call the termination method
  662.     XMLPlatformUtils::Terminate();
  663.     // Went ok, so return success
  664.     return ErrReturn_Success;
  665. }
  666. // -----------------------------------------------------------------------
  667. //  XlatErrHandler: Implementation of the error handler interface
  668. // -----------------------------------------------------------------------
  669. void XlatErrHandler::warning(const SAXParseException& toCatch)
  670. {
  671.     parseError(toCatch);
  672. }
  673. void XlatErrHandler::error(const SAXParseException& toCatch)
  674. {
  675.     parseError(toCatch);
  676. }
  677. void XlatErrHandler::fatalError(const SAXParseException& toCatch)
  678. {
  679.     parseError(toCatch);
  680. }
  681. void XlatErrHandler::resetErrors()
  682. {
  683. }