/ libxml2 / os400 / README400
README400
  1  
  2  Implementation notes:
  3  
  4    This is a true OS/400 implementation, not a PASE implementation (for PASE,
  5  use an AIX implementation).
  6  
  7    The biggest problem with OS/400 is EBCDIC. The current libxml2 implementation
  8  uses UTF-8 internally. To ease encoding conversion between the calling
  9  applications and libxml2, supplementary "convert and latch" functions are
 10  provided (See below). To bind the EBCDIC OS/400 system calls and libxml2,
 11  an ASCII run-time environment (QADRT) has been used and wrapper functions have
 12  been designed.
 13  
 14  Other problems are:
 15  - Source code line length: to be stored in DB2 members, source files may not
 16    have lines longer than 100 characters. Some header and documentation files
 17    have been modified accordingly.
 18  - va_list dereferencing: the OS/400 implementation of va_list type is an array
 19    but the compiler forbids explicit array dereferencing. Source files have
 20    been updated accordingly.
 21  - Depending on the compilation/execution environment, it is possible that
 22    stdin/stdout/stderr are not associated with a file descriptor; as a side
 23    effect, open() may return a file descriptor value 0, 1 or 2 that is NOT
 24    a C standard file. Thus using such a number may be inaccurate.
 25  - iconv_open() arguments: OS/400 uses non-standard encoding names and does not
 26    support standard names. For this reason, a name wrapper has been designed.
 27  - dlopen() (support for xmodule): the function and its corollaries are not
 28    provided by the OS/400 library. However a local implementation is provided.
 29  
 30  
 31  Compiling on OS/400:
 32  
 33  _ As a prerequisite, QADRT development environment must be installed.
 34  _ Install the libxml2 source directory in IFS.
 35  _ Enter shell (QSH)
 36  _ Change current directory to the libxml2 installation directory
 37  _ Change current directory to ./os400
 38  _ Edit file iniscript.sh. You may want to change tunable configuration
 39    parameters, like debug info generation, optimisation level, listing option,
 40    target library, zlib availability, etc.
 41  _ Copy any file in the current directory to makelog (i.e.:
 42    cp initscript.sh makelog): this is intended to create the makelog file with
 43    an ASCII CCSID!
 44  _ Enter the command "sh make.sh >makelog 2>&1'
 45  _ Examine the makelog file to check for compilation errors.
 46  
 47    Leaving file initscript.sh unchanged, this will produce the following
 48  OS/400 objects:
 49  _ Library LIBXML2. All other objects will be stored in this library.
 50  _ Modules for all libxml2 units, with full debug info and no code optimization.
 51  _ Binding directory LIBXML2_A, to be used at calling program link time for
 52    statically binding the modules (specify BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR)
 53    when creating a program using LIBXML2_A).
 54  _ Service program LIBXML2. To be used at calling program run-time
 55    when this program has dynamically bound libxml2 at link time.
 56  _ Binding directory LIBXML2. To be used to dynamically bind libxml2 when
 57    linking a calling program.
 58  _ Source file LIBXML. It contains all the header members needed to compile a
 59    C/C++ module using libxml2.
 60  _ Standard and additional C/C++ libxml2 header members (possibly renamed) in
 61    file LIBXML.
 62  _ IFS directory /libxml2 with subdirectory include/libxml containing all
 63    C/C++ header files for IFS-based compilation.
 64  _ Source file LIBXMLRPG. It contains all the include members needed to compile a
 65    ILE/RPG module/program using libxml2 (ILE/RPG binding).
 66  _ ILE/RPG binding include members (possibly renamed) in file LIBXMLRPG.
 67  _ IFS subdirectory /libxml2/include/libxmlrpg containing all ILE/RPG include
 68    files for IFS-based compilation.
 69  
 70  
 71  Renamed header files in DB2 members:
 72    DB2 member names are limited to 10 characters, thus the following C/C++
 73  header members are renamed as:
 74    parserInternals.h     -->     PARSERINTE
 75    schemasInternals.h    -->     SCHEMASINT
 76    xmlautomata.h         -->     XMLAUTOMAT
 77    xmlschemastype.h      -->     SCHMTYPES
 78    xpathInternals.h      -->     XPATHINTER
 79  IFS header files are NOT renamed.
 80  ILE/RPG headers are processed likewise.
 81  
 82  
 83  Special programming consideration:
 84  
 85  QADRT being used, the following points must be considered:
 86  _ If static binding is used, service program QADRTTS must be linked too.
 87  _ The EBCDIC CCSID used by QADRT is 37 by default, NOT THE JOB'S CCSID. If
 88    another EBCDIC CCSID is required, it must be set via a locale through a call
 89    to setlocale_a (QADRT's setlocale() ASCII wrapper) with category LC_ALL or
 90    LC_CTYPE, or by setting environment variable QADRT_ENV_LOCALE to the locale
 91    object path before executing the program.
 92  _ Always use *IFSIO or *IFS64IO to compile calling programs.
 93  
 94  
 95  
 96  Supplementary (non libxml2 standard) support procedures for OS/400.
 97  
 98    As cited above, there are some procedures to ease encoding conversion of
 99  libxml2 function arguments and results: the mechanism is based on
100  dictionaries. The functions convert a string, latch the result in a dictionary
101  to ensure its persistence and return its address. It is the caller's
102  responsibility to clean the dictionary when it becomes too big or disappears.
103  
104  The procedures are:
105  
106  #include <libxml/transcode.h>
107  
108  const char *  xmlTranscodeResult(const xmlChar * s,
109                                   const char * encoding,
110                                   xmlDictPtr * dict,
111                                   void (*freeproc)(const void *));
112  
113  const xmlChar * xmlTranscodeString(const char * s,
114                                     const char * encoding,
115                                     xmlDictPtr * dict);
116  
117  const xmlChar * xmlTranscodeWString(const char * s,
118                                      const char * encoding,
119                                      xmlDictPtr * dict);
120  
121  const xmlChar * xmlTranscodeWString(const char * s,
122                                      const char * encoding,
123                                      xmlDictPtr * dict);
124  
125  where:
126  s               is the string to translate.
127  encoding        is the alternate character encoding. If null, the current job's
128                  encoding (CCSID) is used.
129  dict            is the address of the latching directory. If NULL, the procedure
130                  functions as a simple non-latching encoding converter and
131                  its result value should be freed by the caller.
132  freeproc        is a procedure to release the original string, or NULL.
133  
134  xmlTranscodeResult()  converts from UTF-8 to the given alternate encoding.
135  xmlTranscodeString()  converts from the given 8-bit encoding to UTF-8 (note that
136                        UTF-8 itself is considered as a 8-bit encoding).
137  xmlTranscodeWString() converts from the given 16-bit encoding to UTF-8.
138  xmlTranscodeHString() converts from the given 32-bit encoding to UTF-8.
139  
140  
141  To shorten statements using these functions, shorthands are defined:
142  
143  xmlTR for xmlTranscodeResult
144  xmlTS for xmlTranscodeString
145  xmlTW for xmlTranscodeWString
146  xmlTH for xmlTranscodeHstring
147  
148  These shorthands may be disabled by defining XML_NO_SHORT_NAMES before
149  libxml/transcode.h inclusion.
150  
151  A directory pointer must be preset to NULL before the first call using it to
152  one of the above procedure.
153  
154  To release a latching directory, use function
155  
156  void          xmlZapDict(xmlDictPtr * dict);
157  
158  
159  Example:
160  
161  #include <libxml/transcode.h>
162  #include <libxml/tree.h>
163  
164  xmlDocPtr mySimpleXMLDoc(char * element, char * text)
165  {
166          xmlDocPtr doc;
167          xmlNodePtr node;
168          xmlDictPtr dict = NULL;
169  
170          /* element and text are encoded in the current job's encoding. */
171  
172          doc = xmlNewDoc();
173          xmlNewTextChild((xmlNodePtr) doc, NULL, xmlTS(element, NULL,
174                                 &dict), xmlTS(text, NULL, &dict));
175          xmlZapDict(&dict);
176          return doc;
177  }
178  
179  
180  Additionally, a formatter into latched/dynamic storage is provided:
181  
182  const char *    xmlVasprintf(xmlDictPtr * dict,
183                               const char * encoding,
184                               const xmlChar * fmt,
185                               va_list args);
186  
187  
188  xmllint and xmlcatalog programs:
189  
190    These programs are fully implemented at the qshell level, with standard
191  command line options. Links to these are installed in sub-directory bin of
192  the IFS installation directory.
193    CL command interfaces to these programs are also provided with limited
194  support. In particular, interactive mode is not supported and argument count
195  and lengths are limited by the CL command syntax.
196  
197  
198  ILE/RPG binding:
199  
200    All standard types and procedures are provided. Since ILE/RPG does not
201  support macros, they have not been ported. However some of them are emulated
202  as functions: these are the more useful ones (xmlXPathNodeSetGetLength,
203  xmlXPathNodeSetItem, xmlXPathNodeSetIsEmpty, htmlDefaultSubelement,
204  htmlElementAllowedHereDesc, htmlRequiredAttrs) and the global/threaded
205  variables access macros. These variables can be read with function
206  get_xxx(void), where xxxx is the name of the variable; they may be set by
207  calling function set_xxxx(value), where value is of the same type as the
208  variable.
209  
210    The C va_list is not implemented as such in ILE/RPG. Functions implementing
211  va_list and associated methods are provided:
212  
213        /include "libxmlrpg/xmlstdarg"
214  
215       d xmlVaStart      pr
216       d  list                               like(xmlVaList)
217       d  lastargaddr                    *   value
218       d  lastargsize                  10u 0 value
219  
220       d xmlVaArg        pr
221       d  list                               like(xmlVaList)
222       d  dest                           *   value
223       d  argsize                      10i 0 value
224  
225       d xmlVaEnd        pr
226       d  list                               like(xmlVaList)