(root)/
libxml2-2.12.3/
os400/
xmllintcl.c
       1  /**
       2  ***     XMLLINT command response program.
       3  ***
       4  ***     See Copyright for the status of this software.
       5  ***
       6  ***     Author: Patrick Monnerat <pm@datasphere.ch>, 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  }