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