Hash :
26db5e7a
Author :
Date :
2015-04-17T17:21:14
os400: implement CL command XMLLINT.
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
/**
*** XMLLINT command response program.
***
*** See Copyright for the status of this software.
***
*** Author: Patrick Monnerat <pm@datasphere.ch>, DATASPHERE S.A.
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <qshell.h>
/* Variable-length string, with 16-bit length. */
typedef struct {
short len;
char string[5000];
} vary2;
/* Variable-length string, with 32-bit length. */
typedef struct {
int len;
char string[5000];
} vary4;
/* Multiple occurrence parameter list. */
#define paramlist(itemsize, itemtype) \
_Packed struct { \
short len; \
union { \
char _pad[itemsize]; \
itemtype param; \
} item[1]; \
}
/* Arguments from CL command. */
typedef struct {
char * pgm; /* Program name. */
vary2 * stmf; /* XML file name or URL. */
vary2 * dtd; /* DTD location or public identifier. */
char * dtdvalid; /* *DTDURL or *DTDFPI. */
vary2 * schema; /* Schema file name or URL. */
vary2 * schemakind; /* --schema/--relaxng/--schematron. */
vary2 * outstmf; /* Output stream file name. */
vary2 * xpath; /* XPath filter. */
vary2 * pattern; /* Reader filter pattern. */
paramlist(5000 + 2, vary2) * path; /* Path for resources. */
vary2 * pretty; /* Pretty-print style. */
unsigned long * maxmem; /* Maximum dynamic memory. */
vary2 * encoding; /* Output encoding. */
paramlist(20 + 2, vary2) * options; /* Other options. */
} arguments;
/* Definition of QSHELL program. */
extern void qshell(vary4 * cmd);
#pragma linkage(qshell, OS)
#pragma map(qshell, "QSHELL/QZSHQSHC")
static void
vary4nappend(vary4 * dst, const char * src, size_t len)
{
if (len > sizeof(dst->string) - dst->len)
len = sizeof(dst->string) - dst->len;
if (len) {
memcpy(dst->string + dst->len, src, len);
dst->len += len;
}
}
static void
vary4append(vary4 * dst, const char * src)
{
vary4nappend(dst, src, strlen(src));
}
static void
vary4arg(vary4 * dst, const char * arg)
{
vary4nappend(dst, " ", 1);
vary4append(dst, arg);
}
static void
vary4varg(vary4 * dst, vary2 * arg)
{
vary4nappend(dst, " ", 1);
vary4nappend(dst, arg->string, arg->len);
}
static void
vary4vescape(vary4 * dst, vary2 * arg)
{
int i;
for (i = 0; i < arg->len; i++)
if (arg->string[i] == '\'')
vary4nappend(dst, "'\"'\"'", 5);
else
vary4nappend(dst, arg->string + i, 1);
}
static void
vary4vargquote(vary4 * dst, vary2 * arg)
{
vary4nappend(dst, " '", 2);
vary4vescape(dst, arg);
vary4nappend(dst, "'", 1);
}
int
main(int argsc, arguments * args)
{
vary4 cmd;
int i;
char textbuf[20];
char * lang;
/* find length of library name. */
for (i = 0; i < 10 && args->pgm[i] && args->pgm[i] != '/'; i++)
;
/* Store program name in command buffer. */
cmd.len = 0;
vary4append(&cmd, "/QSYS.LIB/");
vary4nappend(&cmd, args->pgm, i);
vary4append(&cmd, ".LIB/XMLLINT.PGM");
/* Map command arguments to standard xmllint argument vector. */
if (args->dtd && args->dtd->len) {
if (args->dtdvalid && args->dtdvalid[4] == 'F')
vary4arg(&cmd, "--dtdvalidfpi");
else
vary4arg(&cmd, "--dtdvalid");
vary4vargquote(&cmd, args->dtd);
}
if (args->schema && args->schema->len) {
vary4varg(&cmd, args->schemakind);
vary4vargquote(&cmd, args->schema);
}
if (args->outstmf && args->outstmf->len) {
vary4arg(&cmd, "--output");
vary4vargquote(&cmd, args->outstmf);
if (args->encoding && args->encoding->len) {
vary4arg(&cmd, "--encoding");
vary4vargquote(&cmd, args->encoding);
}
}
if (args->xpath && args->xpath->len) {
vary4arg(&cmd, "--xpath");
vary4vargquote(&cmd, args->xpath);
}
if (args->pattern && args->pattern->len) {
vary4arg(&cmd, "--pattern");
vary4vargquote(&cmd, args->pattern);
}
if (args->path && args->path->len) {
vary4arg(&cmd, "--path '");
vary4vescape(&cmd, &args->path->item[0].param);
for (i = 1; i < args->path->len; i++) {
vary4nappend(&cmd, ":", 1);
vary4vescape(&cmd, &args->path->item[i].param);
}
vary4nappend(&cmd, "'", 1);
}
if (args->pretty && args->pretty->len &&
args->pretty->string[0] != '0') {
vary4arg(&cmd, "--pretty");
vary4varg(&cmd, args->pretty);
}
if (args->maxmem && *args->maxmem) {
snprintf(textbuf, sizeof textbuf, "%lu", *args->maxmem);
vary4arg(&cmd, "--maxmem");
vary4arg(&cmd, textbuf);
}
for (i = 0; i < args->options->len; i++)
vary4varg(&cmd, &args->options->item[i].param);
vary4vargquote(&cmd, args->stmf);
/* Execute the shell command. */
qshell(&cmd);
/* Terminate. */
exit(0);
}