xref: /freebsd/contrib/expat/examples/elements.c (revision dc58b3fca5e7a7bb1e9aa640667944d0fe0601cd)
15bb6a25fSPoul-Henning Kamp /* This is simple demonstration of how to use expat. This program
25bb6a25fSPoul-Henning Kamp    reads an XML document from standard input and writes a line with
35bb6a25fSPoul-Henning Kamp    the name of each element to standard output indenting child
45bb6a25fSPoul-Henning Kamp    elements by one tab stop more than their parent element.
5220ed979SColeman Kane    It must be used with Expat compiled for UTF-8 output.
60a48773fSEric van Gyzen                             __  __            _
70a48773fSEric van Gyzen                          ___\ \/ /_ __   __ _| |_
80a48773fSEric van Gyzen                         / _ \\  /| '_ \ / _` | __|
90a48773fSEric van Gyzen                        |  __//  \| |_) | (_| | |_
100a48773fSEric van Gyzen                         \___/_/\_\ .__/ \__,_|\__|
110a48773fSEric van Gyzen                                  |_| XML parser
120a48773fSEric van Gyzen 
130a48773fSEric van Gyzen    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
14cc68614dSXin LI    Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
15cc68614dSXin LI    Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
16ac69e5d4SEric van Gyzen    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
17*dc58b3fcSXin LI    Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
18cc68614dSXin LI    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
19cc68614dSXin LI    Copyright (c) 2019      Zhongyuan Zhou <zhouzhongyuan@huawei.com>
200a48773fSEric van Gyzen    Licensed under the MIT license:
210a48773fSEric van Gyzen 
220a48773fSEric van Gyzen    Permission is  hereby granted,  free of charge,  to any  person obtaining
230a48773fSEric van Gyzen    a  copy  of  this  software   and  associated  documentation  files  (the
240a48773fSEric van Gyzen    "Software"),  to  deal in  the  Software  without restriction,  including
250a48773fSEric van Gyzen    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
260a48773fSEric van Gyzen    distribute, sublicense, and/or sell copies of the Software, and to permit
270a48773fSEric van Gyzen    persons  to whom  the Software  is  furnished to  do so,  subject to  the
280a48773fSEric van Gyzen    following conditions:
290a48773fSEric van Gyzen 
300a48773fSEric van Gyzen    The above copyright  notice and this permission notice  shall be included
310a48773fSEric van Gyzen    in all copies or substantial portions of the Software.
320a48773fSEric van Gyzen 
330a48773fSEric van Gyzen    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
340a48773fSEric van Gyzen    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
350a48773fSEric van Gyzen    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
360a48773fSEric van Gyzen    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
370a48773fSEric van Gyzen    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
380a48773fSEric van Gyzen    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
390a48773fSEric van Gyzen    USE OR OTHER DEALINGS IN THE SOFTWARE.
405bb6a25fSPoul-Henning Kamp */
415bb6a25fSPoul-Henning Kamp 
425bb6a25fSPoul-Henning Kamp #include <stdio.h>
430a48773fSEric van Gyzen #include <expat.h>
44220ed979SColeman Kane 
45220ed979SColeman Kane #ifdef XML_LARGE_SIZE
46220ed979SColeman Kane #  define XML_FMT_INT_MOD "ll"
47220ed979SColeman Kane #else
48220ed979SColeman Kane #  define XML_FMT_INT_MOD "l"
49220ed979SColeman Kane #endif
50220ed979SColeman Kane 
510a48773fSEric van Gyzen #ifdef XML_UNICODE_WCHAR_T
520a48773fSEric van Gyzen #  define XML_FMT_STR "ls"
530a48773fSEric van Gyzen #else
540a48773fSEric van Gyzen #  define XML_FMT_STR "s"
550a48773fSEric van Gyzen #endif
560a48773fSEric van Gyzen 
57220ed979SColeman Kane static void XMLCALL
startElement(void * userData,const XML_Char * name,const XML_Char ** atts)586b2c1e49SXin LI startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
595bb6a25fSPoul-Henning Kamp   int i;
60*dc58b3fcSXin LI   int *const depthPtr = (int *)userData;
61be8aff81SXin LI   (void)atts;
62be8aff81SXin LI 
635bb6a25fSPoul-Henning Kamp   for (i = 0; i < *depthPtr; i++)
645bb6a25fSPoul-Henning Kamp     putchar('\t');
650a48773fSEric van Gyzen   printf("%" XML_FMT_STR "\n", name);
665bb6a25fSPoul-Henning Kamp   *depthPtr += 1;
675bb6a25fSPoul-Henning Kamp }
685bb6a25fSPoul-Henning Kamp 
69220ed979SColeman Kane static void XMLCALL
endElement(void * userData,const XML_Char * name)706b2c1e49SXin LI endElement(void *userData, const XML_Char *name) {
71*dc58b3fcSXin LI   int *const depthPtr = (int *)userData;
72be8aff81SXin LI   (void)name;
73be8aff81SXin LI 
745bb6a25fSPoul-Henning Kamp   *depthPtr -= 1;
755bb6a25fSPoul-Henning Kamp }
765bb6a25fSPoul-Henning Kamp 
775bb6a25fSPoul-Henning Kamp int
main(void)78*dc58b3fcSXin LI main(void) {
795bb6a25fSPoul-Henning Kamp   XML_Parser parser = XML_ParserCreate(NULL);
805bb6a25fSPoul-Henning Kamp   int done;
815bb6a25fSPoul-Henning Kamp   int depth = 0;
82*dc58b3fcSXin LI 
83*dc58b3fcSXin LI   if (! parser) {
84*dc58b3fcSXin LI     fprintf(stderr, "Couldn't allocate memory for parser\n");
85*dc58b3fcSXin LI     return 1;
86*dc58b3fcSXin LI   }
87be8aff81SXin LI 
885bb6a25fSPoul-Henning Kamp   XML_SetUserData(parser, &depth);
895bb6a25fSPoul-Henning Kamp   XML_SetElementHandler(parser, startElement, endElement);
90*dc58b3fcSXin LI 
915bb6a25fSPoul-Henning Kamp   do {
92*dc58b3fcSXin LI     void *const buf = XML_GetBuffer(parser, BUFSIZ);
93*dc58b3fcSXin LI     if (! buf) {
94*dc58b3fcSXin LI       fprintf(stderr, "Couldn't allocate memory for buffer\n");
95*dc58b3fcSXin LI       XML_ParserFree(parser);
96*dc58b3fcSXin LI       return 1;
97*dc58b3fcSXin LI     }
98*dc58b3fcSXin LI 
99*dc58b3fcSXin LI     const size_t len = fread(buf, 1, BUFSIZ, stdin);
100*dc58b3fcSXin LI 
101*dc58b3fcSXin LI     if (ferror(stdin)) {
102*dc58b3fcSXin LI       fprintf(stderr, "Read error\n");
103*dc58b3fcSXin LI       XML_ParserFree(parser);
104*dc58b3fcSXin LI       return 1;
105*dc58b3fcSXin LI     }
106*dc58b3fcSXin LI 
107*dc58b3fcSXin LI     done = feof(stdin);
108*dc58b3fcSXin LI 
109*dc58b3fcSXin LI     if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
110*dc58b3fcSXin LI       fprintf(stderr,
111*dc58b3fcSXin LI               "Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
112*dc58b3fcSXin LI               XML_GetCurrentLineNumber(parser),
113*dc58b3fcSXin LI               XML_ErrorString(XML_GetErrorCode(parser)));
1146b2c1e49SXin LI       XML_ParserFree(parser);
1155bb6a25fSPoul-Henning Kamp       return 1;
1165bb6a25fSPoul-Henning Kamp     }
1175bb6a25fSPoul-Henning Kamp   } while (! done);
118*dc58b3fcSXin LI 
1195bb6a25fSPoul-Henning Kamp   XML_ParserFree(parser);
1205bb6a25fSPoul-Henning Kamp   return 0;
1215bb6a25fSPoul-Henning Kamp }
122