]> matita.cs.unibo.it Git - helm.git/blob - helm/papers/use_case/stats/parse/SAX2Print/SAX2Print.cpp
ocaml 3.09 transition
[helm.git] / helm / papers / use_case / stats / parse / SAX2Print / SAX2Print.cpp
1 /*
2  * Copyright 1999-2001,2004 The Apache Software Foundation.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * $Log$
19  * Revision 1.1  2004/11/23 13:38:52  lpadovan
20  * * basic infrastructure for collecting statistics
21  *
22  * Revision 1.17  2004/09/08 13:55:33  peiyongz
23  * Apache License Version 2.0
24  *
25  * Revision 1.16  2004/09/02 14:59:29  cargilld
26  * Add OutOfMemoryException block to samples.
27  *
28  * Revision 1.15  2004/02/06 15:04:16  cargilld
29  * Misc 390 changes.
30  *
31  * Revision 1.14  2003/08/07 21:21:38  neilg
32  * fix segmentation faults that may arise when the parser throws exceptions during document parsing.  In general, XMLPlatformUtils::Terminate() should not be called from within a catch statement.
33  *
34  * Revision 1.13  2003/05/30 09:36:36  gareth
35  * Use new macros for iostream.h and std:: issues.
36  *
37  * Revision 1.12  2002/06/17 15:33:00  tng
38  * Name Xerces features as XMLUni::fgXercesXXXX instead of XMLUni::fgSAX2XercesXXXX so that they can be shared with DOM parser.
39  *
40  * Revision 1.11  2002/05/28 20:20:26  tng
41  * Add option '-n' to SAX2Print.
42  *
43  * Revision 1.10  2002/04/17 20:18:08  tng
44  * [Bug 7493] The word "occured" is misspelled and it is a global error.
45  *
46  * Revision 1.9  2002/02/13 16:11:06  knoaman
47  * Update samples to use SAX2 features/properties constants from XMLUni.
48  *
49  * Revision 1.8  2002/02/06 16:36:51  knoaman
50  * Added a new flag '-p' to SAX2 samples to set the 'namespace-prefixes' feature.
51  *
52  * Revision 1.7  2002/02/01 22:40:44  peiyongz
53  * sane_include
54  *
55  * Revision 1.6  2001/10/25 15:18:33  tng
56  * delete the parser before XMLPlatformUtils::Terminate.
57  *
58  * Revision 1.5  2001/10/19 19:02:43  tng
59  * [Bug 3909] return non-zero an exit code when error was encounted.
60  * And other modification for consistent help display and return code across samples.
61  *
62  * Revision 1.4  2001/08/02 17:10:29  tng
63  * Allow DOMCount/SAXCount/IDOMCount/SAX2Count to take a file that has a list of xml file as input.
64  *
65  * Revision 1.3  2001/08/01 19:11:01  tng
66  * Add full schema constraint checking flag to the samples and the parser.
67  *
68  * Revision 1.2  2000/08/09 22:20:38  jpolast
69  * updates for changes to sax2 core functionality.
70  *
71  * Revision 1.1  2000/08/02 19:16:14  jpolast
72  * initial checkin of SAX2Print
73  *
74  *
75  */
76
77
78 // ---------------------------------------------------------------------------
79 //  Includes
80 // ---------------------------------------------------------------------------
81 #include <xercesc/util/PlatformUtils.hpp>
82 #include <xercesc/util/TransService.hpp>
83 #include <xercesc/sax2/SAX2XMLReader.hpp>
84 #include <xercesc/sax2/XMLReaderFactory.hpp>
85 #include "SAX2Print.hpp"
86 #include <xercesc/util/OutOfMemoryException.hpp>
87 #include <sys/time.h>
88
89 // ---------------------------------------------------------------------------
90 //  Local data
91 //
92 //  encodingName
93 //      The encoding we are to output in. If not set on the command line,
94 //      then it is defaulted to LATIN1.
95 //
96 //  xmlFile
97 //      The path to the file to parser. Set via command line.
98 //
99 //  valScheme
100 //      Indicates what validation scheme to use. It defaults to 'auto', but
101 //      can be set via the -v= command.
102 //
103 //      expandNamespaces
104 //              Indicates if the output should expand the namespaces Alias with
105 //              their URI's, defaults to false, can be set via the command line -e
106 // ---------------------------------------------------------------------------
107 static const char*              encodingName    = "LATIN1";
108 static XMLFormatter::UnRepFlags unRepFlags      = XMLFormatter::UnRep_CharRef;
109 static char*                    xmlFile         = 0;
110 static SAX2XMLReader::ValSchemes valScheme      = SAX2XMLReader::Val_Auto;
111 static bool                                             expandNamespaces= false ;
112 static bool                     doNamespaces    = true;
113 static bool                     doSchema        = true;
114 static bool                     schemaFullChecking = false;
115 static bool                     namespacePrefixes = false;
116
117
118 // ---------------------------------------------------------------------------
119 //  Local helper methods
120 // ---------------------------------------------------------------------------
121 static void usage()
122 {
123     XERCES_STD_QUALIFIER cout << "\nUsage:\n"
124             "    SAX2Print [options] <XML file>\n\n"
125             "This program invokes the SAX2XMLReader, and then prints the\n"
126             "data returned by the various SAX2 handlers for the specified\n"
127             "XML file.\n\n"
128             "Options:\n"
129              "    -u=xxx      Handle unrepresentable chars [fail | rep | ref*].\n"
130              "    -v=xxx      Validation scheme [always | never | auto*].\n"
131              "    -e          Expand Namespace Alias with URI's. Defaults to off.\n"
132              "    -x=XXX      Use a particular encoding for output (LATIN1*).\n"
133              "    -f          Enable full schema constraint checking processing. Defaults to off.\n"
134              "    -p          Enable namespace-prefixes feature. Defaults to off.\n"
135              "    -n          Disable namespace processing. Defaults to on.\n"
136              "                NOTE: THIS IS OPPOSITE FROM OTHER SAMPLES.\n"
137              "    -s          Disable schema processing. Defaults to on.\n"
138              "                NOTE: THIS IS OPPOSITE FROM OTHER SAMPLES.\n"
139              "    -?          Show this help.\n\n"
140              "  * = Default if not provided explicitly.\n\n"
141              "The parser has intrinsic support for the following encodings:\n"
142              "    UTF-8, USASCII, ISO8859-1, UTF-16[BL]E, UCS-4[BL]E,\n"
143              "    WINDOWS-1252, IBM1140, IBM037, IBM1047.\n"
144          <<  XERCES_STD_QUALIFIER endl;
145 }
146
147
148
149 // ---------------------------------------------------------------------------
150 //  Program entry point
151 // ---------------------------------------------------------------------------
152 int main(int argC, char* argV[])
153 {
154     // Initialize the XML4C2 system
155     try
156     {
157          XMLPlatformUtils::Initialize();
158     }
159
160     catch (const XMLException& toCatch)
161     {
162          XERCES_STD_QUALIFIER cerr << "Error during initialization! :\n"
163               << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
164          return 1;
165     }
166
167     // Check command line and extract arguments.
168     if (argC < 2)
169     {
170         usage();
171         XMLPlatformUtils::Terminate();
172         return 1;
173     }
174
175     int parmInd;
176     for (parmInd = 1; parmInd < argC; parmInd++)
177     {
178         // Break out on first parm not starting with a dash
179         if (argV[parmInd][0] != '-')
180             break;
181
182         // Watch for special case help request
183         if (!strcmp(argV[parmInd], "-?"))
184         {
185             usage();
186             XMLPlatformUtils::Terminate();
187             return 2;
188         }
189          else if (!strncmp(argV[parmInd], "-v=", 3)
190               ||  !strncmp(argV[parmInd], "-V=", 3))
191         {
192             const char* const parm = &argV[parmInd][3];
193
194             if (!strcmp(parm, "never"))
195                 valScheme = SAX2XMLReader::Val_Never;
196             else if (!strcmp(parm, "auto"))
197                 valScheme = SAX2XMLReader::Val_Auto;
198             else if (!strcmp(parm, "always"))
199                 valScheme = SAX2XMLReader::Val_Always;
200             else
201             {
202                 XERCES_STD_QUALIFIER cerr << "Unknown -v= value: " << parm << XERCES_STD_QUALIFIER endl;
203                 XMLPlatformUtils::Terminate();
204                 return 2;
205             }
206         }
207          else if (!strcmp(argV[parmInd], "-e")
208               ||  !strcmp(argV[parmInd], "-E"))
209         {
210             expandNamespaces = true;
211         }
212          else if (!strncmp(argV[parmInd], "-x=", 3)
213               ||  !strncmp(argV[parmInd], "-X=", 3))
214         {
215             // Get out the encoding name
216             encodingName = &argV[parmInd][3];
217         }
218          else if (!strncmp(argV[parmInd], "-u=", 3)
219               ||  !strncmp(argV[parmInd], "-U=", 3))
220         {
221             const char* const parm = &argV[parmInd][3];
222
223             if (!strcmp(parm, "fail"))
224                 unRepFlags = XMLFormatter::UnRep_Fail;
225             else if (!strcmp(parm, "rep"))
226                 unRepFlags = XMLFormatter::UnRep_Replace;
227             else if (!strcmp(parm, "ref"))
228                 unRepFlags = XMLFormatter::UnRep_CharRef;
229             else
230             {
231                 XERCES_STD_QUALIFIER cerr << "Unknown -u= value: " << parm << XERCES_STD_QUALIFIER endl;
232                 XMLPlatformUtils::Terminate();
233                 return 2;
234             }
235         }
236          else if (!strcmp(argV[parmInd], "-n")
237               ||  !strcmp(argV[parmInd], "-N"))
238         {
239             doNamespaces = false;
240         }
241          else if (!strcmp(argV[parmInd], "-s")
242               ||  !strcmp(argV[parmInd], "-S"))
243         {
244             doSchema = false;
245         }
246          else if (!strcmp(argV[parmInd], "-f")
247               ||  !strcmp(argV[parmInd], "-F"))
248         {
249             schemaFullChecking = true;
250         }
251          else if (!strcmp(argV[parmInd], "-p")
252               ||  !strcmp(argV[parmInd], "-P"))
253         {
254             namespacePrefixes = true;
255         }
256          else
257         {
258             XERCES_STD_QUALIFIER cerr << "Unknown option '" << argV[parmInd]
259                  << "', ignoring it\n" << XERCES_STD_QUALIFIER endl;
260         }
261     }
262
263     //
264     //  And now we have to have only one parameter left and it must be
265     //  the file name.
266     //
267     if (parmInd + 1 != argC)
268     {
269         usage();
270         XMLPlatformUtils::Terminate();
271         return 1;
272     }
273     xmlFile = argV[parmInd];
274
275     //
276     //  Create a SAX parser object. Then, according to what we were told on
277     //  the command line, set it to validate or not.
278     //
279     SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
280
281     //
282     //  Then, according to what we were told on
283     //  the command line, set it to validate or not.
284     //
285     if (valScheme == SAX2XMLReader::Val_Auto)
286     {
287         parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
288         parser->setFeature(XMLUni::fgXercesDynamic, true);
289     }
290
291     if (valScheme == SAX2XMLReader::Val_Never)
292     {
293         parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
294     }
295
296     if (valScheme == SAX2XMLReader::Val_Always)
297     {
298         parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
299         parser->setFeature(XMLUni::fgXercesDynamic, false);
300     }
301
302     parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, doNamespaces);
303     parser->setFeature(XMLUni::fgXercesSchema, doSchema);
304     parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
305     parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, namespacePrefixes);
306
307     //
308     //  Create the handler object and install it as the document and error
309     //  handler for the parser. Then parse the file and catch any exceptions
310     //  that propogate out
311     //
312
313     struct timeval timing1, timing2;
314     int errorCount = 0;
315     int errorCode = 0;
316     try
317     {
318         SAX2PrintHandlers handler(encodingName, unRepFlags, expandNamespaces);
319         parser->setContentHandler(&handler);
320         parser->setErrorHandler(&handler);
321         gettimeofday(&timing1, NULL);
322         parser->parse(xmlFile);
323         gettimeofday(&timing2, NULL);
324         errorCount = parser->getErrorCount();
325     }
326     catch (const OutOfMemoryException&)
327     {
328         XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
329         errorCode = 5;          
330     }
331     catch (const XMLException& toCatch)
332     {
333         XERCES_STD_QUALIFIER cerr << "\nAn error occurred\n  Error: "
334              << StrX(toCatch.getMessage())
335              << "\n" << XERCES_STD_QUALIFIER endl;
336         errorCode = 4;
337     }
338
339     if(errorCode) {
340         XMLPlatformUtils::Terminate();
341         return errorCode;
342     }
343
344     //
345     //  Delete the parser itself.  Must be done prior to calling Terminate, below.
346     //
347     delete parser;
348
349     fprintf(stdout, "%d\n", ((timing2.tv_sec * 1000000 + timing2.tv_usec) - (timing1.tv_sec * 1000000 + timing1.tv_usec)) / 1000);
350
351     // And call the termination method
352     XMLPlatformUtils::Terminate();
353
354     if (errorCount > 0)
355         return 4;
356     else
357         return 0;
358 }
359