xref: /openbsd-src/lib/libexpat/examples/elements.c (revision 751a8f41a926cac5cc0587722fe35d38520b2eb7)
11a3ddf8cSespie /* This is simple demonstration of how to use expat. This program
21a3ddf8cSespie    reads an XML document from standard input and writes a line with
31a3ddf8cSespie    the name of each element to standard output indenting child
41a3ddf8cSespie    elements by one tab stop more than their parent element.
57d36914fSalek    It must be used with Expat compiled for UTF-8 output.
62e724bc9Sbluhm                             __  __            _
72e724bc9Sbluhm                          ___\ \/ /_ __   __ _| |_
82e724bc9Sbluhm                         / _ \\  /| '_ \ / _` | __|
92e724bc9Sbluhm                        |  __//  \| |_) | (_| | |_
102e724bc9Sbluhm                         \___/_/\_\ .__/ \__,_|\__|
112e724bc9Sbluhm                                  |_| XML parser
122e724bc9Sbluhm 
132e724bc9Sbluhm    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
1408819b41Sbluhm    Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
1508819b41Sbluhm    Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
16253fd6bfSbluhm    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
17*751a8f41Sbluhm    Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
1808819b41Sbluhm    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
1908819b41Sbluhm    Copyright (c) 2019      Zhongyuan Zhou <zhouzhongyuan@huawei.com>
202e724bc9Sbluhm    Licensed under the MIT license:
212e724bc9Sbluhm 
222e724bc9Sbluhm    Permission is  hereby granted,  free of charge,  to any  person obtaining
232e724bc9Sbluhm    a  copy  of  this  software   and  associated  documentation  files  (the
242e724bc9Sbluhm    "Software"),  to  deal in  the  Software  without restriction,  including
252e724bc9Sbluhm    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
262e724bc9Sbluhm    distribute, sublicense, and/or sell copies of the Software, and to permit
272e724bc9Sbluhm    persons  to whom  the Software  is  furnished to  do so,  subject to  the
282e724bc9Sbluhm    following conditions:
292e724bc9Sbluhm 
302e724bc9Sbluhm    The above copyright  notice and this permission notice  shall be included
312e724bc9Sbluhm    in all copies or substantial portions of the Software.
322e724bc9Sbluhm 
332e724bc9Sbluhm    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
342e724bc9Sbluhm    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
352e724bc9Sbluhm    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
362e724bc9Sbluhm    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
372e724bc9Sbluhm    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
382e724bc9Sbluhm    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
392e724bc9Sbluhm    USE OR OTHER DEALINGS IN THE SOFTWARE.
401a3ddf8cSespie */
411a3ddf8cSespie 
421a3ddf8cSespie #include <stdio.h>
432feb5d2aSbluhm #include <expat.h>
44b26ab0f8Smatthieu 
457d36914fSalek #ifdef XML_LARGE_SIZE
467d36914fSalek #  define XML_FMT_INT_MOD "ll"
477d36914fSalek #else
487d36914fSalek #  define XML_FMT_INT_MOD "l"
497d36914fSalek #endif
507d36914fSalek 
519b8e2351Sbluhm #ifdef XML_UNICODE_WCHAR_T
529b8e2351Sbluhm #  define XML_FMT_STR "ls"
539b8e2351Sbluhm #else
549b8e2351Sbluhm #  define XML_FMT_STR "s"
559b8e2351Sbluhm #endif
569b8e2351Sbluhm 
577d36914fSalek static void XMLCALL
startElement(void * userData,const XML_Char * name,const XML_Char ** atts)5828ce3119Sbluhm startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
591a3ddf8cSespie   int i;
60*751a8f41Sbluhm   int *const depthPtr = (int *)userData;
612feb5d2aSbluhm   (void)atts;
622feb5d2aSbluhm 
631a3ddf8cSespie   for (i = 0; i < *depthPtr; i++)
641a3ddf8cSespie     putchar('\t');
659b8e2351Sbluhm   printf("%" XML_FMT_STR "\n", name);
661a3ddf8cSespie   *depthPtr += 1;
671a3ddf8cSespie }
681a3ddf8cSespie 
697d36914fSalek static void XMLCALL
endElement(void * userData,const XML_Char * name)7028ce3119Sbluhm endElement(void *userData, const XML_Char *name) {
71*751a8f41Sbluhm   int *const depthPtr = (int *)userData;
722feb5d2aSbluhm   (void)name;
732feb5d2aSbluhm 
741a3ddf8cSespie   *depthPtr -= 1;
751a3ddf8cSespie }
761a3ddf8cSespie 
771a3ddf8cSespie int
main(void)78*751a8f41Sbluhm main(void) {
791a3ddf8cSespie   XML_Parser parser = XML_ParserCreate(NULL);
801a3ddf8cSespie   int done;
811a3ddf8cSespie   int depth = 0;
82*751a8f41Sbluhm 
83*751a8f41Sbluhm   if (! parser) {
84*751a8f41Sbluhm     fprintf(stderr, "Couldn't allocate memory for parser\n");
85*751a8f41Sbluhm     return 1;
86*751a8f41Sbluhm   }
872feb5d2aSbluhm 
881a3ddf8cSespie   XML_SetUserData(parser, &depth);
891a3ddf8cSespie   XML_SetElementHandler(parser, startElement, endElement);
90*751a8f41Sbluhm 
911a3ddf8cSespie   do {
92*751a8f41Sbluhm     void *const buf = XML_GetBuffer(parser, BUFSIZ);
93*751a8f41Sbluhm     if (! buf) {
94*751a8f41Sbluhm       fprintf(stderr, "Couldn't allocate memory for buffer\n");
95*751a8f41Sbluhm       XML_ParserFree(parser);
96*751a8f41Sbluhm       return 1;
97*751a8f41Sbluhm     }
98*751a8f41Sbluhm 
99*751a8f41Sbluhm     const size_t len = fread(buf, 1, BUFSIZ, stdin);
100*751a8f41Sbluhm 
101*751a8f41Sbluhm     if (ferror(stdin)) {
102*751a8f41Sbluhm       fprintf(stderr, "Read error\n");
103*751a8f41Sbluhm       XML_ParserFree(parser);
104*751a8f41Sbluhm       return 1;
105*751a8f41Sbluhm     }
106*751a8f41Sbluhm 
107*751a8f41Sbluhm     done = feof(stdin);
108*751a8f41Sbluhm 
109*751a8f41Sbluhm     if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
110*751a8f41Sbluhm       fprintf(stderr,
111*751a8f41Sbluhm               "Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
112*751a8f41Sbluhm               XML_GetCurrentLineNumber(parser),
113*751a8f41Sbluhm               XML_ErrorString(XML_GetErrorCode(parser)));
11428ce3119Sbluhm       XML_ParserFree(parser);
1151a3ddf8cSespie       return 1;
1161a3ddf8cSespie     }
1171a3ddf8cSespie   } while (! done);
118*751a8f41Sbluhm 
1191a3ddf8cSespie   XML_ParserFree(parser);
1201a3ddf8cSespie   return 0;
1211a3ddf8cSespie }
122