You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
9.3 KiB
226 lines
9.3 KiB
|
|
Implementation notes: |
|
|
|
This is a true OS/400 implementation, not a PASE implementation (for PASE, |
|
use an AIX implementation). |
|
|
|
The biggest problem with OS/400 is EBCDIC. The current libxml2 implementation |
|
uses UTF-8 internally. To ease encoding conversion between the calling |
|
applications and libxml2, supplementary "convert and latch" functions are |
|
provided (See below). To bind the EBCDIC OS/400 system calls and libxml2, |
|
an ASCII run-time environment (QADRT) has been used and wrapper functions have |
|
been designed. |
|
|
|
Other problems are: |
|
- Source code line length: to be stored in DB2 members, source files may not |
|
have lines longer than 100 characters. Some header and documentation files |
|
have been modified accordingly. |
|
- va_list dereferencing: the OS/400 implementation of va_list type is an array |
|
but the compiler forbids explicit array dereferencing. Source files have |
|
been updated accordingly. |
|
- Depending on the compilation/execution environment, it is possible that |
|
stdin/stdout/stderr are not associated with a file descriptor; as a side |
|
effect, open() may return a file descriptor value 0, 1 or 2 that is NOT |
|
a C standard file. Thus using such a number may be inaccurate. |
|
- iconv_open() arguments: OS/400 uses non-standard encoding names and does not |
|
support standard names. For this reason, a name wrapper has been designed. |
|
- dlopen() (support for xmodule): the function and its corollaries are not |
|
provided by the OS/400 library. However a local implementation is provided. |
|
|
|
|
|
Compiling on OS/400: |
|
|
|
_ As a prerequisite, QADRT development environment must be installed. |
|
_ Install the libxml2 source directory in IFS. |
|
_ Enter shell (QSH) |
|
_ Change current directory to the libxml2 installation directory |
|
_ Change current directory to ./os400 |
|
_ Edit file iniscript.sh. You may want to change tunable configuration |
|
parameters, like debug info generation, optimisation level, listing option, |
|
target library, zlib availability, etc. |
|
_ Copy any file in the current directory to makelog (i.e.: |
|
cp initscript.sh makelog): this is intended to create the makelog file with |
|
an ASCII CCSID! |
|
_ Enter the command "sh make.sh >makelog 2>&1' |
|
_ Examine the makelog file to check for compilation errors. |
|
|
|
Leaving file initscript.sh unchanged, this will produce the following |
|
OS/400 objects: |
|
_ Library LIBXML2. All other objects will be stored in this library. |
|
_ Modules for all libxml2 units, with full debug info and no code optimization. |
|
_ Binding directory LIBXML2_A, to be used at calling program link time for |
|
statically binding the modules (specify BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR) |
|
when creating a program using LIBXML2_A). |
|
_ Service program LIBXML2. To be used at calling program run-time |
|
when this program has dynamically bound libxml2 at link time. |
|
_ Binding directory LIBXML2. To be used to dynamically bind libxml2 when |
|
linking a calling program. |
|
_ Source file LIBXML. It contains all the header members needed to compile a |
|
C/C++ module using libxml2. |
|
_ Standard and additional C/C++ libxml2 header members (possibly renamed) in |
|
file LIBXML. |
|
_ IFS directory /libxml2 with subdirectory include/libxml containing all |
|
C/C++ header files for IFS-based compilation. |
|
_ Source file LIBXMLRPG. It contains all the include members needed to compile a |
|
ILE/RPG module/program using libxml2 (ILE/RPG binding). |
|
_ ILE/RPG binding include members (possibly renamed) in file LIBXMLRPG. |
|
_ IFS subdirectory /libxml2/include/libxmlrpg containing all ILE/RPG include |
|
files for IFS-based compilation. |
|
|
|
|
|
Renamed header files in DB2 members: |
|
DB2 member names are limited to 10 characters, thus the following C/C++ |
|
header members are renamed as: |
|
parserInternals.h --> PARSERINTE |
|
schemasInternals.h --> SCHEMASINT |
|
xmlautomata.h --> XMLAUTOMAT |
|
xmlschemastype.h --> SCHMTYPES |
|
xpathInternals.h --> XPATHINTER |
|
IFS header files are NOT renamed. |
|
ILE/RPG headers are processed likewise. |
|
|
|
|
|
Special programming consideration: |
|
|
|
QADRT being used, the following points must be considered: |
|
_ If static binding is used, service program QADRTTS must be linked too. |
|
_ The EBCDIC CCSID used by QADRT is 37 by default, NOT THE JOB'S CCSID. If |
|
another EBCDIC CCSID is required, it must be set via a locale through a call |
|
to setlocale_a (QADRT's setlocale() ASCII wrapper) with category LC_ALL or |
|
LC_CTYPE, or by setting environment variable QADRT_ENV_LOCALE to the locale |
|
object path before executing the program. |
|
_ Always use *IFSIO or *IFS64IO to compile calling programs. |
|
|
|
|
|
|
|
Supplementary (non libxml2 standard) support procedures for OS/400. |
|
|
|
As cited above, there are some procedures to ease encoding conversion of |
|
libxml2 function arguments and results: the mechanism is based on |
|
dictionaries. The functions convert a string, latch the result in a dictionary |
|
to ensure its persistence and return its address. It is the caller's |
|
responsibility to clean the dictionary when it becomes too big or disappears. |
|
|
|
The procedures are: |
|
|
|
#include <libxml/transcode.h> |
|
|
|
const char * xmlTranscodeResult(const xmlChar * s, |
|
const char * encoding, |
|
xmlDictPtr * dict, |
|
void (*freeproc)(const void *)); |
|
|
|
const xmlChar * xmlTranscodeString(const char * s, |
|
const char * encoding, |
|
xmlDictPtr * dict); |
|
|
|
const xmlChar * xmlTranscodeWString(const char * s, |
|
const char * encoding, |
|
xmlDictPtr * dict); |
|
|
|
const xmlChar * xmlTranscodeWString(const char * s, |
|
const char * encoding, |
|
xmlDictPtr * dict); |
|
|
|
where: |
|
s is the string to translate. |
|
encoding is the alternate character encoding. If null, the current job's |
|
encoding (CCSID) is used. |
|
dict is the address of the latching directory. If NULL, the procedure |
|
functions as a simple non-latching encoding converter and |
|
its result value should be freed by the caller. |
|
freeproc is a procedure to release the original string, or NULL. |
|
|
|
xmlTranscodeResult() converts from UTF-8 to the given alternate encoding. |
|
xmlTranscodeString() converts from the given 8-bit encoding to UTF-8 (note that |
|
UTF-8 itself is considered as a 8-bit encoding). |
|
xmlTranscodeWString() converts from the given 16-bit encoding to UTF-8. |
|
xmlTranscodeHString() converts from the given 32-bit encoding to UTF-8. |
|
|
|
|
|
To shorten statements using these functions, shorthands are defined: |
|
|
|
xmlTR for xmlTranscodeResult |
|
xmlTS for xmlTranscodeString |
|
xmlTW for xmlTranscodeWString |
|
xmlTH for xmlTranscodeHstring |
|
|
|
These shorthands may be disabled by defining XML_NO_SHORT_NAMES before |
|
libxml/transcode.h inclusion. |
|
|
|
A directory pointer must be preset to NULL before the first call using it to |
|
one of the above procedure. |
|
|
|
To release a latching directory, use function |
|
|
|
void xmlZapDict(xmlDictPtr * dict); |
|
|
|
|
|
Example: |
|
|
|
#include <libxml/transcode.h> |
|
#include <libxml/tree.h> |
|
|
|
xmlDocPtr mySimpleXMLDoc(char * element, char * text) |
|
{ |
|
xmlDocPtr doc; |
|
xmlNodePtr node; |
|
xmlDictPtr dict = NULL; |
|
|
|
/* element and text are encoded in the current job's encoding. */ |
|
|
|
doc = xmlNewDoc(); |
|
xmlNewTextChild((xmlNodePtr) doc, NULL, xmlTS(element, NULL, |
|
&dict), xmlTS(text, NULL, &dict)); |
|
xmlZapDict(&dict); |
|
return doc; |
|
} |
|
|
|
|
|
Additionally, a formatter into latched/dynamic storage is provided: |
|
|
|
const char * xmlVasprintf(xmlDictPtr * dict, |
|
const char * encoding, |
|
const xmlChar * fmt, |
|
va_list args); |
|
|
|
|
|
xmllint and xmlcatalog programs: |
|
|
|
These programs are fully implemented at the qshell level, with standard |
|
command line options. Links to these are installed in sub-directory bin of |
|
the IFS installation directory. |
|
CL command interfaces to these programs are also provided with limited |
|
support. In particular, interactive mode is not supported and argument count |
|
and lengths are limited by the CL command syntax. |
|
|
|
|
|
ILE/RPG binding: |
|
|
|
All standard types and procedures are provided. Since ILE/RPG does not |
|
support macros, they have not been ported. However some of them are emulated |
|
as functions: these are the more useful ones (xmlXPathNodeSetGetLength, |
|
xmlXPathNodeSetItem, xmlXPathNodeSetIsEmpty, htmlDefaultSubelement, |
|
htmlElementAllowedHereDesc, htmlRequiredAttrs) and the global/threaded |
|
variables access macros. These variables can be read with function |
|
get_xxx(void), where xxxx is the name of the variable; they may be set by |
|
calling function set_xxxx(value), where value is of the same type as the |
|
variable. |
|
|
|
The C va_list is not implemented as such in ILE/RPG. Functions implementing |
|
va_list and associated methods are provided: |
|
|
|
/include "libxmlrpg/xmlstdarg" |
|
|
|
d xmlVaStart pr |
|
d list like(xmlVaList) |
|
d lastargaddr * value |
|
d lastargsize 10u 0 value |
|
|
|
d xmlVaArg pr |
|
d list like(xmlVaList) |
|
d dest * value |
|
d argsize 10i 0 value |
|
|
|
d xmlVaEnd pr |
|
d list like(xmlVaList)
|
|
|