1 | /**
|
---|
2 | *** XMLLINT command response program.
|
---|
3 | ***
|
---|
4 | *** See Copyright for the status of this software.
|
---|
5 | ***
|
---|
6 | *** Author: Patrick Monnerat <[email protected]>, DATASPHERE S.A.
|
---|
7 | **/
|
---|
8 |
|
---|
9 | #include <stdio.h>
|
---|
10 | #include <stdlib.h>
|
---|
11 | #include <string.h>
|
---|
12 | #include <qshell.h>
|
---|
13 |
|
---|
14 |
|
---|
15 | /* Variable-length string, with 16-bit length. */
|
---|
16 | typedef struct {
|
---|
17 | short len;
|
---|
18 | char string[5000];
|
---|
19 | } vary2;
|
---|
20 |
|
---|
21 |
|
---|
22 | /* Variable-length string, with 32-bit length. */
|
---|
23 | typedef struct {
|
---|
24 | int len;
|
---|
25 | char string[5000];
|
---|
26 | } vary4;
|
---|
27 |
|
---|
28 |
|
---|
29 | /* Multiple occurrence parameter list. */
|
---|
30 | #define paramlist(itemsize, itemtype) \
|
---|
31 | _Packed struct { \
|
---|
32 | short len; \
|
---|
33 | union { \
|
---|
34 | char _pad[itemsize]; \
|
---|
35 | itemtype param; \
|
---|
36 | } item[1]; \
|
---|
37 | }
|
---|
38 |
|
---|
39 |
|
---|
40 | /* Arguments from CL command. */
|
---|
41 | typedef struct {
|
---|
42 | char * pgm; /* Program name. */
|
---|
43 | vary2 * stmf; /* XML file name or URL. */
|
---|
44 | vary2 * dtd; /* DTD location or public identifier. */
|
---|
45 | char * dtdvalid; /* *DTDURL or *DTDFPI. */
|
---|
46 | vary2 * schema; /* Schema file name or URL. */
|
---|
47 | vary2 * schemakind; /* --schema/--relaxng/--schematron. */
|
---|
48 | vary2 * outstmf; /* Output stream file name. */
|
---|
49 | vary2 * xpath; /* XPath filter. */
|
---|
50 | vary2 * pattern; /* Reader filter pattern. */
|
---|
51 | paramlist(5000 + 2, vary2) * path; /* Path for resources. */
|
---|
52 | vary2 * pretty; /* Pretty-print style. */
|
---|
53 | unsigned long * maxmem; /* Maximum dynamic memory. */
|
---|
54 | vary2 * encoding; /* Output encoding. */
|
---|
55 | paramlist(20 + 2, vary2) * options; /* Other options. */
|
---|
56 | } arguments;
|
---|
57 |
|
---|
58 |
|
---|
59 | /* Definition of QSHELL program. */
|
---|
60 | extern void qshell(vary4 * cmd);
|
---|
61 | #pragma linkage(qshell, OS)
|
---|
62 | #pragma map(qshell, "QSHELL/QZSHQSHC")
|
---|
63 |
|
---|
64 |
|
---|
65 | static void
|
---|
66 | vary4nappend(vary4 * dst, const char * src, size_t len)
|
---|
67 |
|
---|
68 | {
|
---|
69 | if (len > sizeof(dst->string) - dst->len)
|
---|
70 | len = sizeof(dst->string) - dst->len;
|
---|
71 |
|
---|
72 | if (len) {
|
---|
73 | memcpy(dst->string + dst->len, src, len);
|
---|
74 | dst->len += len;
|
---|
75 | }
|
---|
76 | }
|
---|
77 |
|
---|
78 |
|
---|
79 | static void
|
---|
80 | vary4append(vary4 * dst, const char * src)
|
---|
81 |
|
---|
82 | {
|
---|
83 | vary4nappend(dst, src, strlen(src));
|
---|
84 | }
|
---|
85 |
|
---|
86 |
|
---|
87 | static void
|
---|
88 | vary4arg(vary4 * dst, const char * arg)
|
---|
89 |
|
---|
90 | {
|
---|
91 | vary4nappend(dst, " ", 1);
|
---|
92 | vary4append(dst, arg);
|
---|
93 | }
|
---|
94 |
|
---|
95 |
|
---|
96 | static void
|
---|
97 | vary4varg(vary4 * dst, vary2 * arg)
|
---|
98 |
|
---|
99 | {
|
---|
100 | vary4nappend(dst, " ", 1);
|
---|
101 | vary4nappend(dst, arg->string, arg->len);
|
---|
102 | }
|
---|
103 |
|
---|
104 |
|
---|
105 | static void
|
---|
106 | vary4vescape(vary4 * dst, vary2 * arg)
|
---|
107 |
|
---|
108 | {
|
---|
109 | int i;
|
---|
110 |
|
---|
111 | for (i = 0; i < arg->len; i++)
|
---|
112 | if (arg->string[i] == '\'')
|
---|
113 | vary4nappend(dst, "'\"'\"'", 5);
|
---|
114 | else
|
---|
115 | vary4nappend(dst, arg->string + i, 1);
|
---|
116 | }
|
---|
117 |
|
---|
118 |
|
---|
119 | static void
|
---|
120 | vary4vargquote(vary4 * dst, vary2 * arg)
|
---|
121 |
|
---|
122 | {
|
---|
123 | vary4nappend(dst, " '", 2);
|
---|
124 | vary4vescape(dst, arg);
|
---|
125 | vary4nappend(dst, "'", 1);
|
---|
126 | }
|
---|
127 |
|
---|
128 |
|
---|
129 | int
|
---|
130 | main(int argsc, arguments * args)
|
---|
131 |
|
---|
132 | {
|
---|
133 | vary4 cmd;
|
---|
134 | int i;
|
---|
135 | char textbuf[20];
|
---|
136 | char * lang;
|
---|
137 |
|
---|
138 | /* find length of library name. */
|
---|
139 | for (i = 0; i < 10 && args->pgm[i] && args->pgm[i] != '/'; i++)
|
---|
140 | ;
|
---|
141 |
|
---|
142 | /* Store program name in command buffer. */
|
---|
143 | cmd.len = 0;
|
---|
144 | vary4append(&cmd, "/QSYS.LIB/");
|
---|
145 | vary4nappend(&cmd, args->pgm, i);
|
---|
146 | vary4append(&cmd, ".LIB/XMLLINT.PGM");
|
---|
147 |
|
---|
148 | /* Map command arguments to standard xmllint argument vector. */
|
---|
149 |
|
---|
150 | if (args->dtd && args->dtd->len) {
|
---|
151 | if (args->dtdvalid && args->dtdvalid[4] == 'F')
|
---|
152 | vary4arg(&cmd, "--dtdvalidfpi");
|
---|
153 | else
|
---|
154 | vary4arg(&cmd, "--dtdvalid");
|
---|
155 |
|
---|
156 | vary4vargquote(&cmd, args->dtd);
|
---|
157 | }
|
---|
158 |
|
---|
159 | if (args->schema && args->schema->len) {
|
---|
160 | vary4varg(&cmd, args->schemakind);
|
---|
161 | vary4vargquote(&cmd, args->schema);
|
---|
162 | }
|
---|
163 |
|
---|
164 | if (args->outstmf && args->outstmf->len) {
|
---|
165 | vary4arg(&cmd, "--output");
|
---|
166 | vary4vargquote(&cmd, args->outstmf);
|
---|
167 |
|
---|
168 | if (args->encoding && args->encoding->len) {
|
---|
169 | vary4arg(&cmd, "--encoding");
|
---|
170 | vary4vargquote(&cmd, args->encoding);
|
---|
171 | }
|
---|
172 | }
|
---|
173 |
|
---|
174 | if (args->xpath && args->xpath->len) {
|
---|
175 | vary4arg(&cmd, "--xpath");
|
---|
176 | vary4vargquote(&cmd, args->xpath);
|
---|
177 | }
|
---|
178 |
|
---|
179 | if (args->pattern && args->pattern->len) {
|
---|
180 | vary4arg(&cmd, "--pattern");
|
---|
181 | vary4vargquote(&cmd, args->pattern);
|
---|
182 | }
|
---|
183 |
|
---|
184 | if (args->path && args->path->len) {
|
---|
185 | vary4arg(&cmd, "--path '");
|
---|
186 | vary4vescape(&cmd, &args->path->item[0].param);
|
---|
187 | for (i = 1; i < args->path->len; i++) {
|
---|
188 | vary4nappend(&cmd, ":", 1);
|
---|
189 | vary4vescape(&cmd, &args->path->item[i].param);
|
---|
190 | }
|
---|
191 | vary4nappend(&cmd, "'", 1);
|
---|
192 | }
|
---|
193 |
|
---|
194 | if (args->pretty && args->pretty->len &&
|
---|
195 | args->pretty->string[0] != '0') {
|
---|
196 | vary4arg(&cmd, "--pretty");
|
---|
197 | vary4varg(&cmd, args->pretty);
|
---|
198 | }
|
---|
199 |
|
---|
200 | if (args->maxmem && *args->maxmem) {
|
---|
201 | snprintf(textbuf, sizeof textbuf, "%lu", *args->maxmem);
|
---|
202 | vary4arg(&cmd, "--maxmem");
|
---|
203 | vary4arg(&cmd, textbuf);
|
---|
204 | }
|
---|
205 |
|
---|
206 | for (i = 0; i < args->options->len; i++)
|
---|
207 | vary4varg(&cmd, &args->options->item[i].param);
|
---|
208 |
|
---|
209 | vary4vargquote(&cmd, args->stmf);
|
---|
210 |
|
---|
211 | /* Execute the shell command. */
|
---|
212 | qshell(&cmd);
|
---|
213 |
|
---|
214 | /* Terminate. */
|
---|
215 | exit(0);
|
---|
216 | }
|
---|