1355604Sdelphij/* Read an XML document from standard input and print an element
2355604Sdelphij   outline on standard output.
3355604Sdelphij   Must be used with Expat compiled for UTF-8 output.
4355604Sdelphij                            __  __            _
5355604Sdelphij                         ___\ \/ /_ __   __ _| |_
6355604Sdelphij                        / _ \\  /| '_ \ / _` | __|
7355604Sdelphij                       |  __//  \| |_) | (_| | |_
8355604Sdelphij                        \___/_/\_\ .__/ \__,_|\__|
9355604Sdelphij                                 |_| XML parser
10104349Sphk
11355604Sdelphij   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
12355604Sdelphij   Copyright (c) 2000-2017 Expat development team
13355604Sdelphij   Licensed under the MIT license:
14104349Sphk
15355604Sdelphij   Permission is  hereby granted,  free of charge,  to any  person obtaining
16355604Sdelphij   a  copy  of  this  software   and  associated  documentation  files  (the
17355604Sdelphij   "Software"),  to  deal in  the  Software  without restriction,  including
18355604Sdelphij   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
19355604Sdelphij   distribute, sublicense, and/or sell copies of the Software, and to permit
20355604Sdelphij   persons  to whom  the Software  is  furnished to  do so,  subject to  the
21355604Sdelphij   following conditions:
22355604Sdelphij
23355604Sdelphij   The above copyright  notice and this permission notice  shall be included
24355604Sdelphij   in all copies or substantial portions of the Software.
25355604Sdelphij
26355604Sdelphij   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
27355604Sdelphij   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
28355604Sdelphij   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
29355604Sdelphij   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
30355604Sdelphij   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
31355604Sdelphij   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
32355604Sdelphij   USE OR OTHER DEALINGS IN THE SOFTWARE.
33355604Sdelphij*/
34355604Sdelphij
35104349Sphk#include <stdio.h>
36104349Sphk#include <expat.h>
37104349Sphk
38178848Scokane#ifdef XML_LARGE_SIZE
39355604Sdelphij#  define XML_FMT_INT_MOD "ll"
40178848Scokane#else
41355604Sdelphij#  define XML_FMT_INT_MOD "l"
42178848Scokane#endif
43355604Sdelphij
44355604Sdelphij#ifdef XML_UNICODE_WCHAR_T
45355604Sdelphij#  define XML_FMT_STR "ls"
46178848Scokane#else
47355604Sdelphij#  define XML_FMT_STR "s"
48178848Scokane#endif
49178848Scokane
50355604Sdelphij#define BUFFSIZE 8192
51104349Sphk
52104349Sphkchar Buff[BUFFSIZE];
53104349Sphk
54104349Sphkint Depth;
55104349Sphk
56178848Scokanestatic void XMLCALL
57355604Sdelphijstart(void *data, const XML_Char *el, const XML_Char **attr) {
58104349Sphk  int i;
59302305Sdelphij  (void)data;
60104349Sphk
61104349Sphk  for (i = 0; i < Depth; i++)
62104349Sphk    printf("  ");
63104349Sphk
64355604Sdelphij  printf("%" XML_FMT_STR, el);
65104349Sphk
66104349Sphk  for (i = 0; attr[i]; i += 2) {
67355604Sdelphij    printf(" %" XML_FMT_STR "='%" XML_FMT_STR "'", attr[i], attr[i + 1]);
68104349Sphk  }
69104349Sphk
70104349Sphk  printf("\n");
71104349Sphk  Depth++;
72104349Sphk}
73104349Sphk
74178848Scokanestatic void XMLCALL
75355604Sdelphijend(void *data, const XML_Char *el) {
76302305Sdelphij  (void)data;
77302305Sdelphij  (void)el;
78302305Sdelphij
79104349Sphk  Depth--;
80104349Sphk}
81104349Sphk
82104349Sphkint
83355604Sdelphijmain(int argc, char *argv[]) {
84104349Sphk  XML_Parser p = XML_ParserCreate(NULL);
85302305Sdelphij  (void)argc;
86302305Sdelphij  (void)argv;
87302305Sdelphij
88104349Sphk  if (! p) {
89104349Sphk    fprintf(stderr, "Couldn't allocate memory for parser\n");
90104349Sphk    exit(-1);
91104349Sphk  }
92104349Sphk
93104349Sphk  XML_SetElementHandler(p, start, end);
94104349Sphk
95104349Sphk  for (;;) {
96104349Sphk    int done;
97104349Sphk    int len;
98104349Sphk
99178848Scokane    len = (int)fread(Buff, 1, BUFFSIZE, stdin);
100104349Sphk    if (ferror(stdin)) {
101104349Sphk      fprintf(stderr, "Read error\n");
102104349Sphk      exit(-1);
103104349Sphk    }
104104349Sphk    done = feof(stdin);
105104349Sphk
106104349Sphk    if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
107355604Sdelphij      fprintf(stderr,
108355604Sdelphij              "Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
109104349Sphk              XML_GetCurrentLineNumber(p),
110104349Sphk              XML_ErrorString(XML_GetErrorCode(p)));
111104349Sphk      exit(-1);
112104349Sphk    }
113104349Sphk
114104349Sphk    if (done)
115104349Sphk      break;
116104349Sphk  }
117178848Scokane  XML_ParserFree(p);
118104349Sphk  return 0;
119104349Sphk}
120