Annotation of XML/testDocbook.c, revision 1.3
1.1 veillard 1: /*
2: * testSGML.c : a small tester program for SGML input.
3: *
4: * See Copyright for the status of this software.
5: *
6: * Daniel.Veillard@w3.org
7: */
8:
9: #ifdef WIN32
10: #include "win32config.h"
11: #else
12: #include "config.h"
13: #endif
14:
15: #include "xmlversion.h"
16: #ifdef LIBXML_SGML_ENABLED
17:
18: #include <stdio.h>
19: #include <string.h>
20: #include <stdarg.h>
21:
22:
23: #ifdef HAVE_SYS_TYPES_H
24: #include <sys/types.h>
25: #endif
26: #ifdef HAVE_SYS_STAT_H
27: #include <sys/stat.h>
28: #endif
29: #ifdef HAVE_FCNTL_H
30: #include <fcntl.h>
31: #endif
32: #ifdef HAVE_UNISTD_H
33: #include <unistd.h>
34: #endif
35: #ifdef HAVE_STDLIB_H
36: #include <stdlib.h>
37: #endif
38:
39: #include <libxml/xmlmemory.h>
40: #include <libxml/SGMLparser.h>
41: #include <libxml/HTMLtree.h>
42: #include <libxml/tree.h>
43: #include <libxml/debugXML.h>
44:
45: #ifdef LIBXML_DEBUG_ENABLED
46: static int debug = 0;
47: #endif
48: static int copy = 0;
49: static int sax = 0;
50: static int repeat = 0;
51: static int noout = 0;
52: static int push = 0;
53: static char *encoding = NULL;
54:
55: xmlSAXHandler emptySAXHandlerStruct = {
56: NULL, /* internalSubset */
57: NULL, /* isStandalone */
58: NULL, /* hasInternalSubset */
59: NULL, /* hasExternalSubset */
60: NULL, /* resolveEntity */
61: NULL, /* getEntity */
62: NULL, /* entityDecl */
63: NULL, /* notationDecl */
64: NULL, /* attributeDecl */
65: NULL, /* elementDecl */
66: NULL, /* unparsedEntityDecl */
67: NULL, /* setDocumentLocator */
68: NULL, /* startDocument */
69: NULL, /* endDocument */
70: NULL, /* startElement */
71: NULL, /* endElement */
72: NULL, /* reference */
73: NULL, /* characters */
74: NULL, /* ignorableWhitespace */
75: NULL, /* processingInstruction */
76: NULL, /* comment */
77: NULL, /* xmlParserWarning */
78: NULL, /* xmlParserError */
79: NULL, /* xmlParserError */
80: NULL, /* getParameterEntity */
81: };
82:
83: xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
84: extern xmlSAXHandlerPtr debugSAXHandler;
85:
86: /************************************************************************
87: * *
88: * Debug Handlers *
89: * *
90: ************************************************************************/
91:
92: /**
93: * isStandaloneDebug:
94: * @ctxt: An XML parser context
95: *
96: * Is this document tagged standalone ?
97: *
98: * Returns 1 if true
99: */
100: int
101: isStandaloneDebug(void *ctx)
102: {
103: fprintf(stdout, "SAX.isStandalone()\n");
104: return(0);
105: }
106:
107: /**
108: * hasInternalSubsetDebug:
109: * @ctxt: An XML parser context
110: *
111: * Does this document has an internal subset
112: *
113: * Returns 1 if true
114: */
115: int
116: hasInternalSubsetDebug(void *ctx)
117: {
118: fprintf(stdout, "SAX.hasInternalSubset()\n");
119: return(0);
120: }
121:
122: /**
123: * hasExternalSubsetDebug:
124: * @ctxt: An XML parser context
125: *
126: * Does this document has an external subset
127: *
128: * Returns 1 if true
129: */
130: int
131: hasExternalSubsetDebug(void *ctx)
132: {
133: fprintf(stdout, "SAX.hasExternalSubset()\n");
134: return(0);
135: }
136:
137: /**
138: * hasInternalSubsetDebug:
139: * @ctxt: An XML parser context
140: *
141: * Does this document has an internal subset
142: */
143: void
144: internalSubsetDebug(void *ctx, const xmlChar *name,
145: const xmlChar *ExternalID, const xmlChar *SystemID)
146: {
147: fprintf(stdout, "SAX.internalSubset(%s,", name);
148: if (ExternalID == NULL)
149: fprintf(stdout, " ,");
150: else
151: fprintf(stdout, " %s,", ExternalID);
152: if (SystemID == NULL)
153: fprintf(stdout, " )\n");
154: else
155: fprintf(stdout, " %s)\n", SystemID);
156: }
157:
158: /**
159: * resolveEntityDebug:
160: * @ctxt: An XML parser context
161: * @publicId: The public ID of the entity
162: * @systemId: The system ID of the entity
163: *
164: * Special entity resolver, better left to the parser, it has
165: * more context than the application layer.
166: * The default behaviour is to NOT resolve the entities, in that case
167: * the ENTITY_REF nodes are built in the structure (and the parameter
168: * values).
169: *
170: * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
171: */
172: xmlParserInputPtr
173: resolveEntityDebug(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
174: {
175: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
176:
177:
178: fprintf(stdout, "SAX.resolveEntity(");
179: if (publicId != NULL)
180: fprintf(stdout, "%s", (char *)publicId);
181: else
182: fprintf(stdout, " ");
183: if (systemId != NULL)
184: fprintf(stdout, ", %s)\n", (char *)systemId);
185: else
186: fprintf(stdout, ", )\n");
187: /*********
188: if (systemId != NULL) {
189: return(xmlNewInputFromFile(ctxt, (char *) systemId));
190: }
191: *********/
192: return(NULL);
193: }
194:
195: /**
196: * getEntityDebug:
197: * @ctxt: An XML parser context
198: * @name: The entity name
199: *
200: * Get an entity by name
201: *
202: * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
203: */
204: xmlEntityPtr
205: getEntityDebug(void *ctx, const xmlChar *name)
206: {
207: fprintf(stdout, "SAX.getEntity(%s)\n", name);
208: return(NULL);
209: }
210:
211: /**
212: * getParameterEntityDebug:
213: * @ctxt: An XML parser context
214: * @name: The entity name
215: *
216: * Get a parameter entity by name
217: *
218: * Returns the xmlParserInputPtr
219: */
220: xmlEntityPtr
221: getParameterEntityDebug(void *ctx, const xmlChar *name)
222: {
223: fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
224: return(NULL);
225: }
226:
227:
228: /**
229: * entityDeclDebug:
230: * @ctxt: An XML parser context
231: * @name: the entity name
232: * @type: the entity type
233: * @publicId: The public ID of the entity
234: * @systemId: The system ID of the entity
235: * @content: the entity value (without processing).
236: *
237: * An entity definition has been parsed
238: */
239: void
240: entityDeclDebug(void *ctx, const xmlChar *name, int type,
241: const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
242: {
243: fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
244: name, type, publicId, systemId, content);
245: }
246:
247: /**
248: * attributeDeclDebug:
249: * @ctxt: An XML parser context
250: * @name: the attribute name
251: * @type: the attribute type
252: *
253: * An attribute definition has been parsed
254: */
255: void
256: attributeDeclDebug(void *ctx, const xmlChar *elem, const xmlChar *name,
257: int type, int def, const xmlChar *defaultValue,
258: xmlEnumerationPtr tree)
259: {
260: fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
261: elem, name, type, def, defaultValue);
262: }
263:
264: /**
265: * elementDeclDebug:
266: * @ctxt: An XML parser context
267: * @name: the element name
268: * @type: the element type
269: * @content: the element value (without processing).
270: *
271: * An element definition has been parsed
272: */
273: void
274: elementDeclDebug(void *ctx, const xmlChar *name, int type,
275: xmlElementContentPtr content)
276: {
277: fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
278: name, type);
279: }
280:
281: /**
282: * notationDeclDebug:
283: * @ctxt: An XML parser context
284: * @name: The name of the notation
285: * @publicId: The public ID of the entity
286: * @systemId: The system ID of the entity
287: *
288: * What to do when a notation declaration has been parsed.
289: */
290: void
291: notationDeclDebug(void *ctx, const xmlChar *name,
292: const xmlChar *publicId, const xmlChar *systemId)
293: {
294: fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
295: (char *) name, (char *) publicId, (char *) systemId);
296: }
297:
298: /**
299: * unparsedEntityDeclDebug:
300: * @ctxt: An XML parser context
301: * @name: The name of the entity
302: * @publicId: The public ID of the entity
303: * @systemId: The system ID of the entity
304: * @notationName: the name of the notation
305: *
306: * What to do when an unparsed entity declaration is parsed
307: */
308: void
309: unparsedEntityDeclDebug(void *ctx, const xmlChar *name,
310: const xmlChar *publicId, const xmlChar *systemId,
311: const xmlChar *notationName)
312: {
313: fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
314: (char *) name, (char *) publicId, (char *) systemId,
315: (char *) notationName);
316: }
317:
318: /**
319: * setDocumentLocatorDebug:
320: * @ctxt: An XML parser context
321: * @loc: A SAX Locator
322: *
323: * Receive the document locator at startup, actually xmlDefaultSAXLocator
324: * Everything is available on the context, so this is useless in our case.
325: */
326: void
327: setDocumentLocatorDebug(void *ctx, xmlSAXLocatorPtr loc)
328: {
329: fprintf(stdout, "SAX.setDocumentLocator()\n");
330: }
331:
332: /**
333: * startDocumentDebug:
334: * @ctxt: An XML parser context
335: *
336: * called when the document start being processed.
337: */
338: void
339: startDocumentDebug(void *ctx)
340: {
341: fprintf(stdout, "SAX.startDocument()\n");
342: }
343:
344: /**
345: * endDocumentDebug:
346: * @ctxt: An XML parser context
347: *
348: * called when the document end has been detected.
349: */
350: void
351: endDocumentDebug(void *ctx)
352: {
353: fprintf(stdout, "SAX.endDocument()\n");
354: }
355:
356: /**
357: * startElementDebug:
358: * @ctxt: An XML parser context
359: * @name: The element name
360: *
361: * called when an opening tag has been processed.
362: */
363: void
364: startElementDebug(void *ctx, const xmlChar *name, const xmlChar **atts)
365: {
366: int i;
367:
368: fprintf(stdout, "SAX.startElement(%s", (char *) name);
369: if (atts != NULL) {
370: for (i = 0;(atts[i] != NULL);i++) {
371: fprintf(stdout, ", %s", atts[i++]);
372: if (atts[i] != NULL) {
373: unsigned char output[40];
374: const unsigned char *att = atts[i];
375: int outlen, attlen;
376: fprintf(stdout, "='");
377: while ((attlen = strlen((char*)att)) > 0) {
378: outlen = sizeof output - 1;
379: sgmlEncodeEntities(output, &outlen, att, &attlen, '\'');
380: fprintf(stdout, "%.*s", outlen, output);
381: att += attlen;
382: }
383: fprintf(stdout, "'");
384: }
385: }
386: }
387: fprintf(stdout, ")\n");
388: }
389:
390: /**
391: * endElementDebug:
392: * @ctxt: An XML parser context
393: * @name: The element name
394: *
395: * called when the end of an element has been detected.
396: */
397: void
398: endElementDebug(void *ctx, const xmlChar *name)
399: {
400: fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
401: }
402:
403: /**
404: * charactersDebug:
405: * @ctxt: An XML parser context
406: * @ch: a xmlChar string
407: * @len: the number of xmlChar
408: *
409: * receiving some chars from the parser.
410: * Question: how much at a time ???
411: */
412: void
413: charactersDebug(void *ctx, const xmlChar *ch, int len)
414: {
415: unsigned char output[40];
416: int inlen = len, outlen = 30;
417:
418: sgmlEncodeEntities(output, &outlen, ch, &inlen, 0);
419: output[outlen] = 0;
420:
421: fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
422: }
423:
424: /**
425: * referenceDebug:
426: * @ctxt: An XML parser context
427: * @name: The entity name
428: *
429: * called when an entity reference is detected.
430: */
431: void
432: referenceDebug(void *ctx, const xmlChar *name)
433: {
434: fprintf(stdout, "SAX.reference(%s)\n", name);
435: }
436:
437: /**
438: * ignorableWhitespaceDebug:
439: * @ctxt: An XML parser context
440: * @ch: a xmlChar string
441: * @start: the first char in the string
442: * @len: the number of xmlChar
443: *
444: * receiving some ignorable whitespaces from the parser.
445: * Question: how much at a time ???
446: */
447: void
448: ignorableWhitespaceDebug(void *ctx, const xmlChar *ch, int len)
449: {
450: char output[40];
451: int i;
452:
453: for (i = 0;(i<len) && (i < 30);i++)
454: output[i] = ch[i];
455: output[i] = 0;
456:
457: fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
458: }
459:
460: /**
461: * processingInstructionDebug:
462: * @ctxt: An XML parser context
463: * @target: the target name
464: * @data: the PI data's
465: * @len: the number of xmlChar
466: *
467: * A processing instruction has been parsed.
468: */
469: void
470: processingInstructionDebug(void *ctx, const xmlChar *target,
471: const xmlChar *data)
472: {
473: fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
474: (char *) target, (char *) data);
475: }
476:
477: /**
478: * commentDebug:
479: * @ctxt: An XML parser context
480: * @value: the comment content
481: *
482: * A comment has been parsed.
483: */
484: void
485: commentDebug(void *ctx, const xmlChar *value)
486: {
487: fprintf(stdout, "SAX.comment(%s)\n", value);
488: }
489:
490: /**
491: * warningDebug:
492: * @ctxt: An XML parser context
493: * @msg: the message to display/transmit
494: * @...: extra parameters for the message display
495: *
496: * Display and format a warning messages, gives file, line, position and
497: * extra parameters.
498: */
499: void
500: warningDebug(void *ctx, const char *msg, ...)
501: {
502: va_list args;
503:
504: va_start(args, msg);
505: fprintf(stdout, "SAX.warning: ");
506: vfprintf(stdout, msg, args);
507: va_end(args);
508: }
509:
510: /**
511: * errorDebug:
512: * @ctxt: An XML parser context
513: * @msg: the message to display/transmit
514: * @...: extra parameters for the message display
515: *
516: * Display and format a error messages, gives file, line, position and
517: * extra parameters.
518: */
519: void
520: errorDebug(void *ctx, const char *msg, ...)
521: {
522: va_list args;
523:
524: va_start(args, msg);
525: fprintf(stdout, "SAX.error: ");
526: vfprintf(stdout, msg, args);
527: va_end(args);
528: }
529:
530: /**
531: * fatalErrorDebug:
532: * @ctxt: An XML parser context
533: * @msg: the message to display/transmit
534: * @...: extra parameters for the message display
535: *
536: * Display and format a fatalError messages, gives file, line, position and
537: * extra parameters.
538: */
539: void
540: fatalErrorDebug(void *ctx, const char *msg, ...)
541: {
542: va_list args;
543:
544: va_start(args, msg);
545: fprintf(stdout, "SAX.fatalError: ");
546: vfprintf(stdout, msg, args);
547: va_end(args);
548: }
549:
550: xmlSAXHandler debugSAXHandlerStruct = {
551: internalSubsetDebug,
552: isStandaloneDebug,
553: hasInternalSubsetDebug,
554: hasExternalSubsetDebug,
555: resolveEntityDebug,
556: getEntityDebug,
557: entityDeclDebug,
558: notationDeclDebug,
559: attributeDeclDebug,
560: elementDeclDebug,
561: unparsedEntityDeclDebug,
562: setDocumentLocatorDebug,
563: startDocumentDebug,
564: endDocumentDebug,
565: startElementDebug,
566: endElementDebug,
567: referenceDebug,
568: charactersDebug,
569: ignorableWhitespaceDebug,
570: processingInstructionDebug,
571: commentDebug,
572: warningDebug,
573: errorDebug,
574: fatalErrorDebug,
575: getParameterEntityDebug,
576: };
577:
578: xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
579: /************************************************************************
580: * *
581: * Debug *
582: * *
583: ************************************************************************/
584:
585: void parseSAXFile(char *filename) {
586: sgmlDocPtr doc = NULL;
587:
588: /*
589: * Empty callbacks for checking
590: */
591: if (push) {
592: FILE *f;
593:
594: f = fopen(filename, "r");
595: if (f != NULL) {
596: int res, size = 3;
597: char chars[4096];
598: sgmlParserCtxtPtr ctxt;
599:
600: /* if (repeat) */
601: size = 4096;
602: res = fread(chars, 1, 4, f);
603: if (res > 0) {
604: ctxt = sgmlCreatePushParserCtxt(emptySAXHandler, NULL,
605: chars, res, filename, 0);
606: while ((res = fread(chars, 1, size, f)) > 0) {
607: sgmlParseChunk(ctxt, chars, res, 0);
608: }
609: sgmlParseChunk(ctxt, chars, 0, 1);
610: doc = ctxt->myDoc;
611: sgmlFreeParserCtxt(ctxt);
612: }
613: if (doc != NULL) {
614: fprintf(stdout, "sgmlSAXParseFile returned non-NULL\n");
615: xmlFreeDoc(doc);
616: }
617: fclose(f);
618: }
619: if (!noout) {
620: f = fopen(filename, "r");
621: if (f != NULL) {
622: int res, size = 3;
623: char chars[4096];
624: sgmlParserCtxtPtr ctxt;
625:
626: /* if (repeat) */
627: size = 4096;
628: res = fread(chars, 1, 4, f);
629: if (res > 0) {
630: ctxt = sgmlCreatePushParserCtxt(debugSAXHandler, NULL,
631: chars, res, filename, 0);
632: while ((res = fread(chars, 1, size, f)) > 0) {
633: sgmlParseChunk(ctxt, chars, res, 0);
634: }
635: sgmlParseChunk(ctxt, chars, 0, 1);
636: doc = ctxt->myDoc;
637: sgmlFreeParserCtxt(ctxt);
638: }
639: if (doc != NULL) {
640: fprintf(stdout, "sgmlSAXParseFile returned non-NULL\n");
641: xmlFreeDoc(doc);
642: }
643: fclose(f);
644: }
645: }
646: } else {
647: doc = sgmlSAXParseFile(filename, NULL, emptySAXHandler, NULL);
648: if (doc != NULL) {
649: fprintf(stdout, "sgmlSAXParseFile returned non-NULL\n");
650: xmlFreeDoc(doc);
651: }
652:
653: if (!noout) {
654: /*
655: * Debug callback
656: */
657: doc = sgmlSAXParseFile(filename, NULL, debugSAXHandler, NULL);
658: if (doc != NULL) {
659: fprintf(stdout, "sgmlSAXParseFile returned non-NULL\n");
660: xmlFreeDoc(doc);
661: }
662: }
663: }
664: }
665:
666: void parseAndPrintFile(char *filename) {
667: sgmlDocPtr doc = NULL, tmp;
668:
669: /*
670: * build an SGML tree from a string;
671: */
672: if (push) {
673: FILE *f;
674:
675: f = fopen(filename, "r");
676: if (f != NULL) {
677: int res, size = 3;
678: char chars[4096];
679: sgmlParserCtxtPtr ctxt;
680:
681: /* if (repeat) */
682: size = 4096;
683: res = fread(chars, 1, 4, f);
684: if (res > 0) {
685: ctxt = sgmlCreatePushParserCtxt(NULL, NULL,
686: chars, res, filename, 0);
687: while ((res = fread(chars, 1, size, f)) > 0) {
688: sgmlParseChunk(ctxt, chars, res, 0);
689: }
690: sgmlParseChunk(ctxt, chars, 0, 1);
691: doc = ctxt->myDoc;
692: sgmlFreeParserCtxt(ctxt);
693: }
694: fclose(f);
695: }
696: } else {
697: doc = sgmlParseFile(filename, NULL);
698: }
699: if (doc == NULL) {
1.3 ! veillard 700: xmlGenericError(xmlGenericErrorContext,
! 701: "Could not parse %s\n", filename);
1.1 veillard 702: }
703:
704: /*
705: * test intermediate copy if needed.
706: */
707: if (copy) {
708: tmp = doc;
709: doc = xmlCopyDoc(doc, 1);
710: xmlFreeDoc(tmp);
711: }
712:
713: /*
714: * print it.
715: */
716: if (!noout) {
717: #ifdef LIBXML_DEBUG_ENABLED
718: if (!debug) {
719: if (encoding)
720: htmlSaveFileEnc("-", doc, encoding);
721: else
722: htmlDocDump(stdout, doc);
723: } else
724: xmlDebugDumpDocument(stdout, doc);
725: #else
726: if (encoding)
1.2 veillard 727: htmlSaveFileEnc("-", doc, encoding);
1.1 veillard 728: else
1.2 veillard 729: htmlDocDump(stdout, doc);
1.1 veillard 730: #endif
731: }
732:
733: /*
734: * free it.
735: */
736: xmlFreeDoc(doc);
737: }
738:
739: int main(int argc, char **argv) {
740: int i, count;
741: int files = 0;
742:
743: for (i = 1; i < argc ; i++) {
744: #ifdef LIBXML_DEBUG_ENABLED
745: if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
746: debug++;
747: else
748: #endif
749: if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
750: copy++;
751: else if ((!strcmp(argv[i], "-push")) || (!strcmp(argv[i], "--push")))
752: push++;
753: else if ((!strcmp(argv[i], "-sax")) || (!strcmp(argv[i], "--sax")))
754: sax++;
755: else if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout")))
756: noout++;
757: else if ((!strcmp(argv[i], "-repeat")) ||
758: (!strcmp(argv[i], "--repeat")))
759: repeat++;
760: else if ((!strcmp(argv[i], "-encode")) ||
761: (!strcmp(argv[i], "--encode"))) {
762: i++;
763: encoding = argv[i];
764: }
765: }
766: for (i = 1; i < argc ; i++) {
767: if ((!strcmp(argv[i], "-encode")) ||
768: (!strcmp(argv[i], "--encode"))) {
769: i++;
770: continue;
771: }
772: if (argv[i][0] != '-') {
773: if (repeat) {
774: for (count = 0;count < 100 * repeat;count++) {
775: if (sax)
776: parseSAXFile(argv[i]);
777: else
778: parseAndPrintFile(argv[i]);
779: }
780: } else {
781: if (sax)
782: parseSAXFile(argv[i]);
783: else
784: parseAndPrintFile(argv[i]);
785: }
786: files ++;
787: }
788: }
789: if (files == 0) {
790: printf("Usage : %s [--debug] [--copy] [--copy] SGMLfiles ...\n",
791: argv[0]);
792: printf("\tParse the Docbook files and output the result of the parsing\n");
793: #ifdef LIBXML_DEBUG_ENABLED
794: printf("\t--debug : dump a debug tree of the in-memory document\n");
795: #endif
796: printf("\t--copy : used to test the internal copy implementation\n");
797: printf("\t--sax : debug the sequence of SAX callbacks\n");
798: printf("\t--repeat : parse the file 100 times, for timing\n");
799: printf("\t--noout : do not print the result\n");
800: printf("\t--push : use the push mode parser\n");
801: printf("\t--encode encoding : output in the given encoding\n");
802: }
803: xmlCleanupParser();
804: xmlMemoryDump();
805:
806: return(0);
807: }
808: #else /* !LIBXML_SGML_ENABLED */
809: #include <stdio.h>
810: int main(int argc, char **argv) {
811: printf("%s : SGML support not compiled in\n", argv[0]);
812: return(0);
813: }
814: #endif
Webmaster