2015-04-21 13:56:39 +02:00
/**
* * * 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 ;
2015-04-21 16:56:54 +02:00
/* SGML add element list structure. */
typedef struct {
short elcount ; /* Element count (=3). */
paramlist ( 256 , char ) catalog ; /* vary2(256). */
paramlist ( 256 , char ) ident ; /* vary2(256). */
} sgmladdelement ;
2015-04-21 13:56:39 +02:00
/* 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. */
2015-04-21 16:56:54 +02:00
vary2 * convert ; /* Convert SGML to XML. */
2015-04-21 13:56:39 +02:00
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. */
2015-04-21 16:56:54 +02:00
paramlist ( 2 , unsigned short ) * sgmladd ; /* SGML items to add. */
2015-04-21 13:56:39 +02:00
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 ;
2015-04-21 16:56:54 +02:00
sgmladdelement * saelp ;
2015-04-21 13:56:39 +02:00
/* 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 - > 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 ) ;
}
2015-04-21 16:56:54 +02:00
if ( args - > kind & & args - > kind - > len ) {
/* Process SGML-specific parameters. */
if ( args - > superupd & & args - > superupd - > len )
vary4varg ( & cmd , args - > superupd ) ;
if ( args - > sgmladd )
for ( i = 0 ; i < args - > sgmladd - > len ; i + + ) {
saelp = OFFSETBY ( sgmladdelement , args - > sgmladd ,
args - > sgmladd - > item [ i ] . param ) ;
if ( ! ( ( vary2 * ) & saelp - > catalog ) - > len )
continue ;
vary4arg ( & cmd , " --add " ) ;
vary4vargquote ( & cmd , ( vary2 * ) & saelp - > catalog ) ;
vary4vargquote ( & cmd , ( vary2 * ) & saelp - > ident ) ;
}
}
else {
/* Process XML-specific parameters. */
if ( args - > convert & & args - > convert - > len )
vary4varg ( & cmd , args - > convert ) ;
if ( args - > add )
for ( i = 0 ; i < args - > add - > len ; i + + ) {
aelp = OFFSETBY ( addelement , args - > add ,
args - > add - > item [ i ] . param ) ;
if ( ! ( ( vary2 * ) & aelp - > origin ) - > len )
continue ;
vary4arg ( & cmd , " --add " ) ;
2015-04-21 13:56:39 +02:00
vary4varg ( & cmd , ( vary2 * ) & aelp - > type ) ;
vary4vargquote ( & cmd , ( vary2 * ) & aelp - > origin ) ;
vary4vargquote ( & cmd , ( vary2 * ) & aelp - > replace ) ;
}
2015-04-21 16:56:54 +02:00
}
2015-04-21 13:56:39 +02:00
/* 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 ) {
2015-04-21 16:56:54 +02:00
vary4arg ( & cmd , " --create - " ) ;
2015-04-21 13:56:39 +02:00
vary4arg ( & cmd , " .dmyxmlcatalog " ) ;
}
2015-04-21 16:56:54 +02:00
else {
vary4arg ( & cmd , " - " ) ;
2015-04-21 13:56:39 +02:00
vary4vargquote ( & cmd , args - > instmf ) ;
2015-04-21 16:56:54 +02:00
}
2015-04-21 13:56:39 +02:00
/* 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 ) ;
}