1 2Implementation notes: 3 4 This is a true OS/400 implementation, not a PASE implementation (for PASE, 5use an AIX implementation). 6 7 The biggest problem with OS/400 is EBCDIC. The current libxml2 implementation 8uses UTF-8 internally. To ease encoding conversion between the calling 9applications and libxml2, supplementary "convert and latch" functions are 10provided (See below). To bind the EBCDIC OS/400 system calls and libxml2, 11an ASCII run-time environment (QADRT) has been used and wrapper functions have 12been designed. 13 14Other 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 31Compiling 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 48OS/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 71Renamed header files in DB2 members: 72 DB2 member names are limited to 10 characters, thus the following C/C++ 73header members are renamed as: 74 parserInternals.h --> PARSERINTE 75 schemasInternals.h --> SCHEMASINT 76 xmlautomata.h --> XMLAUTOMAT 77 xmlschemastype.h --> SCHMTYPES 78 xpathInternals.h --> XPATHINTER 79IFS header files are NOT renamed. 80ILE/RPG headers are processed likewise. 81 82 83Special programming consideration: 84 85QADRT 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 96Supplementary (non libxml2 standard) support procedures for OS/400. 97 98 As cited above, there are some procedures to ease encoding conversion of 99libxml2 function arguments and results: the mechanism is based on 100dictionaries. The functions convert a string, latch the result in a dictionary 101to ensure its persistence and return its address. It is the caller's 102responsibility to clean the dictionary when it becomes too big or disappears. 103 104The procedures are: 105 106#include <libxml/transcode.h> 107 108const char * xmlTranscodeResult(const xmlChar * s, 109 const char * encoding, 110 xmlDictPtr * dict, 111 void (*freeproc)(const void *)); 112 113const xmlChar * xmlTranscodeString(const char * s, 114 const char * encoding, 115 xmlDictPtr * dict); 116 117const xmlChar * xmlTranscodeWString(const char * s, 118 const char * encoding, 119 xmlDictPtr * dict); 120 121const xmlChar * xmlTranscodeWString(const char * s, 122 const char * encoding, 123 xmlDictPtr * dict); 124 125where: 126s is the string to translate. 127encoding is the alternate character encoding. If null, the current job's 128 encoding (CCSID) is used. 129dict 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. 132freeproc is a procedure to release the original string, or NULL. 133 134xmlTranscodeResult() converts from UTF-8 to the given alternate encoding. 135xmlTranscodeString() converts from the given 8-bit encoding to UTF-8 (note that 136 UTF-8 itself is considered as a 8-bit encoding). 137xmlTranscodeWString() converts from the given 16-bit encoding to UTF-8. 138xmlTranscodeHString() converts from the given 32-bit encoding to UTF-8. 139 140 141To shorten statements using these functions, shorthands are defined: 142 143xmlTR for xmlTranscodeResult 144xmlTS for xmlTranscodeString 145xmlTW for xmlTranscodeWString 146xmlTH for xmlTranscodeHstring 147 148These shorthands may be disabled by defining XML_NO_SHORT_NAMES before 149libxml/transcode.h inclusion. 150 151A directory pointer must be preset to NULL before the first call using it to 152one of the above procedure. 153 154To release a latching directory, use function 155 156void xmlZapDict(xmlDictPtr * dict); 157 158 159Example: 160 161#include <libxml/transcode.h> 162#include <libxml/tree.h> 163 164xmlDocPtr 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 180Additionally, a formatter into latched/dynamic storage is provided: 181 182const char * xmlVasprintf(xmlDictPtr * dict, 183 const char * encoding, 184 const xmlChar * fmt, 185 va_list args); 186 187 188xmllint and xmlcatalog programs: 189 190 These programs are fully implemented at the qshell level, with standard 191command line options. Links to these are installed in sub-directory bin of 192the IFS installation directory. 193 CL command interfaces to these programs are also provided with limited 194support. In particular, interactive mode is not supported and argument count 195and lengths are limited by the CL command syntax. 196 197 198ILE/RPG binding: 199 200 All standard types and procedures are provided. Since ILE/RPG does not 201support macros, they have not been ported. However some of them are emulated 202as functions: these are the more useful ones (xmlXPathNodeSetGetLength, 203xmlXPathNodeSetItem, xmlXPathNodeSetIsEmpty, htmlDefaultSubelement, 204htmlElementAllowedHereDesc, htmlRequiredAttrs) and the global/threaded 205variables access macros. These variables can be read with function 206get_xxx(void), where xxxx is the name of the variable; they may be set by 207calling function set_xxxx(value), where value is of the same type as the 208variable. 209 210 The C va_list is not implemented as such in ILE/RPG. Functions implementing 211va_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) 227