Index: trunk/src/helpers/encodings.c
===================================================================
--- trunk/src/helpers/encodings.c	(revision 186)
+++ trunk/src/helpers/encodings.c	(revision 187)
@@ -2,5 +2,8 @@
 /*
  *@@sourcefile encodings.c:
- *      character encoding translations.
+ *      character encoding support. Handles all kinds
+ *      of legacy codepages (including most OS/2 codepage)
+ *      and Unicode in the form of UTF-8 and translations
+ *      between then.
  *
  *      See encCreateCodec for an introduction.
Index: trunk/src/helpers/xml.c
===================================================================
--- trunk/src/helpers/xml.c	(revision 186)
+++ trunk/src/helpers/xml.c	(revision 187)
@@ -1902,4 +1902,5 @@
  *
  *@@added V0.9.14 (2001-08-09) [umoeller]
+ *@@changed V0.9.20 (2002-07-06) [umoeller]: added automatic doctype support
  */
 
@@ -1915,6 +1916,4 @@
     int i = 0;          // return error per default
 
-    APIRET  arc = NO_ERROR;
-
     // store the previous parser because
     // all the callbacks use the parser pointer
@@ -1922,5 +1921,7 @@
     pDom->pParser = NULL;
 
-    if (    (pDom->pfnExternalHandler)
+    if (    (    (pDom->pfnExternalHandler)
+              || (pDom->cSystemIds)      // V0.9.20 (2002-07-06) [umoeller]
+            )
             // create sub-parser and replace the one
             // in the DOM with it
@@ -1930,38 +1931,73 @@
        )
     {
-        if ((arc = pDom->pfnExternalHandler(pDom,
-                                            pDom->pParser,
-                                            pcszSystemId,
-                                            pcszPublicId)))
-        {
-            // error:
-            // now this needs special handling, since we're
-            // dealing with a sub-handler here...
-
-            if (arc == -1)
-                // parser error: well, then xmlSetError has been
-                // called from somewhere in the callbacks already,
-                // and we can safely ignore this
-                ;
+        // run through the predefined doctypes given to us
+        // in xmlCreateDOM, if any
+        // V0.9.20 (2002-07-06) [umoeller]
+        BOOL fCallExternal = TRUE;
+        ULONG ul;
+
+        for (ul = 0;
+             ul < pDom->cSystemIds;
+             ++ul)
+        {
+            const STATICSYSTEMID *pThis = &pDom->paSystemIds[ul];
+            if (!strcmp(pThis->pcszSystemId, pcszSystemId))
+            {
+                // this one matches:
+                // then parse the corresponding entry given
+                // to us
+                if (XML_Parse(pDom->pParser,
+                              pThis->pcszContent,
+                              strlen(pThis->pcszContent),
+                              TRUE))
+                    i = 1;      // success
+
+                fCallExternal = FALSE;
+
+                break;
+            }
+        }
+
+        if (    (fCallExternal)     // not handled above
+             && (pDom->pfnExternalHandler) // user handler set
+           )
+        {
+            APIRET  arc;
+
+            if (!(arc = pDom->pfnExternalHandler(pDom,
+                                                 pDom->pParser,
+                                                 pcszSystemId,
+                                                 pcszPublicId)))
+                i = 1;      // success
             else
             {
-                pDom->arcDOM = arc;
-                if (pcszSystemId)
+                // error:
+                // now this needs special handling, since we're
+                // dealing with a sub-handler here...
+
+                if (arc == -1)
+                    // parser error: well, then xmlSetError has been
+                    // called from somewhere in the callbacks already,
+                    // and we can safely ignore this
+                    ;
+                else
                 {
-                    if (!pDom->pxstrFailingNode)
-                        pDom->pxstrFailingNode = xstrCreate(0);
-                    xstrcpy(pDom->pxstrFailingNode, pcszSystemId, 0);
+                    pDom->arcDOM = arc;
+                    if (pcszSystemId)
+                    {
+                        if (!pDom->pxstrFailingNode)
+                            pDom->pxstrFailingNode = xstrCreate(0);
+                        xstrcpy(pDom->pxstrFailingNode, pcszSystemId, 0);
+                    }
+                    pDom->pcszErrorDescription = xmlDescribeError(arc);
+                    pDom->ulErrorLine = XML_GetCurrentLineNumber(pDom->pParser);
+                    pDom->ulErrorColumn = XML_GetCurrentColumnNumber(pDom->pParser);
                 }
-                pDom->pcszErrorDescription = xmlDescribeError(arc);
-                pDom->ulErrorLine = XML_GetCurrentLineNumber(pDom->pParser);
-                pDom->ulErrorColumn = XML_GetCurrentColumnNumber(pDom->pParser);
             }
         }
-
-        i = 1;      // success
     }
     else
         xmlSetError(pDom,
-                    (!arc) ? ERROR_DOM_INVALID_EXTERNAL_HANDLER : arc,
+                    ERROR_DOM_INVALID_EXTERNAL_HANDLER,
                     NULL,
                     FALSE);
@@ -2336,4 +2372,25 @@
  *      not all @expat features are supported yet.
  *
+ *      flParserFlags is any combination of the following:
+ *
+ *      --  DF_PARSECOMMENTS: XML @comments are to be returned in
+ *          the DOM tree. Otherwise they are discarded.
+ *
+ *      --  DF_PARSEDTD: add the @DTD of the document into the DOM tree
+ *          as well and validate the document, if a DTD was found.
+ *          Otherwise just parse and do not validate.
+ *
+ *          DF_PARSEDTD is required for external entities to work
+ *          also.
+ *
+ *      --  DF_FAIL_IF_NO_DTD: fail if no @DTD was found. Useful
+ *          if you want to enforce validation. @@todo
+ *
+ *      --  DF_DROP_WHITESPACE: discard all @whitespace for those
+ *          elements that can only have element content. Whitespace
+ *          will be preserved only for elements that can have
+ *          mixed content. -- If this flag is not set, all whitespace
+ *          is preserved.
+ *
  *      The following callbacks can be specified (any of these
  *      can be NULL):
@@ -2371,29 +2428,8 @@
  *              the int at index 0x94 to 0x00f6.
  *
- *      pvCallbackUser is a user parameter which is simply stored
- *      in the XMLDOM struct which is returned. Since the XMLDOM
- *      is passed to all the callbacks, you can access that pointer
- *      from them.
- *
- *      flParserFlags is any combination of the following:
- *
- *      --  DF_PARSECOMMENTS: XML @comments are to be returned in
- *          the DOM tree. Otherwise they are discarded.
- *
- *      --  DF_PARSEDTD: add the @DTD of the document into the DOM tree
- *          as well and validate the document, if a DTD was found.
- *          Otherwise just parse and do not validate.
- *
- *          DF_PARSEDTD is required for external entities to work
- *          also.
- *
- *      --  DF_FAIL_IF_NO_DTD: fail if no @DTD was found. Useful
- *          if you want to enforce validation. @@todo
- *
- *      --  DF_DROP_WHITESPACE: discard all @whitespace for those
- *          elements that can only have element content. Whitespace
- *          will be preserved only for elements that can have
- *          mixed content. -- If this flag is not set, all whitespace
- *          is preserved.
+ *      --  pvCallbackUser is a user parameter which is simply stored
+ *          in the XMLDOM struct which is returned. Since the XMLDOM
+ *          is passed to all the callbacks, you can access that pointer
+ *          from them.
  *
  *@@added V0.9.9 (2001-02-14) [umoeller]
@@ -2402,4 +2438,6 @@
 
 APIRET xmlCreateDOM(ULONG flParserFlags,            // in: DF_* parser flags
+                    const STATICSYSTEMID *paSystemIds, // in: array of STATICSYSTEMID's or NULL
+                    ULONG cSystemIds,                // in: array item count
                     PFNGETCPDATA pfnGetCPData,      // in: codepage callback or NULL
                     PFNEXTERNALHANDLER pfnExternalHandler, // in: external entity callback or NULL
@@ -2422,4 +2460,8 @@
         pDom->pfnExternalHandler = pfnExternalHandler;
         pDom->pvCallbackUser = pvCallbackUser;
+
+        // these added with V0.9.20 (2002-07-06) [umoeller]
+        pDom->paSystemIds = paSystemIds;
+        pDom->cSystemIds = cSystemIds;
 
         lstInit(&pDom->llElementStack,
@@ -2470,5 +2512,7 @@
                                           CommentHandler);
 
-                if (pfnExternalHandler)
+                if (    (pfnExternalHandler)
+                     || (cSystemIds)     // V0.9.20 (2002-07-06) [umoeller]
+                   )
                     XML_SetExternalEntityRefHandler(pDom->pParser,
                                                     ExternalEntityRefHandler);
Index: trunk/src/helpers/xstring.c
===================================================================
--- trunk/src/helpers/xstring.c	(revision 186)
+++ trunk/src/helpers/xstring.c	(revision 187)
@@ -34,4 +34,7 @@
  *         iterative appends, you can pre-allocate memory to
  *         avoid excessive reallocations.
+ *
+ *      These functions are also used internally by the
+ *      WarpIN BSString class (and related classes).
  *
  *      Usage:
@@ -139,4 +142,5 @@
 {
     memset(pxstr, 0, sizeof(XSTRING));
+
     if (ulPreAllocate)
     {
@@ -186,4 +190,5 @@
 {
     memset(pxstr, 0, sizeof(XSTRING));
+
     if (ulPreAllocate)
     {
@@ -362,4 +367,5 @@
     if (pxstr->psz)
         free(pxstr->psz);
+
     memset(pxstr, 0, sizeof(XSTRING));
 }
@@ -441,5 +447,5 @@
     // else: we have enough memory
 
-    return (pxstr->cbAllocated);
+    return pxstr->cbAllocated;
 }
 
@@ -485,5 +491,5 @@
         xstrInit(pxstr, ulPreAllocate);
 
-    return (pxstr);
+    return pxstr;
 }
 
@@ -542,5 +548,5 @@
 {
     if (!pxstr)
-        return (0);         // V0.9.9 (2001-02-14) [umoeller]
+        return 0;         // V0.9.9 (2001-02-14) [umoeller]
 
     xstrClear(pxstr);
@@ -556,5 +562,5 @@
     // else null string: cbAllocated and ulLength are 0 already
 
-    return (pxstr->ulLength);
+    return pxstr->ulLength;
 }
 
@@ -570,5 +576,5 @@
               PSZ pszNew)                   // in: heap PSZ to use
 {
-    return (xstrset2(pxstr, pszNew, 0));
+    return xstrset2(pxstr, pszNew, 0);
 }
 
@@ -621,9 +627,9 @@
 
 ULONG xstrcpy(PXSTRING pxstr,               // in/out: string
-              PCSZ pcszSource,       // in: source, can be NULL
+              PCSZ pcszSource,              // in: source, can be NULL
               ULONG ulSourceLength)         // in: length of pcszSource or 0
 {
     if (!pxstr)
-        return (0);         // V0.9.9 (2001-02-14) [umoeller]
+        return 0;         // V0.9.9 (2001-02-14) [umoeller]
 
     if (pcszSource)
@@ -647,5 +653,5 @@
                    pcszSource,
                    ulSourceLength);
-            *(pxstr->psz + ulSourceLength) = '\0';
+            pxstr->psz[ulSourceLength] = '\0';
                     // V0.9.9 (2001-02-16) [umoeller]
                     // we must do this or otherwise we require pcszSource
@@ -670,5 +676,5 @@
     pxstr->ulLength = ulSourceLength;
 
-    return (pxstr->ulLength);
+    return pxstr->ulLength;
 }
 
@@ -684,7 +690,7 @@
 {
     if (!pcstrSource)
-        return (0);
-
-    return (xstrcpy(pxstr, pcstrSource->psz, pcstrSource->ulLength));
+        return 0;
+
+    return xstrcpy(pxstr, pcstrSource->psz, pcstrSource->ulLength);
 }
 
@@ -758,5 +764,5 @@
                        ulSourceLength);
 
-                *(pxstr->psz + pxstr->ulLength + ulSourceLength) = '\0';
+                pxstr->psz[pxstr->ulLength + ulSourceLength] = '\0';
                         // V0.9.9 (2001-02-16) [umoeller]
                         // we must do this or otherwise we require pcszSource
@@ -774,5 +780,5 @@
     }
 
-    return (ulrc);
+    return ulrc;
 }
 
@@ -816,5 +822,4 @@
     if ((pxstr) && (c))
     {
-        // ULONG   ulSourceLength = 1;
         // 1) memory management
         xstrReserve(pxstr,
@@ -833,5 +838,5 @@
     } // end if ((pxstr) && (c))
 
-    return (ulrc);
+    return ulrc;
 }
 
@@ -847,9 +852,9 @@
 {
     if (!pcstrSource)
-        return (0);
-
-    return (xstrcat(pxstr,
-                    pcstrSource->psz,
-                    pcstrSource->ulLength));
+        return 0;
+
+    return xstrcat(pxstr,
+                   pcstrSource->psz,
+                   pcstrSource->ulLength);
 }
 
@@ -1023,5 +1028,5 @@
     } // end checks
 
-    return (ulrc);
+    return ulrc;
 }
 
@@ -1094,5 +1099,5 @@
     }
 
-    return (pReturn);
+    return pReturn;
 }
 
@@ -1210,5 +1215,5 @@
     } // end if ((pxstr) && (pstrSearch) && (pstrReplace))
 
-    return (ulrc);
+    return ulrc;
 }
 
@@ -1246,5 +1251,5 @@
     xstrInitSet(&xstrReplace, (PSZ)pcszReplace);
 
-    return (xstrFindReplace(pxstr, pulOfs, &xstrFind, &xstrReplace, ShiftTable, &fRepeat));
+    return xstrFindReplace(pxstr, pulOfs, &xstrFind, &xstrReplace, ShiftTable, &fRepeat);
 }
 
@@ -1325,5 +1330,5 @@
  */
 
-ULONG xstrEncode(PXSTRING pxstr,            // in/out: string to convert
+ULONG xstrEncode(PXSTRING pxstr,     // in/out: string to convert
                  PCSZ pcszEncode)    // in: characters to encode (e.g. "%,();=")
 {
@@ -1383,5 +1388,5 @@
     }
 
-    return (ulrc);
+    return ulrc;
 }
 
@@ -1464,5 +1469,5 @@
     }
 
-    return (ulrc);
+    return ulrc;
 }
 
@@ -1476,5 +1481,5 @@
 ULONG xstrDecode(PXSTRING pxstr)
 {
-    return (xstrDecode2(pxstr, '%'));
+    return xstrDecode2(pxstr, '%');
 }
 
@@ -1683,5 +1688,5 @@
     printf("New string is: \"%s\" (%d/%d/%d)\n", str.psz, str.ulLength, str.cbAllocated, str.ulDelta);
 
-    return (0);
+    return 0;
 } */
 
