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)
|
---|