[libxml2] os400: implement CL command XMLCATALOG.



commit 9b5a57cf37f5a79c3459ef978fa9f51fa29cd1d6
Author: Patrick Monnerat <pm datasphere ch>
Date:   Tue Apr 21 13:56:39 2015 +0200

    os400: implement CL command XMLCATALOG.

 os400/make-src.sh    |   34 ++++++-
 os400/xmlcatalog.cmd |   93 ++++++++++++++++++
 os400/xmlcatlgcl.c   |  259 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 383 insertions(+), 3 deletions(-)
---
diff --git a/os400/make-src.sh b/os400/make-src.sh
index 6bd1c69..6094de8 100644
--- a/os400/make-src.sh
+++ b/os400/make-src.sh
@@ -17,7 +17,7 @@ cd "${TOPDIR}"
 echo '#pragma comment(user, "libxml2 version '"${LIBXML_VERSION}"'")' > os400.c
 echo '#pragma comment(user, __DATE__)' >> os400.c
 echo '#pragma comment(user, __TIME__)' >> os400.c
-echo '#pragma comment(copyright, "Copyright (C) 1998-2014 Daniel Veillard. OS/400 version by P. Monnerat.")' 
os400.c
+echo '#pragma comment(copyright, "Copyright (C) 1998-2015 Daniel Veillard. OS/400 version by P. Monnerat.")' 
os400.c
 make_module     OS400           os400.c
 LINK=                           # No need to rebuild service program yet.
 MODULES=
@@ -250,7 +250,7 @@ make_module     --ebcdic --sysiconv     LIBXMLMAIN  "${SCRIPTDIR}/libxmlmain.c"
 
 if action_needed "${LIBIFSNAME}/XMLLINT.PGM" "xmllint.c" ||
    action_needed "${LIBIFSNAME}/XMLLINT.PGM" "${LIBIFSNAME}/${SRVPGM}.SRVPGM" ||
-   action_needed "${LIBIFSNAME}/XMLLINT.PGM" "${LIBIFSNAME}/LIMXMLMAIN.MODULE"
+   action_needed "${LIBIFSNAME}/XMLLINT.PGM" "${LIBIFSNAME}/LIBXMLMAIN.MODULE"
 then    make_module XMLLINT xmllint.c
         CMD="CRTPGM PGM(${TARGETLIB}/XMLLINT) MODULE(${TARGETLIB}/XMLLINT)"
         CMD="${CMD} ENTMOD(${TARGETLIB}/LIBXMLMAIN)"
@@ -306,7 +306,7 @@ if action_needed "${LIBIFSNAME}/XMLCATALOG.PGM" "xmlcatalog.c" ||
    action_needed "${LIBIFSNAME}/XMLCATALOG.PGM"                         \
                  "${LIBIFSNAME}/${SRVPGM}.SRVPGM" ||
    action_needed "${LIBIFSNAME}/XMLCATALOG.PGM"                         \
-                 "${LIBIFSNAME}/LIMXMLMAIN.MODULE"
+                 "${LIBIFSNAME}/LIBXMLMAIN.MODULE"
 then    make_module XMLCATALOG xmlcatalog.c
         CMD="CRTPGM PGM(${TARGETLIB}/XMLCATALOG)"
         CMD="${CMD}  MODULE(${TARGETLIB}/XMLCATALOG)"
@@ -325,3 +325,31 @@ fi
 
 rm -f "${IFSDIR}/bin/xmlcatalog"
 ln -s "${LIBIFSNAME}/XMLCATALOG.PGM" "${IFSDIR}/bin/xmlcatalog"
+
+#       Prepare the XMLCATALOG command and its response program.
+
+if action_needed "${LIBIFSNAME}/XMLCATLGCL.PGM" "${SCRIPTDIR}/xmlcatlgcl.c"
+then    make_module --ebcdic XMLCATLGCL "${SCRIPTDIR}/xmlcatlgcl.c"
+        CMD="CRTPGM PGM(${TARGETLIB}/XMLCATLGCL)"
+        CMD="${CMD} MODULE(${TARGETLIB}/XMLCATLGCL)"
+        CMD="${CMD} ACTGRP(*NEW) TEXT('XMLCATALOG command response')"
+        CMD="${CMD} TGTRLS(${TGTRLS})"
+        system "${CMD}"
+        rm -f "${LIBIFSNAME}/XMLCATLGCL.MODULE"
+fi
+
+if action_needed "${LIBIFSNAME}/TOOLS.FILE/XMLCATALOG.MBR"              \
+                 "${SCRIPTDIR}/xmlcatalog.cmd"
+then    CMD="CPY OBJ('${SCRIPTDIR}/xmlcatalog.cmd')"
+        CMD="${CMD} TOOBJ('${LIBIFSNAME}/TOOLS.FILE/XMLCATALOG.MBR')"
+        CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
+        system "${CMD}"
+fi
+
+if action_needed "${LIBIFSNAME}/XMLCATALOG.CMD"                         \
+                 "${LIBIFSNAME}/TOOLS.FILE/XMLCATALOG.MBR"
+then    CMD="CRTCMD CMD(${TARGETLIB}/XMLCATALOG) PGM(${TARGETLIB}/XMLCATLGCL)"
+        CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(XMLCATALOG)"
+        CMD="${CMD} THDSAFE(*YES) TEXT('XML/SGML catalog tool') REPLACE(*YES)"
+        system "${CMD}"
+fi
diff --git a/os400/xmlcatalog.cmd b/os400/xmlcatalog.cmd
new file mode 100644
index 0000000..aac523f
--- /dev/null
+++ b/os400/xmlcatalog.cmd
@@ -0,0 +1,93 @@
+/*      XMLCATALOG CL command.                                                */
+/*                                                                            */
+/*      See Copyright for the status of this software.                        */
+/*                                                                            */
+/*      Author: Patrick Monnerat <pm datasphere ch>, DATASPHERE S.A.          */
+
+/*      Interface to program XMLCATLGCL                                       */
+
+             CMD        PROMPT('XML/SGML catalog  tool')
+
+             /* Catalog file path. */
+
+             PARM       KWD(INSTMF) TYPE(*PNAME) LEN(5000) VARY(*YES *INT2)    +
+                          CASE(*MIXED) EXPR(*YES) MIN(1) SPCVAL((*NEW ''))     +
+                          CHOICE('Stream file path')                           +
+                          PROMPT('XML/SGML catalog file')
+
+             /* Catalog kind: XML/SGML. */
+
+             PARM       KWD(KIND) TYPE(*CHAR) LEN(7) VARY(*YES *INT2)          +
+                          EXPR(*YES) RSTD(*YES) DFT(*XML)                      +
+                          SPCVAL((*XML '') (*SGML '--sgml'))                   +
+                          PROMPT('Catalog kind')
+
+             /* Output file. */
+
+             PARM       KWD(OUTSTMF) TYPE(*PNAME) LEN(5000) VARY(*YES *INT2)   +
+                          CASE(*MIXED) EXPR(*YES) DFT(*STDOUT)                 +
+                          SPCVAL((*STDOUT '') (*INSTMF X'00'))                 +
+                          CHOICE('*STDOUT, *INSTMF or file path')              +
+                          PROMPT('Output stream file path')
+
+             /* SGML super catalog update. */
+
+             PARM       KWD(SUPERUPD) TYPE(*CHAR) LEN(17) VARY(*YES *INT2)     +
+                          SPCVAL((*YES '') (*NO '--no-super-update'))          +
+                          EXPR(*YES) DFT(*YES) RSTD(*YES)                      +
+                          PROMPT('Update the SGML super catalog')
+
+             /* Verbose/debug output. */
+
+             PARM       KWD(VERBOSE) TYPE(*CHAR) LEN(4) VARY(*YES *INT2)       +
+                          RSTD(*YES) SPCVAL((*YES '-v') (*NO ''))              +
+                          EXPR(*YES) DFT(*NO)                                  +
+                          PROMPT('Output debugging information')
+
+             /* Interactive shell not supported. */
+
+             /* Values to delete. */
+
+             PARM       KWD(DELETE) TYPE(*PNAME) LEN(256) VARY(*YES *INT2)     +
+                          CASE(*MIXED) MAX(64) EXPR(*YES)                      +
+                          CHOICE('Identifier value')                           +
+                          PROMPT('Delete System/URI identifier')
+
+             /* Values to add. */
+
+             PARM       KWD(ADD) TYPE(ADDELEM) MAX(10)                         +
+                          PROMPT('Add definition')
+ADDELEM:     ELEM       TYPE(*CHAR) LEN(16) VARY(*YES *INT2) DFT(*PUBLIC)      +
+                          PROMPT('Entry type')                                 +
+                          EXPR(*YES) RSTD(*YES) SPCVAL(                        +
+                            (*PUBLIC         'public')                         +
+                            (*SYSTEM         'system')                         +
+                            (*URI            'uri')                            +
+                            (*REWRITESYSTEM  'rewriteSystem')                  +
+                            (*REWRITEURI     'rewriteURI')                     +
+                            (*DELEGATEPUBLIC 'delegatePublic')                 +
+                            (*DELEGATESYSTEM 'delegateSystem')                 +
+                            (*DELEGATEURI    'delegateURI')                    +
+                            (*NEXTCATALOG    'nextCatalog')                    +
+                            (*FILENAME       '')                               +
+                          )
+             ELEM       TYPE(*PNAME) LEN(256) VARY(*YES *INT2) EXPR(*YES)      +
+                          CASE(*MIXED) PROMPT('Original reference/file name')
+             ELEM       TYPE(*PNAME) LEN(256) VARY(*YES *INT2) EXPR(*YES)      +
+                          CASE(*MIXED) PROMPT('Replacement entity URI')
+
+             /* Entities to resolve. */
+
+             PARM       KWD(ENTITY) TYPE(*PNAME) LEN(256) VARY(*YES *INT2)     +
+                          CASE(*MIXED) EXPR(*YES) MAX(150)                     +
+                          PROMPT('Resolve entity')
+
+             /* Additional catalog files. */
+
+             PARM       KWD(CATALOG) TYPE(*PNAME) LEN(5000) VARY(*YES *INT2)   +
+                          CASE(*MIXED) EXPR(*YES) MAX(150) DFT(*DEFAULT)       +
+                          CHOICE('Catalog stream file path')                   +
+                          PROMPT('Additional catalog file') SPCVAL(            +
+                            (*DEFAULT       '/etc/xml/catalog')                +
+                            (*NONE          '')                                +
+                          )
diff --git a/os400/xmlcatlgcl.c b/os400/xmlcatlgcl.c
new file mode 100644
index 0000000..c178b41
--- /dev/null
+++ b/os400/xmlcatlgcl.c
@@ -0,0 +1,259 @@
+/**
+***     XMLCATALOG 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;                                    \
+                _Packed union {                                         \
+                         char           _pad[itemsize];                 \
+                        itemtype        param;                          \
+                }               item[1];                                \
+        }
+
+/* Add element list structure. */
+typedef struct {
+        short           elcount;        /* Element count (=3). */
+        paramlist(16, char) type;       /* vary2(16). */
+        paramlist(256, char) origin;    /* vary2(256). */
+        paramlist(256, char) replace;   /* vary2(256). */
+}               addelement;
+
+
+/* Arguments from CL command. */
+typedef struct {
+        char *          pgm;            /* Program name. */
+        vary2 *         instmf;         /* Input catalog file name. */
+        vary2 *         kind;           /* Catalog kind. */
+        vary2 *         outstmf;        /* Output catalog file name. */
+        vary2 *         superupd;       /* --no-super-update. */
+        vary2 *         verbose;        /* Verbose output. */
+        paramlist(256 + 2, vary2) * delete; /* Identifiers to delete. */
+        paramlist(2, unsigned short) * add; /* Items to add. */
+        paramlist(256 + 2, vary2) * resolve; /* Identifiers to resolve. */
+        paramlist(5000 + 2, vary2) * catalog; /* Additional catalog files. */
+}               arguments;
+
+
+/* Definition of QSHELL program. */
+extern void     qshell(vary4 * cmd);
+#pragma linkage(qshell, OS)
+#pragma map(qshell, "QSHELL/QZSHQSHC")
+
+/* Macro to handle displacements. */
+#define OFFSETBY(t, p, n)       ((t *) (((char *) (p)) + (n)))
+
+
+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 c;
+        addelement * aelp;
+
+        /* Specify additional catalogs. */
+        cmd.len = 0;
+        if (args->catalog->len) {
+                for (i = 0; i < args->catalog->len &&
+                            !args->catalog->item[i].param.len; i++)
+                        ;
+
+                vary4append(&cmd, "XML_CATALOG_FILES=");
+                if (i < args->catalog->len) {
+                        c = '\'';
+                        for (i = 0; i < args->catalog->len; i++) {
+                                if (!args->catalog->item[i].param.len)
+                                        continue;
+                                vary4nappend(&cmd, &c, 1);
+                                c = ' ';
+                                vary4vescape(&cmd,
+                                            &args->catalog->item[i].param);
+                                }
+                        vary4nappend(&cmd, "'", 1);
+                        }
+                vary4nappend(&cmd, " ", 1);
+                }
+
+        /* find length of library name. */
+        for (i = 0; i < 10 && args->pgm[i] && args->pgm[i] != '/'; i++)
+                ;
+
+        /* Store program name in command buffer. */
+        vary4append(&cmd, "/QSYS.LIB/");
+        vary4nappend(&cmd, args->pgm, i);
+        vary4append(&cmd, ".LIB/XMLCATALOG.PGM");
+
+        /* Map command arguments to standard xmlcatalog argument vector. */
+        if (args->kind && args->kind->len)
+                vary4varg(&cmd, args->kind);
+
+        if (args->superupd && args->superupd->len)
+                vary4varg(&cmd, args->superupd);
+
+        if (args->verbose && args->verbose->len)
+                vary4varg(&cmd, args->verbose);
+
+        if (args->delete)
+                for (i = 0; i < args->delete->len; i++) {
+                        vary4arg(&cmd, "--del");
+                        vary4vargquote(&cmd, &args->delete->item[i].param);
+                        }
+
+        if (args->add)
+                for (i = 0; i < args->add->len; i++) {
+                        aelp = OFFSETBY(addelement,
+                                        args->add, args->add->item[i].param);
+                        vary4arg(&cmd, "--add");
+                        if (((vary2 *) &aelp->type)->len) {
+                                vary4varg(&cmd, (vary2 *) &aelp->type);
+                                vary4vargquote(&cmd, (vary2 *) &aelp->origin);
+                                vary4vargquote(&cmd, (vary2 *) &aelp->replace);
+                                }
+                        else
+                                vary4vargquote(&cmd, (vary2 *) &aelp->origin);
+                        }
+
+        /* Avoid INSTMF(*NEW) and OUTSMTF(*INSTMF). */
+        if (args->outstmf && args->outstmf->len && !args->outstmf->string[0])
+                if (args->instmf && args->instmf->len)
+                        args->outstmf = args->instmf;
+                else
+                        args->outstmf = NULL;
+
+        /* If INSTMF(*NEW) and OUTSTMF(somepath), Use --create --noout and
+           somepath as (unexisting) input file. */
+        if (args->outstmf && args->outstmf->len)
+                if (!args->instmf || !args->instmf->len) {
+                        vary4arg(&cmd, "--create");
+                        vary4arg(&cmd, "--noout");
+                        args->instmf = args->outstmf;
+                        args->outstmf = NULL;
+                        }
+
+        /* If output to input file, use --noout option. */
+        if (args->instmf && args->outstmf && args->instmf->len &&
+            args->instmf->len == args->outstmf->len &&
+            !strncmp(args->instmf->string, args->outstmf->string,
+                     args->instmf->len)) {
+                vary4arg(&cmd, "--noout");
+                args->outstmf = NULL;
+                }
+
+        /* If no input file create catalog, else specify the input file name. */
+        /* Specify the input file name: my be a dummy one. */
+        if (!args->instmf || !args->instmf->len) {
+                vary4arg(&cmd, "--create");
+                vary4arg(&cmd, ".dmyxmlcatalog");
+                }
+        else
+                vary4vargquote(&cmd, args->instmf);
+
+        /* Query entities. */
+
+        if (args->resolve)
+                for (i = 0; i < args->resolve->len; i++)
+                        vary4vargquote(&cmd, &args->resolve->item[i].param);
+
+        /* Redirect output if requested. */
+        if (args->outstmf && args->outstmf->len) {
+                vary4arg(&cmd, ">");
+                vary4vargquote(&cmd, args->outstmf);
+                }
+
+        /* Execute the shell command. */
+        qshell(&cmd);
+
+        /* Terminate. */
+        exit(0);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]