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