xref: /freebsd/contrib/expat/examples/outline.c (revision ac69e5d471014c95070cd6294db315089a62725b)
10a48773fSEric van Gyzen /* Read an XML document from standard input and print an element
20a48773fSEric van Gyzen    outline on standard output.
30a48773fSEric van Gyzen    Must be used with Expat compiled for UTF-8 output.
40a48773fSEric van Gyzen                             __  __            _
50a48773fSEric van Gyzen                          ___\ \/ /_ __   __ _| |_
60a48773fSEric van Gyzen                         / _ \\  /| '_ \ / _` | __|
70a48773fSEric van Gyzen                        |  __//  \| |_) | (_| | |_
80a48773fSEric van Gyzen                         \___/_/\_\ .__/ \__,_|\__|
90a48773fSEric van Gyzen                                  |_| XML parser
105bb6a25fSPoul-Henning Kamp 
11cc68614dSXin LI    Copyright (c) 2000      Clark Cooper <coopercc@users.sourceforge.net>
12cc68614dSXin LI    Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
13*ac69e5d4SEric van Gyzen    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
14cc68614dSXin LI    Copyright (c) 2005-2006 Karl Waclawek <karl@waclawek.net>
15cc68614dSXin LI    Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
16cc68614dSXin LI    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
170a48773fSEric van Gyzen    Licensed under the MIT license:
180a48773fSEric van Gyzen 
190a48773fSEric van Gyzen    Permission is  hereby granted,  free of charge,  to any  person obtaining
200a48773fSEric van Gyzen    a  copy  of  this  software   and  associated  documentation  files  (the
210a48773fSEric van Gyzen    "Software"),  to  deal in  the  Software  without restriction,  including
220a48773fSEric van Gyzen    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
230a48773fSEric van Gyzen    distribute, sublicense, and/or sell copies of the Software, and to permit
240a48773fSEric van Gyzen    persons  to whom  the Software  is  furnished to  do so,  subject to  the
250a48773fSEric van Gyzen    following conditions:
260a48773fSEric van Gyzen 
270a48773fSEric van Gyzen    The above copyright  notice and this permission notice  shall be included
280a48773fSEric van Gyzen    in all copies or substantial portions of the Software.
290a48773fSEric van Gyzen 
300a48773fSEric van Gyzen    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
310a48773fSEric van Gyzen    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
320a48773fSEric van Gyzen    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
330a48773fSEric van Gyzen    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
340a48773fSEric van Gyzen    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
350a48773fSEric van Gyzen    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
360a48773fSEric van Gyzen    USE OR OTHER DEALINGS IN THE SOFTWARE.
370a48773fSEric van Gyzen */
385bb6a25fSPoul-Henning Kamp 
395bb6a25fSPoul-Henning Kamp #include <stdio.h>
405bb6a25fSPoul-Henning Kamp #include <expat.h>
415bb6a25fSPoul-Henning Kamp 
42220ed979SColeman Kane #ifdef XML_LARGE_SIZE
43220ed979SColeman Kane #  define XML_FMT_INT_MOD "ll"
44220ed979SColeman Kane #else
45220ed979SColeman Kane #  define XML_FMT_INT_MOD "l"
46220ed979SColeman Kane #endif
47220ed979SColeman Kane 
480a48773fSEric van Gyzen #ifdef XML_UNICODE_WCHAR_T
490a48773fSEric van Gyzen #  define XML_FMT_STR "ls"
500a48773fSEric van Gyzen #else
510a48773fSEric van Gyzen #  define XML_FMT_STR "s"
520a48773fSEric van Gyzen #endif
530a48773fSEric van Gyzen 
545bb6a25fSPoul-Henning Kamp #define BUFFSIZE 8192
555bb6a25fSPoul-Henning Kamp 
565bb6a25fSPoul-Henning Kamp char Buff[BUFFSIZE];
575bb6a25fSPoul-Henning Kamp 
585bb6a25fSPoul-Henning Kamp int Depth;
595bb6a25fSPoul-Henning Kamp 
60220ed979SColeman Kane static void XMLCALL
616b2c1e49SXin LI start(void *data, const XML_Char *el, const XML_Char **attr) {
625bb6a25fSPoul-Henning Kamp   int i;
63be8aff81SXin LI   (void)data;
645bb6a25fSPoul-Henning Kamp 
655bb6a25fSPoul-Henning Kamp   for (i = 0; i < Depth; i++)
665bb6a25fSPoul-Henning Kamp     printf("  ");
675bb6a25fSPoul-Henning Kamp 
680a48773fSEric van Gyzen   printf("%" XML_FMT_STR, el);
695bb6a25fSPoul-Henning Kamp 
705bb6a25fSPoul-Henning Kamp   for (i = 0; attr[i]; i += 2) {
710a48773fSEric van Gyzen     printf(" %" XML_FMT_STR "='%" XML_FMT_STR "'", attr[i], attr[i + 1]);
725bb6a25fSPoul-Henning Kamp   }
735bb6a25fSPoul-Henning Kamp 
745bb6a25fSPoul-Henning Kamp   printf("\n");
755bb6a25fSPoul-Henning Kamp   Depth++;
765bb6a25fSPoul-Henning Kamp }
775bb6a25fSPoul-Henning Kamp 
78220ed979SColeman Kane static void XMLCALL
796b2c1e49SXin LI end(void *data, const XML_Char *el) {
80be8aff81SXin LI   (void)data;
81be8aff81SXin LI   (void)el;
82be8aff81SXin LI 
835bb6a25fSPoul-Henning Kamp   Depth--;
845bb6a25fSPoul-Henning Kamp }
855bb6a25fSPoul-Henning Kamp 
865bb6a25fSPoul-Henning Kamp int
876b2c1e49SXin LI main(int argc, char *argv[]) {
885bb6a25fSPoul-Henning Kamp   XML_Parser p = XML_ParserCreate(NULL);
89be8aff81SXin LI   (void)argc;
90be8aff81SXin LI   (void)argv;
91be8aff81SXin LI 
925bb6a25fSPoul-Henning Kamp   if (! p) {
935bb6a25fSPoul-Henning Kamp     fprintf(stderr, "Couldn't allocate memory for parser\n");
945bb6a25fSPoul-Henning Kamp     exit(-1);
955bb6a25fSPoul-Henning Kamp   }
965bb6a25fSPoul-Henning Kamp 
975bb6a25fSPoul-Henning Kamp   XML_SetElementHandler(p, start, end);
985bb6a25fSPoul-Henning Kamp 
995bb6a25fSPoul-Henning Kamp   for (;;) {
1005bb6a25fSPoul-Henning Kamp     int done;
1015bb6a25fSPoul-Henning Kamp     int len;
1025bb6a25fSPoul-Henning Kamp 
103220ed979SColeman Kane     len = (int)fread(Buff, 1, BUFFSIZE, stdin);
1045bb6a25fSPoul-Henning Kamp     if (ferror(stdin)) {
1055bb6a25fSPoul-Henning Kamp       fprintf(stderr, "Read error\n");
1065bb6a25fSPoul-Henning Kamp       exit(-1);
1075bb6a25fSPoul-Henning Kamp     }
1085bb6a25fSPoul-Henning Kamp     done = feof(stdin);
1095bb6a25fSPoul-Henning Kamp 
1105bb6a25fSPoul-Henning Kamp     if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
1110a48773fSEric van Gyzen       fprintf(stderr,
1120a48773fSEric van Gyzen               "Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
1135bb6a25fSPoul-Henning Kamp               XML_GetCurrentLineNumber(p),
1145bb6a25fSPoul-Henning Kamp               XML_ErrorString(XML_GetErrorCode(p)));
1155bb6a25fSPoul-Henning Kamp       exit(-1);
1165bb6a25fSPoul-Henning Kamp     }
1175bb6a25fSPoul-Henning Kamp 
1185bb6a25fSPoul-Henning Kamp     if (done)
1195bb6a25fSPoul-Henning Kamp       break;
1205bb6a25fSPoul-Henning Kamp   }
121220ed979SColeman Kane   XML_ParserFree(p);
1225bb6a25fSPoul-Henning Kamp   return 0;
1235bb6a25fSPoul-Henning Kamp }
124