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
189 ILE/RPG binding:
190
191 All standard types and procedures are provided. Since ILE/RPG does not
192 support macros, they have not been ported, with the exceptions of the more
193 useful ones and the global/threaded variables access macros. These variables
194 can be read with function get_xxx(void), where xxxx is the name of the
195 variable; they may be set by calling function set_xxxx(value), where value is
196 of the same type as the variable.
197
198 The C va_list is not implemented as such in ILE/RPG. Functions implementing
199 va_list and associated methods are provided:
200
201 /include "libxmlrpg/xmlstdarg"
202
203 d xmlVaStart pr
204 d list like(xmlVaList)
205 d lastargaddr * value
206 d lastargsize 10u 0 value
207
208 d xmlVaArg pr
209 d list like(xmlVaList)
210 d dest * value
211 d argsize 10i 0 value
212
213 d xmlVaEnd pr
214 d list like(xmlVaList)
215