aboutsummaryrefslogtreecommitdiff
path: root/examples/cxx/parser/minimal/driver.cxx
blob: 07394f615ec005608427e7d68ec44c25b968d129 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// file      : examples/cxx/parser/minimal/driver.cxx
// copyright : not copyrighted - public domain

#include <stdio.h>

#include "people-pskel.hxx" // Get the configuration macros (XSDE_*).

#if defined(XSDE_REUSE_STYLE_MIXIN)
#  include "people-pimpl-mixin.hxx"
#elif defined(XSDE_REUSE_STYLE_TIEIN)
#  include "people-pimpl-tiein.hxx"
#else
#  error this example requires mixin or tiein parser reuse support
#endif

int
main (int argc, char* argv[])
{
  const char* input;

  if (argc < 2)
  {
    input = "STDIN";
    fprintf (stderr, "XML file not specified, reading from STDIN\n");
  }
  else
    input = argv[1];

  // Construct the parser.
  //
  xml_schema::unsigned_short_pimpl unsigned_short_p;
  xml_schema::string_pimpl string_p;

  gender_pimpl gender_p;
  person_pimpl person_p;
  people_pimpl people_p;

  person_p.parsers (string_p, string_p, gender_p, unsigned_short_p);
  people_p.parsers (person_p);

  // Open the file or use STDIN.
  //
  FILE* f = argc > 1 ? fopen (argv[1], "rb") : stdin;

  if (f == 0)
  {
    fprintf (stderr, "%s: unable to open\n", input);
    return 1;
  }

  // Parse.
  //
  typedef xml_schema::parser_error error;
  error e;
  bool io_error = false;

  do
  {
    xml_schema::document_pimpl doc_p (people_p, "people");

    if (e = doc_p._error ())
      break;

    people_p.pre ();

    if (e = people_p._error ())
      break;

    char buf[4096];

    do
    {
      size_t s = fread (buf, 1, sizeof (buf), f);

      if (s != sizeof (buf) && ferror (f))
      {
        io_error = true;
        break;
      }

      doc_p.parse (buf, s, feof (f) != 0);
      e = doc_p._error ();

    } while (!e && !feof (f));

    if (io_error || e)
      break;

    people_p.post_people ();

    e = people_p._error ();

  } while (false);

  if (argc > 1)
    fclose (f);

  // Handle errors.
  //

  if (io_error)
  {
    fprintf (stderr, "%s: read failure\n", input);
    return 1;
  }

  if (e)
  {
    switch (e.type ())
    {
    case error::sys:
      {
        fprintf (stderr, "%s: %s\n", input, e.sys_text ());
        break;
      }
    case error::xml:
      {
        fprintf (stderr, "%s:%lu:%lu: %s\n",
                 input, e.line (), e.column (), e.xml_text ());
        break;
      }
#ifdef XSDE_PARSER_VALIDATION
    case error::schema:
      {
        fprintf (stderr, "%s:%lu:%lu: %s\n",
                 input, e.line (), e.column (), e.schema_text ());
        break;
      }
#endif
    case error::app:
      {
        fprintf (stderr, "%s:%lu:%lu: application error %d\n",
                 input, e.line (), e.column (), e.app_code ());
        break;
      }
    default:
      break;
    }

    return 1;
  }

  return 0;
}