Changeset 39
- Timestamp:
- Feb 23, 2001, 7:50:07 AM (24 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/expat/expat.h
r38 r39 624 624 enum XML_ParamEntityParsing parsing); 625 625 626 #define ERROR_EXPAT_NONE 0 // explicitly added V0.9.9 (2001-02-14) [umoeller]627 628 626 #define ERROR_XML_FIRST 40000 // first error code used 629 627 630 628 typedef enum _XMLERROR 631 629 { 630 ERROR_EXPAT_NONE = 0, 632 631 // ERROR_EXPAT_NONE, // removed to adhere with APIRET V0.9.9 (2001-02-14) [umoeller] 633 632 ERROR_EXPAT_NO_MEMORY = ERROR_XML_FIRST, -
trunk/include/helpers/xml.h
r38 r39 52 52 // more than one declaration for an attribute type 53 53 ERROR_DOM_UNDECLARED_ATTRIBUTE, 54 ERROR_ELEMENT_CANNOT_HAVE_CONTENT, 55 // element was declared "empty" and contains text anyway, 56 // or was declared "children" and contains something other 57 // than whitespace 58 ERROR_DOM_INVALID_ATTRIB_VALUE, 59 ERROR_DOM_REQUIRED_ATTRIBUTE_MISSING, 60 ERROR_DOM_SUBELEMENT_IN_EMPTY_ELEMENT, 54 61 // END MATCHING ERROR MESSAGES (xmlDescribeError) 55 62 … … 60 67 // additional DOM errors 61 68 ERROR_DOM_NODETYPE_NOT_SUPPORTED, 62 // invalid node type in xmlCreate Node69 // invalid node type in xmlCreateDomNode 63 70 ERROR_DOM_NO_DOCUMENT, 64 71 // cannot find document node … … 80 87 typedef enum _NODEBASETYPE 81 88 { 89 TYPE_UNKNOWN, 90 82 91 DOMNODE_ELEMENT, // node is a DOM ELEMENT 83 92 DOMNODE_ATTRIBUTE, // node is a DOM ATTRIBUTE … … 219 228 NODEBASE NodeBase; 220 229 221 // PXSTRING pstrNodeName; // ptr is NULL if none222 230 PXSTRING pstrNodeValue; // ptr is NULL if none 223 231 … … 270 278 271 279 TREE *AttribDeclBasesTree; 272 // tree with pointers to _CMATTRIBUTEDE DECLBASE nodes280 // tree with pointers to _CMATTRIBUTEDECLBASE nodes 273 281 274 282 } DOMDOCTYPENODE, *PDOMDOCTYPENODE; … … 291 299 } DOMDOCUMENTNODE, *PDOMDOCUMENTNODE; 292 300 293 APIRET xmlCreateNode(PDOMNODE pParentNode, 294 ULONG ulNodeType, 295 PDOMNODE *ppNew); 296 297 ULONG xmlDeleteNode(PDOMNODE pNode); 301 APIRET xmlCreateDomNode(PDOMNODE pParentNode, 302 NODEBASETYPE ulNodeType, 303 const char *pcszNodeName, 304 ULONG ulNodeNameLength, 305 PDOMNODE *ppNew); 306 307 VOID xmlDeleteNode(PNODEBASE pNode); 298 308 299 309 /* ****************************************************************** … … 328 338 typedef struct _CMELEMENTPARTICLE 329 339 { 330 NODEBASE CMNode;// has TREE* as first item in turn331 // NODEBASE.ul CMNodeType may be one of these:340 NODEBASE NodeBase; // has TREE* as first item in turn 341 // NODEBASE.ulNodeType may be one of these: 332 342 // -- ELEMENTPARTICLE_EMPTY: 333 343 // ulRepeater will be XML_CQUANT_NONE, rest is NULL … … 354 364 // -- XML_CQUANT_PLUS 355 365 366 struct _CMELEMENTPARTICLE *pParentParticle; // or NULL if this is in the 367 // CMELEMENTDECLNODE 368 356 369 PLINKLIST pllSubNodes; 357 370 // linked list of sub-CMELEMENTPARTICLE structs … … 378 391 * 379 392 * For the "root" element declaration in the DTD, 380 * Particle.NODEBASE.ul CMNodeType will always be one of the following:393 * Particle.NODEBASE.ulNodeType will always be one of the following: 381 394 * 382 395 * -- ELEMENTPARTICLE_EMPTY: element must be empty. … … 438 451 *@@ CMATTRIBUTEDECL: 439 452 * single attribute declaration within the attribute 440 * declarations tree in _CMATTRIBUTEDE DECLBASE.453 * declarations tree in _CMATTRIBUTEDECLBASE. 441 454 * 442 455 *@@added V0.9.9 (2001-02-16) [umoeller] … … 445 458 typedef struct _CMATTRIBUTEDECL 446 459 { 447 NODEBASE CMNode; // has TREE* as first item in turn 448 // CMNode.strName is attribute name 449 450 // XSTRING strType; 460 NODEBASE NodeBase; // has TREE* as first item in turn 461 // NodeBase.strName is attribute name 451 462 452 463 ATTRIBTYPE ulAttrType; … … 463 474 TREE *ValuesTree; 464 475 // enumeration of allowed values, if CMAT_ENUM; 465 // tree entries are plain NODEBASEs 476 // tree entries are plain NODEBASEs with 477 // ATTRIBUTE_DECLARATION_ENUM type 466 478 467 479 ATTRIBCONSTRAINT ulConstraint; … … 479 491 480 492 /* 481 *@@ CMATTRIBUTEDE DECLBASE:493 *@@ CMATTRIBUTEDECLBASE: 482 494 * representation of an @attribute_declaration. 483 495 * … … 493 505 */ 494 506 495 typedef struct _CMATTRIBUTEDE DECLBASE496 { 497 NODEBASE CMNode; // has TREE* as first item in turn498 // CMNode.strName is element name507 typedef struct _CMATTRIBUTEDECLBASE 508 { 509 NODEBASE NodeBase; // has TREE* as first item in turn 510 // NodeBase.strName is element name 499 511 500 512 TREE *AttribDeclsTree; 501 513 // root of tree with CMATTRIBUTEDECL; 502 514 503 } CMATTRIBUTEDE DECLBASE, *PCMATTRIBUTEDEDECLBASE;515 } CMATTRIBUTEDECLBASE, *PCMATTRIBUTEDECLBASE; 504 516 505 517 /* … … 513 525 typedef struct _CMENTITYDECLNODE 514 526 { 515 NODEBASE CMNode;527 NODEBASE NodeBase; 516 528 } CMENTITYDECLNODE, *PCMENTITYDECLNODE; 517 529 … … 526 538 typedef struct _CMNOTATIONDECLNODE 527 539 { 528 NODEBASE CMNode;540 NODEBASE NodeBase; 529 541 } CMNOTATIONDECLNODE, *PCMNOTATIONDECLNODE; 530 542 … … 568 580 // expat parser instance 569 581 570 LINKLIST ll Stack;582 LINKLIST llElementStack; 571 583 // stack for maintaining the current items; 572 // these point to the NODERECORDs (noauto-free)584 // these point to DOMSTACKITEMs (auto-free) 573 585 574 586 PDOMNODE pLastWasTextNode; 575 587 576 PCMATTRIBUTEDE DECLBASE pAttListDeclCache;588 PCMATTRIBUTEDECLBASE pAttListDeclCache; 577 589 // cache for attribute declarations according 578 590 // to attdecl element name … … 595 607 const XSTRING *pstrElementName); 596 608 597 PCMATTRIBUTEDE DECLBASE xmlFindAttribDeclBase(PXMLDOM pDom,609 PCMATTRIBUTEDECLBASE xmlFindAttribDeclBase(PXMLDOM pDom, 598 610 const XSTRING *pstrElementName); 599 611 600 612 PCMATTRIBUTEDECL xmlFindAttribDecl(PXMLDOM pDom, 601 613 const XSTRING *pstrElementName, 602 const XSTRING *pstrAttribName); 614 const XSTRING *pstrAttribName, 615 PCMATTRIBUTEDECLBASE *ppAttribDeclBase); 603 616 604 617 #endif -
trunk/include/setup.h
r35 r39 16 16 #define XWPENTRY _Optlink 17 17 #endif 18 19 #error This file shouldn't be included.20 18 21 19 /************************************************************* -
trunk/src/helpers/tree.c
r38 r39 922 922 * as a data pointer to some structure for whatever you like. 923 923 * 924 * WARNING: This function recurses and can use up a lot of 925 * stack. For very deep trees, traverse the tree using 926 * treeFirst and treeNext instead. See treeNext for a sample. 927 * 924 928 * "method" specifies in which order the nodes are traversed. 925 929 * This can be: … … 936 940 int method) // in: traversal mode 937 941 { 938 if ( (!tree)939 ||(tree == TREE_NULL))942 if ( (!tree) 943 || (tree == TREE_NULL)) 940 944 return; 941 945 … … 963 967 *@@ treeFirst: 964 968 * finds and returns the first node in a (sub-)tree. 969 * 970 * See treeNext for a sample usage for traversing a tree. 965 971 */ 966 972 … … 970 976 *current; 971 977 972 if ((!tree) 973 || (tree == TREE_NULL)) 978 if ( (!tree) 979 || (tree == TREE_NULL) 980 ) 974 981 return NULL; 975 982 … … 991 998 *current; 992 999 993 if ( (!tree)994 ||(tree == TREE_NULL))1000 if ( (!tree) 1001 || (tree == TREE_NULL)) 995 1002 return NULL; 996 1003 … … 1005 1012 *@@ treeNext: 1006 1013 * finds and returns the next node in a tree. 1014 * 1015 * Example for traversing a whole tree if you don't 1016 * want to use treeTraverse: 1017 * 1018 + TREE *TreeRoot; 1019 + ... 1020 + TREE* pNode = treeFirst(TreeRoot); 1021 + while (pNode) 1022 + { 1023 + ... 1024 + pNode = treeNext(pNode); 1025 + } 1026 * 1027 * This runs through the tree items in sorted order. 1007 1028 */ 1008 1029 … … 1013 1034 *child; 1014 1035 1015 if ((!tree) 1016 || (tree == TREE_NULL)) 1036 if ( (!tree) 1037 || (tree == TREE_NULL) 1038 ) 1017 1039 return NULL; 1018 1040 … … 1024 1046 current = tree; 1025 1047 child = TREE_NULL; 1026 while ((current->parent) 1027 && (current->right == child)) 1048 while ( (current->parent) 1049 && (current->right == child) 1050 ) 1028 1051 { 1029 1052 child = current; … … 1048 1071 *child; 1049 1072 1050 if ( (!tree)1051 ||(tree == TREE_NULL))1073 if ( (!tree) 1074 || (tree == TREE_NULL)) 1052 1075 return NULL; 1053 1076 -
trunk/src/helpers/xml.c
r38 r39 62 62 * 63 63 * However, we do implement node management as in the standard. 64 * See xmlCreate Node and xmlDeleteNode.64 * See xmlCreateDomNode and xmlDeleteNode. 65 65 * 66 66 * The main entry point into this is xmlCreateDOM. See remarks 67 * there for details.67 * there for how this will be typically used. 68 68 * 69 69 * <B>Validation</B> … … 72 72 * In other words, expat is a non-validating XML processor. 73 73 * 74 * By contrast, this pseudo-DOM implementation can validate. To 75 * do this, you must pass DF_PARSEDTD to xmlCreateDOM (otherwise 76 * the @DTD entries will not be stored in the DOM nodes). This 77 * will not validate yet; to do this, explicitly call xmlValidate. 74 * By contrast, this pseudo-DOM implementation can validate to 75 * a certain extent. 76 * 77 * -- If you pass DF_PARSEDTD to xmlCreateDOM, the DTD will be 78 * parsed and the document will be validated against it. 79 * Validation is working as far as elements and attributes 80 * are checked for proper nesting. However, we cannot fully 81 * check for proper ordering etc. in (children) mode of 82 * @element_declarations. This will only check for whether 83 * elements may appear in another element at all -- not for 84 * the correct order. 85 * 86 * -- Otherwise the @DTD entries will not be stored in the DOM 87 * nodes, and no validation occurs. Still, if a DTD exists, 88 * @expat will insert attributes that have a default value 89 * in their @attribute declaraion and have not been specified. 78 90 * 79 91 *@@header "helpers\xml.h" … … 104 116 #include <stdlib.h> 105 117 #include <string.h> 118 #include <stdio.h> 106 119 107 120 #include "setup.h" // code generation and debugging options … … 134 147 135 148 /* 136 *@@ Compare CMNodeNodes:137 * tree comparison func for CMNodes.149 *@@ CompareNodeBaseNodes: 150 * tree comparison func for NodeBases. 138 151 * This works for all trees which contain structures 139 152 * whose first item is a _NODEBASE because NODEBASE's first … … 151 164 */ 152 165 153 int CompareCMNodeNodes(TREE *t1,154 TREE *t2)166 int XWPENTRY CompareNodeBaseNodes(TREE *t1, 167 TREE *t2) 155 168 { 156 169 PNODEBASE p1 = (PNODEBASE)t1, … … 160 173 161 174 /* 162 *@@ Compare CMNodeNodes:175 *@@ CompareNodeBaseNodes: 163 176 * tree comparison func for element declarations. 164 177 * Used to find nodes in _DOMDOCTYPENODE.ElementDeclsTree. … … 167 180 */ 168 181 169 int CompareCMNodeData(TREE *t1,170 void *pData)182 int XWPENTRY CompareNodeBaseData(TREE *t1, 183 void *pData) 171 184 { 172 185 PNODEBASE p1 = (PNODEBASE)t1; … … 175 188 176 189 /* 177 *@@ xmlCreateNode: 190 *@@ xmlCreateNodeBase: 191 * creates a new NODEBASE node. 192 * 193 * Gets called from xmlCreateDomNode also to create 194 * a DOMNODE, since that in turn has a NODEBASE. 195 * 196 *@@added V0.9.9 (2001-02-16) [umoeller] 197 */ 198 199 APIRET xmlCreateNodeBase(NODEBASETYPE ulNodeType, // in: node type 200 ULONG cb, // in: size of struct 201 const char *pcszNodeName, // in: node name or NULL 202 ULONG ulNodeNameLength, // in: node name length 203 // or 0 to run strlen(pcszNodeName) 204 PNODEBASE *ppNew) // out: new node 205 { 206 APIRET arc = NO_ERROR; 207 PNODEBASE pNewNode = (PNODEBASE)malloc(cb); 208 209 if (!pNewNode) 210 arc = ERROR_NOT_ENOUGH_MEMORY; 211 else 212 { 213 memset(pNewNode, 0, cb); 214 pNewNode->ulNodeType = ulNodeType; 215 216 xstrInit(&pNewNode->strNodeName, 0); 217 if (pcszNodeName) 218 xstrcpy(&pNewNode->strNodeName, 219 pcszNodeName, 220 ulNodeNameLength); // if 0, xstrcpy will do strlen() 221 222 223 *ppNew = pNewNode; 224 } 225 226 return (arc); 227 } 228 229 /* 230 *@@ xmlDeleteNode: 231 * deletes a NODEBASE and frees memory that was 232 * associated with its members. 233 * 234 * NOTE: If you call this for derived types, call 235 * this LAST, after you have cleared additional 236 * members. After calling this, pNode is no longer 237 * valid. 238 * 239 *@@added V0.9.9 (2001-02-16) [umoeller] 240 */ 241 242 VOID xmlDeleteNode(PNODEBASE pNode) 243 { 244 if (pNode) 245 { 246 PLISTNODE pNodeThis; 247 PDOMNODE pDomNode = NULL; 248 249 LINKLIST llDeleteNodes; // list that nodes to be deleted 250 // can be appended to 251 PLISTNODE pDelNode; 252 lstInit(&llDeleteNodes, FALSE); 253 254 // now handle special types and their allocations 255 switch (pNode->ulNodeType) 256 { 257 case DOMNODE_ELEMENT: 258 { 259 PDOMNODE pAttrib; 260 261 pDomNode = (PDOMNODE)pNode; 262 263 // delete all attribute nodes 264 pAttrib = (PDOMNODE)treeFirst(pDomNode->AttributesMap); 265 while (pAttrib) 266 { 267 // call delete recursively 268 xmlDeleteNode((PNODEBASE)pAttrib); 269 // this will remove pAttrib from pNode's attrib 270 // tree and rebalance the tree; treeNext will 271 // still work #### noooooo 272 pAttrib = (PDOMNODE)treeNext((TREE*)pAttrib); 273 } 274 break; } 275 276 case DOMNODE_ATTRIBUTE: 277 case DOMNODE_TEXT: 278 case DOMNODE_PROCESSING_INSTRUCTION: 279 case DOMNODE_COMMENT: 280 case DOMNODE_DOCUMENT: 281 pDomNode = (PDOMNODE)pNode; 282 break; 283 284 case DOMNODE_DOCUMENT_TYPE: 285 { 286 PDOMDOCTYPENODE pDocType = (PDOMDOCTYPENODE)pNode; 287 PCMELEMENTDECLNODE pElDecl; 288 PCMATTRIBUTEDECLBASE pAttrDeclBase; 289 290 pDomNode = (PDOMNODE)pNode; 291 292 pElDecl = (PCMELEMENTDECLNODE)treeFirst(pDocType->ElementDeclsTree); 293 while (pElDecl) 294 { 295 lstAppendItem(&llDeleteNodes, pElDecl); 296 pElDecl = (PCMELEMENTDECLNODE)treeNext((TREE*)pElDecl); 297 } 298 299 pAttrDeclBase = (PCMATTRIBUTEDECLBASE)treeFirst(pDocType->AttribDeclBasesTree); 300 while (pAttrDeclBase) 301 { 302 lstAppendItem(&llDeleteNodes, pAttrDeclBase); 303 pAttrDeclBase = (PCMATTRIBUTEDECLBASE)treeNext((TREE*)pAttrDeclBase); 304 } 305 306 xstrClear(&pDocType->strPublicID); 307 xstrClear(&pDocType->strSystemID); 308 break; } 309 310 case ELEMENTPARTICLE_EMPTY: 311 case ELEMENTPARTICLE_ANY: 312 case ELEMENTPARTICLE_MIXED: 313 case ELEMENTPARTICLE_CHOICE: 314 case ELEMENTPARTICLE_SEQ: 315 case ELEMENTPARTICLE_NAME: 316 { 317 PCMELEMENTPARTICLE pp = (PCMELEMENTPARTICLE)pNode; 318 if (pp->pllSubNodes) 319 { 320 pDelNode = lstQueryFirstNode(pp->pllSubNodes); 321 while (pDelNode) 322 { 323 PCMELEMENTPARTICLE 324 pParticle = (PCMELEMENTPARTICLE)pDelNode->pItemData; 325 xmlDeleteNode((PNODEBASE)pParticle); 326 // treeDelete(pp-> ### 327 pDelNode = pDelNode->pNext; 328 } 329 } 330 break; } 331 332 // case ATTRIBUTE_DECLARATION_ENUM: // this is a plain NODEBASE 333 334 case ATTRIBUTE_DECLARATION: 335 { 336 PCMATTRIBUTEDECL pDecl = (PCMATTRIBUTEDECL)pNode; 337 break; } 338 339 case ATTRIBUTE_DECLARATION_BASE: 340 break; 341 } 342 343 if (pDomNode) 344 { 345 // recurse into child nodes 346 while (pNodeThis = lstQueryFirstNode(&pDomNode->llChildren)) 347 // recurse!! 348 xmlDeleteNode((PNODEBASE)(pNodeThis->pItemData)); 349 // this updates llChildren 350 351 if (pDomNode->pParentNode) 352 { 353 // node has a parent: 354 if (pNode->ulNodeType == DOMNODE_ATTRIBUTE) 355 // this is an attribute: 356 // remove from parent's attributes map 357 treeDelete(&pDomNode->pParentNode->AttributesMap, 358 (TREE*)pNode); 359 else 360 // remove this node from the parent's list 361 // of child nodes before deleting this node 362 lstRemoveItem(&pDomNode->pParentNode->llChildren, 363 pNode); 364 365 pDomNode->pParentNode = NULL; 366 } 367 368 xstrFree(pDomNode->pstrNodeValue); 369 lstClear(&pDomNode->llChildren); 370 } 371 372 pDelNode = lstQueryFirstNode(&llDeleteNodes); 373 while (pDelNode) 374 { 375 PNODEBASE pNodeBase = (PNODEBASE)pDelNode->pItemData; 376 xmlDeleteNode(pNodeBase); 377 pDelNode = pDelNode->pNext; 378 } 379 380 lstClear(&llDeleteNodes); 381 382 xstrClear(&pNode->strNodeName); 383 free(pNode); 384 } 385 } 386 387 /* 388 *@@ xmlCreateDomNode: 178 389 * creates a new DOMNODE with the specified 179 390 * type and parent. Other than that, the … … 198 409 */ 199 410 200 APIRET xmlCreateNode(PDOMNODE pParentNode, // in: parent node or NULL if root 201 ULONG ulNodeType, // in: DOMNODE_* type 202 PDOMNODE *ppNew) // out: new node 411 APIRET xmlCreateDomNode(PDOMNODE pParentNode, // in: parent node or NULL if root 412 NODEBASETYPE ulNodeType, // in: DOMNODE_* type 413 const char *pcszNodeName, // in: node name or NULL 414 ULONG ulNodeNameLength, // in: node name length 415 // or 0 to run strlen(pcszNodeName) 416 PDOMNODE *ppNew) // out: new node 203 417 { 204 418 PDOMNODE pNewNode = NULL; … … 222 436 } 223 437 224 pNewNode = (PDOMNODE)malloc(cb); 225 226 if (!pNewNode) 227 arc = ERROR_NOT_ENOUGH_MEMORY; 228 else 229 { 230 memset(pNewNode, 0, cb); 231 pNewNode->NodeBase.ulNodeType = ulNodeType; 232 xstrInit(&pNewNode->NodeBase.strNodeName, 0); 438 arc = xmlCreateNodeBase(ulNodeType, 439 cb, 440 pcszNodeName, 441 ulNodeNameLength, 442 (PNODEBASE*)&pNewNode); 443 if (arc == NO_ERROR) 444 { 233 445 pNewNode->pParentNode = pParentNode; 234 446 … … 242 454 // add to parent's attributes list 243 455 if (treeInsertNode(&pParentNode->AttributesMap, 244 (TREE*)pNewNode,245 Compare CMNodeNodes,456 &pNewNode->NodeBase.Tree, 457 CompareNodeBaseNodes, 246 458 FALSE) // no duplicates 247 459 == TREE_DUPLICATE) … … 283 495 284 496 return (arc); 285 }286 287 /*288 *@@ xmlDeleteNode:289 * deletes the specified node and updates the290 * parent node's children list.291 *292 * If the node has child nodes, all of them are deleted293 * as well. This recurses, if necessary.294 *295 * As a result, if the node is a document node, this296 * deletes an entire document, including all of its297 * child nodes.298 *299 * This returns the following errors:300 *301 * -- ERROR_DOM_NOT_FOUND302 */303 304 APIRET xmlDeleteNode(PDOMNODE pNode)305 {306 ULONG ulrc = 0;307 308 if (!pNode)309 {310 ulrc = ERROR_INVALID_PARAMETER;311 }312 else313 {314 PLISTNODE pNodeThis;315 316 // recurse into child nodes317 while (pNodeThis = lstQueryFirstNode(&pNode->llChildren))318 // recurse!!319 xmlDeleteNode((PDOMNODE)(pNodeThis->pItemData));320 // this updates llChildren321 322 // recurse into attribute nodes323 // while (pNodeThis = lstQueryFirstNode(&pNode->llAttributes))324 // recurse!! ###325 // xmlDeleteNode((PDOMNODE)(pNodeThis->pItemData));326 // this updates llAttributes327 328 if (pNode->pParentNode)329 {330 // node has a parent:331 if (pNode->NodeBase.ulNodeType == DOMNODE_ATTRIBUTE)332 // this is an attribute:333 // remove from parent's attributes map334 treeDelete(&pNode->pParentNode->AttributesMap,335 (TREE*)pNode);336 else337 // remove this node from the parent's list338 // of child nodes before deleting this node339 lstRemoveItem(&pNode->pParentNode->llChildren,340 pNode);341 342 pNode->pParentNode = NULL;343 }344 345 xstrClear(&pNode->NodeBase.strNodeName);346 xstrFree(pNode->pstrNodeValue);347 348 lstClear(&pNode->llChildren);349 // lstClear(&pNode->llAttributes); ###350 351 free(pNode);352 }353 354 return (ulrc);355 497 } 356 498 … … 438 580 "Duplicate element declaration", 439 581 "Duplicate attribute declaration", 440 "Undeclared attribute in element" 582 "Undeclared attribute in element", 583 "Element cannot have content", 584 "Invalid attribute value", 585 "Required attribute is missing", 586 "Subelement in empty element" 441 587 }; 442 588 … … 500 646 { 501 647 PDOMNODE pNew = NULL; 502 APIRET arc = xmlCreate Node(pParent,648 APIRET arc = xmlCreateDomNode(pParent, 503 649 DOMNODE_ELEMENT, 650 pcszElement, 651 0, 504 652 &pNew); 505 653 506 654 if (arc == NO_ERROR) 507 {508 xstrcpy(&pNew->NodeBase.strNodeName, pcszElement, 0);509 510 655 *ppNew = pNew; 511 }512 656 513 657 return (arc); … … 524 668 * This returns the following errors: 525 669 * 526 * -- Error codes from xmlCreate Node.670 * -- Error codes from xmlCreateDomNode. 527 671 * 528 672 * -- ERROR_DOM_NO_ELEMENT: pElement is invalid or does … … 546 690 { 547 691 PDOMNODE pNew = NULL; 548 arc = xmlCreate Node(pElement, // this takes care of adding to the list692 arc = xmlCreateDomNode(pElement, // this takes care of adding to the list 549 693 DOMNODE_ATTRIBUTE, 694 pcszName, 695 0, 550 696 &pNew); 551 697 if (arc == NO_ERROR) 552 698 { 553 xstrcpy(&pNew->NodeBase.strNodeName, pcszName, 0);554 699 pNew->pstrNodeValue = xstrCreate(0); 555 700 xstrcpy(pNew->pstrNodeValue, pcszValue, 0); … … 579 724 { 580 725 PDOMNODE pNew = NULL; 581 APIRET arc = xmlCreateNode(pParent, 582 DOMNODE_TEXT, 583 &pNew); 726 APIRET arc = xmlCreateDomNode(pParent, 727 DOMNODE_TEXT, 728 NULL, 729 0, 730 &pNew); 584 731 if (arc == NO_ERROR) 585 732 { … … 588 735 { 589 736 arc = ERROR_NOT_ENOUGH_MEMORY; 590 xmlDeleteNode( pNew);737 xmlDeleteNode((PNODEBASE)pNew); 591 738 } 592 739 else … … 617 764 { 618 765 PDOMNODE pNew = NULL; 619 APIRET arc = xmlCreate Node(pParent,766 APIRET arc = xmlCreateDomNode(pParent, 620 767 DOMNODE_COMMENT, 768 NULL, 769 0, 621 770 &pNew); 622 771 if (arc == NO_ERROR) … … 644 793 { 645 794 PDOMNODE pNew = NULL; 646 APIRET arc = xmlCreate Node(pParent,795 APIRET arc = xmlCreateDomNode(pParent, 647 796 DOMNODE_PROCESSING_INSTRUCTION, 797 pcszTarget, 798 0, 648 799 &pNew); 649 800 if (arc == NO_ERROR) 650 801 { 651 xstrcpy(&pNew->NodeBase.strNodeName, pcszTarget, 0);652 802 pNew->pstrNodeValue = xstrCreate(0); 653 803 xstrcpy(pNew->pstrNodeValue, pcszData, 0); … … 683 833 // create doctype node 684 834 PDOMDOCTYPENODE pNew = NULL; 685 arc = xmlCreate Node((PDOMNODE)pDocumentNode,835 arc = xmlCreateDomNode((PDOMNODE)pDocumentNode, 686 836 DOMNODE_DOCUMENT_TYPE, 837 NULL, 838 0, 687 839 (PDOMNODE*)&pNew); 688 840 … … 764 916 { 765 917 case XML_CTYPE_EMPTY: // that's easy 766 pParticle-> CMNode.ulNodeType = ELEMENTPARTICLE_EMPTY;918 pParticle->NodeBase.ulNodeType = ELEMENTPARTICLE_EMPTY; 767 919 break; 768 920 769 921 case XML_CTYPE_ANY: // that's easy 770 pParticle-> CMNode.ulNodeType = ELEMENTPARTICLE_ANY;922 pParticle->NodeBase.ulNodeType = ELEMENTPARTICLE_ANY; 771 923 break; 772 924 773 925 case XML_CTYPE_NAME: // that's easy 774 pParticle-> CMNode.ulNodeType = ELEMENTPARTICLE_NAME;775 xstrInitCopy(&pParticle-> CMNode.strNodeName, pModel->name, 0);926 pParticle->NodeBase.ulNodeType = ELEMENTPARTICLE_NAME; 927 xstrInitCopy(&pParticle->NodeBase.strNodeName, pModel->name, 0); 776 928 treeInsertNode(ppElementNamesTree, 777 &pParticle-> CMNode.Tree,778 Compare CMNodeNodes,929 &pParticle->NodeBase.Tree, 930 CompareNodeBaseNodes, 779 931 TRUE); // allow duplicates here 780 932 break; 781 933 782 934 case XML_CTYPE_MIXED: 783 pParticle-> CMNode.ulNodeType = ELEMENTPARTICLE_MIXED;935 pParticle->NodeBase.ulNodeType = ELEMENTPARTICLE_MIXED; 784 936 break; 785 937 786 938 case XML_CTYPE_CHOICE: 787 pParticle-> CMNode.ulNodeType = ELEMENTPARTICLE_CHOICE;939 pParticle->NodeBase.ulNodeType = ELEMENTPARTICLE_CHOICE; 788 940 break; 789 941 790 942 case XML_CTYPE_SEQ: 791 pParticle-> CMNode.ulNodeType = ELEMENTPARTICLE_SEQ;943 pParticle->NodeBase.ulNodeType = ELEMENTPARTICLE_SEQ; 792 944 break; 793 945 } … … 806 958 { 807 959 PXMLCONTENT pSubModel = &pModel->children[ul]; 808 PCMELEMENTPARTICLE pSubNew 809 = (PCMELEMENTPARTICLE)malloc(sizeof(*pSubNew)); 810 if (!pSubNew) 811 arc = ERROR_NOT_ENOUGH_MEMORY; 812 else 960 PCMELEMENTPARTICLE pSubNew = NULL; 961 arc = xmlCreateNodeBase(TYPE_UNKNOWN, // node type... for now 962 sizeof(CMELEMENTPARTICLE), 963 0, 964 0, 965 (PNODEBASE*)&pSubNew); 966 if (!arc) 813 967 { 814 memset(pSubNew, 0, sizeof(*pSubNew));815 816 968 arc = SetupParticleAndSubs(pSubNew, 817 969 pSubModel, … … 819 971 820 972 if (!arc) 973 { 821 974 // no error: append sub-particle to this particle's 822 975 // children list 823 976 lstAppendItem(pParticle->pllSubNodes, 824 977 pSubNew); 978 // and store this particle as the parent in the 979 // sub-particle 980 pSubNew->pParentParticle = pParticle; 981 } 825 982 } 826 983 … … 847 1004 { 848 1005 APIRET arc = NO_ERROR; 849 PCMELEMENTDECLNODE pNew = (PCMELEMENTDECLNODE)malloc(sizeof(*pNew)); 850 if (!pNew) 851 arc = ERROR_NOT_ENOUGH_MEMORY; 852 else 853 { 854 memset(pNew, 0, sizeof(CMELEMENTDECLNODE)); 855 856 // pNew->Particle.CMNode.ulNodeType = ELEMENT_DECLARATION; 857 858 xstrcpy(&pNew->Particle.CMNode.strNodeName, pcszName, 0); 859 1006 PCMELEMENTDECLNODE pNew = NULL; 1007 1008 arc = xmlCreateNodeBase(TYPE_UNKNOWN, // for now 1009 sizeof(CMELEMENTDECLNODE), 1010 pcszName, 1011 0, 1012 (PNODEBASE*)&pNew); 1013 1014 if (!arc) 1015 { 860 1016 treeInit(&pNew->ParticleNamesTree); 861 1017 … … 893 1049 ) 894 1050 { 895 pElementDecl = treeFindEQData(&pDocTypeNode->ElementDeclsTree, 1051 pElementDecl = (PCMELEMENTDECLNODE)treeFindEQData( 1052 &pDocTypeNode->ElementDeclsTree, 896 1053 (void*)pstrElementName->psz, 897 Compare CMNodeData);1054 CompareNodeBaseData); 898 1055 } 899 1056 … … 903 1060 /* 904 1061 *@@ xmlFindAttribDeclBase: 905 * returns the _CMATTRIBUTEDE DECLBASE for the specified1062 * returns the _CMATTRIBUTEDECLBASE for the specified 906 1063 * element name, or NULL if none exists. 907 1064 * … … 913 1070 */ 914 1071 915 PCMATTRIBUTEDE DECLBASE xmlFindAttribDeclBase(PXMLDOM pDom,1072 PCMATTRIBUTEDECLBASE xmlFindAttribDeclBase(PXMLDOM pDom, 916 1073 const XSTRING *pstrElementName) 917 1074 { 918 PCMATTRIBUTEDE DECLBASE pAttribDeclBase = NULL;1075 PCMATTRIBUTEDECLBASE pAttribDeclBase = NULL; 919 1076 920 1077 PDOMDOCTYPENODE pDocTypeNode = pDom->pDocTypeNode; … … 924 1081 ) 925 1082 { 926 pAttribDeclBase = treeFindEQData(&pDocTypeNode->AttribDeclBasesTree, 927 (void*)pstrElementName->psz, 928 CompareCMNodeData); 1083 pAttribDeclBase = (PCMATTRIBUTEDECLBASE)treeFindEQData( 1084 &pDocTypeNode->AttribDeclBasesTree, 1085 (void*)pstrElementName->psz, 1086 CompareNodeBaseData); 929 1087 } 930 1088 … … 942 1100 PCMATTRIBUTEDECL xmlFindAttribDecl(PXMLDOM pDom, 943 1101 const XSTRING *pstrElementName, 944 const XSTRING *pstrAttribName) 1102 const XSTRING *pstrAttribName, 1103 PCMATTRIBUTEDECLBASE *ppAttribDeclBase) 1104 // in/out: attr decl base cache; 1105 // the pointer pointed to by this 1106 // must be NULL on the first call 945 1107 { 946 1108 PCMATTRIBUTEDECL pAttribDecl = NULL; 947 1109 if (pstrElementName && pstrAttribName) 948 1110 { 949 PCMATTRIBUTEDEDECLBASE pAttribDeclBase = xmlFindAttribDeclBase(pDom, 950 pstrElementName); 951 if (pAttribDeclBase) 952 { 953 pAttribDecl = treeFindEQData(&pAttribDeclBase->AttribDeclsTree, 1111 if (!*ppAttribDeclBase) 1112 // first call for this: 1113 *ppAttribDeclBase = xmlFindAttribDeclBase(pDom, 1114 pstrElementName); 1115 if (*ppAttribDeclBase) 1116 { 1117 pAttribDecl = (PCMATTRIBUTEDECL)treeFindEQData( 1118 &((**ppAttribDeclBase).AttribDeclsTree), 954 1119 (void*)pstrAttribName->psz, 955 Compare CMNodeData);1120 CompareNodeBaseData); 956 1121 } 957 1122 } … … 961 1126 962 1127 /* 963 *@@ ValidateElement: 964 * validates the specified element against the document's 965 * @DTD. 1128 *@@ ValidateElementChildren 1129 * validates the specified element against the document's @DTD, 1130 * more specifically, against the element declaration of the 1131 * new element's parent. 966 1132 * 967 1133 * This sets arcDOM in XMLDOM on errors. … … 970 1136 * is a declaration matching the element declaration where the 971 1137 * element's name matches the element type, and _one_ of the 972 * following holds: ###973 * 974 * (1) The declaration matches EMPTY and the element has no @content. 1138 * following holds: 1139 * 1140 * (1) The declaration matches EMPTY and the element has no @content. (done) 975 1141 * 976 1142 * (2) The declaration matches (children) (see @element_declaration) … … 981 1147 * child element and the end-tag. Note that a CDATA section 982 1148 * is never considered "whitespace", even if it contains 983 * white space only. 1149 * white space only. @@todo 984 1150 * 985 1151 * (3) The declaration matches (mixed) (see @element_declaration) 986 1152 * and the content consists of @content and child elements 987 * whose types match names in the content model. 1153 * whose types match names in the content model. (done) 988 1154 * 989 1155 * (4) The declaration matches ANY, and the types of any child 990 1156 * elements have been declared. (done) 991 1157 * 1158 * Preconditions: The element must already have been inserted 1159 * into the parent element's list, or we cannot validate sequences. 1160 * 992 1161 *@@added V0.9.9 (2001-02-16) [umoeller] 993 1162 */ 994 1163 995 1164 VOID ValidateElement(PXMLDOM pDom, 996 PDOMNODE pElement) 997 { 1165 PDOMNODE pNewElement, // in: new element 1166 PCMELEMENTDECLNODE pParentElementDecl) 1167 // in: element decl of element's parent 1168 { 1169 if (pDom && pNewElement) 1170 { 1171 if (!pParentElementDecl) 1172 { 1173 // this is always missing for the root element, of course, 1174 // because the parent is the document 1175 if (pNewElement->pParentNode == (PDOMNODE)pDom->pDocumentNode) 1176 return; // that's OK 1177 else 1178 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1179 } 1180 else 1181 { 1182 ULONG ulDeclType = pParentElementDecl->Particle.NodeBase.ulNodeType; 1183 1184 switch (ulDeclType) 1185 { 1186 case ELEMENTPARTICLE_EMPTY: 1187 // this is an error for sure 1188 xmlSetError(pDom, 1189 ERROR_DOM_SUBELEMENT_IN_EMPTY_ELEMENT, 1190 pNewElement->NodeBase.strNodeName.psz, 1191 TRUE); 1192 break; 1193 1194 case ELEMENTPARTICLE_ANY: 1195 // that's always OK 1196 break; 1197 1198 case ELEMENTPARTICLE_MIXED: 1199 case ELEMENTPARTICLE_CHOICE: 1200 case ELEMENTPARTICLE_SEQ: 1201 { 1202 const char *pcszNewElementName 1203 = pNewElement->NodeBase.strNodeName.psz; 1204 1205 // for all these, we first need to check if 1206 // the element is allowed at all 1207 PCMELEMENTPARTICLE pParticle 1208 = (PCMELEMENTPARTICLE)treeFindEQData( 1209 &pParentElementDecl->ParticleNamesTree, 1210 (void*)pcszNewElementName, 1211 CompareNodeBaseData); 1212 if (!pParticle) 1213 // not found: then this element is not allowed within this 1214 // parent 1215 xmlSetError(pDom, 1216 ERROR_DOM_INVALID_SUBELEMENT, 1217 pcszNewElementName, 1218 TRUE); 1219 else 1220 { 1221 // the element is allowed at all: now check for the 1222 // lists case... 1223 switch (ulDeclType) 1224 { 1225 case ELEMENTPARTICLE_CHOICE: 1226 break; 1227 1228 case ELEMENTPARTICLE_SEQ: 1229 break; 1230 } 1231 } 1232 1233 break; } 1234 } 1235 } 1236 } 1237 else 1238 pDom->arcDOM = ERROR_INVALID_PARAMETER; 1239 998 1240 // yes: get the element decl from the tree 999 PCMELEMENTDECLNODE pElementDecl = xmlFindElementDecl(pDom,1241 /* PCMELEMENTDECLNODE pElementDecl = xmlFindElementDecl(pDom, 1000 1242 &pElement->NodeBase.strNodeName); 1001 1243 if (!pElementDecl) … … 1051 1293 = treeFindEQData(&pParentElementDecl->ParticleNamesTree, 1052 1294 (void*)pElement->NodeBase.strNodeName.psz, 1053 Compare CMNodeData);1295 CompareNodeBaseData); 1054 1296 if (!pParticle) 1055 1297 // not found: then this element is not allowed within this … … 1063 1305 } 1064 1306 } 1065 } 1066 1067 /* 1068 *@@ ValidateAttribute: 1069 * validates the specified element against the document's 1070 * @DTD. 1307 */ 1308 } 1309 1310 /* 1311 *@@ ValidateAttributeType: 1312 * validates the specified attribute's type against the 1313 * document's @DTD. 1071 1314 * 1072 1315 * This sets arcDOM in XMLDOM on errors. … … 1075 1318 */ 1076 1319 1077 VOID ValidateAttribute(PXMLDOM pDom, 1078 PDOMNODE pAttrib) 1320 VOID ValidateAttributeType(PXMLDOM pDom, 1321 PDOMNODE pAttrib, 1322 PCMATTRIBUTEDECLBASE *ppAttribDeclBase) 1079 1323 { 1080 1324 PDOMNODE pElement = pAttrib->pParentNode; … … 1082 1326 PCMATTRIBUTEDECL pAttribDecl = xmlFindAttribDecl(pDom, 1083 1327 &pElement->NodeBase.strNodeName, 1084 &pAttrib->NodeBase.strNodeName); 1328 &pAttrib->NodeBase.strNodeName, 1329 ppAttribDeclBase); 1085 1330 if (!pAttribDecl) 1086 1331 xmlSetError(pDom, … … 1088 1333 pAttrib->NodeBase.strNodeName.psz, 1089 1334 TRUE); 1335 else 1336 { 1337 // check if the attribute value is allowed 1338 switch (pAttribDecl->ulAttrType) 1339 { 1340 case CMAT_CDATA: 1341 case CMAT_ID: 1342 case CMAT_IDREF: 1343 case CMAT_IDREFS: // ### 1344 case CMAT_ENTITY: 1345 case CMAT_ENTITIES: 1346 case CMAT_NMTOKEN: 1347 case CMAT_NMTOKENS: 1348 break; 1349 1350 case CMAT_ENUM: 1351 { 1352 // enumeration: then check if it has one of the 1353 // allowed values 1354 PNODEBASE pValue = (PNODEBASE)treeFindEQData( 1355 &pAttribDecl->ValuesTree, 1356 (void*)pAttrib->pstrNodeValue->psz, 1357 CompareNodeBaseData); 1358 if (!pValue) 1359 xmlSetError(pDom, 1360 ERROR_DOM_INVALID_ATTRIB_VALUE, 1361 pAttrib->NodeBase.strNodeName.psz, 1362 TRUE); 1363 } 1364 } 1365 1366 if (pAttribDecl->ulConstraint == CMAT_FIXED_VALUE) 1367 if (strcmp(pAttrib->pstrNodeValue->psz, pAttribDecl->pstrDefaultValue->psz)) 1368 // fixed value doesn't match: 1369 xmlSetError(pDom, 1370 ERROR_DOM_INVALID_ATTRIB_VALUE, 1371 pAttrib->NodeBase.strNodeName.psz, 1372 TRUE); 1373 } 1374 } 1375 1376 /* 1377 *@@ ValidateAllAttributes: 1378 * validates the constraints of all attributes of the specified 1379 * element against the document's @DTD. 1380 * 1381 *@@added V0.9.9 (2001-02-16) [umoeller] 1382 */ 1383 1384 VOID ValidateAllAttributes(PXMLDOM pDom, 1385 PCMATTRIBUTEDECLBASE pAttribDeclBase, 1386 PDOMNODE pNewElement) 1387 { 1388 PCMATTRIBUTEDECL pDeclThis 1389 = (PCMATTRIBUTEDECL)treeFirst(pAttribDeclBase->AttribDeclsTree); 1390 1391 while ((pDeclThis) && (!pDom->arcDOM)) 1392 { 1393 // if attribute is all optional: then we don't need 1394 // to check for whether it's here 1395 if ( (pDeclThis->ulConstraint != CMAT_IMPLIED) 1396 && (pDeclThis->ulConstraint != CMAT_DEFAULT_VALUE) 1397 // we don't have to check this case because expat 1398 // already adds default attributes for us 1399 ) 1400 { 1401 // for all others , we need to find the attribute 1402 PSZ pszAttrNameThis = pDeclThis->NodeBase.strNodeName.psz; 1403 PDOMNODE pAttrNode = (PDOMNODE)treeFindEQData( 1404 &pNewElement->AttributesMap, 1405 (void*)pszAttrNameThis, 1406 CompareNodeBaseData); 1407 1408 // now switch again 1409 switch (pDeclThis->ulConstraint) 1410 { 1411 case CMAT_REQUIRED: 1412 if (!pAttrNode) 1413 // required, but no attribute with this name exists: 1414 xmlSetError(pDom, 1415 ERROR_DOM_REQUIRED_ATTRIBUTE_MISSING, 1416 pszAttrNameThis, 1417 TRUE); 1418 break; 1419 } 1420 } 1421 1422 pDeclThis = (PCMATTRIBUTEDECL)treeNext((TREE*)pDeclThis); 1423 } 1424 } 1425 1426 /* ****************************************************************** 1427 * 1428 * Expat stack 1429 * 1430 ********************************************************************/ 1431 1432 /* 1433 *@@ DOMSTACKITEM: 1434 * 1435 *@@added V0.9.9 (2001-02-16) [umoeller] 1436 */ 1437 1438 typedef struct _DOMSTACKITEM 1439 { 1440 PDOMNODE pDomNode; 1441 PCMELEMENTDECLNODE pElementDecl; 1442 1443 } DOMSTACKITEM, *PDOMSTACKITEM; 1444 1445 /* 1446 *@@ PopElementStack: 1447 * 1448 * NOTE: 1449 * 1450 *@@added V0.9.9 (2001-02-16) [umoeller] 1451 */ 1452 1453 PDOMSTACKITEM PopElementStack(PXMLDOM pDom, 1454 PLISTNODE *ppListNode) 1455 { 1456 PDOMSTACKITEM pStackItem = NULL; 1457 PLISTNODE pParentLN = lstPop(&pDom->llElementStack); 1458 1459 if (!pParentLN) 1460 pDom->arcDOM = ERROR_DOM_NO_ELEMENT; 1461 else 1462 { 1463 // we have at least one node: 1464 pStackItem = (PDOMSTACKITEM)pParentLN->pItemData; 1465 1466 if (ppListNode) 1467 *ppListNode = pParentLN; 1468 } 1469 1470 return (pStackItem); 1471 } 1472 1473 /* 1474 *@@ PushElementStack: 1475 * 1476 * NOTE: pDomNode will most frequently be an element 1477 * node, but will also be the document for root and 1478 * a DOCTYPE node while parsing the DTD. 1479 * 1480 *@@added V0.9.9 (2001-02-16) [umoeller] 1481 */ 1482 1483 VOID PushElementStack(PXMLDOM pDom, 1484 PDOMNODE pDomNode) 1485 { 1486 PDOMSTACKITEM pNew = (PDOMSTACKITEM)malloc(sizeof(*pNew)); 1487 if (!pNew) 1488 pDom->arcDOM = ERROR_NOT_ENOUGH_MEMORY; 1489 else 1490 { 1491 memset(pNew, 0, sizeof(*pNew)); 1492 pNew->pDomNode = pDomNode; 1493 1494 // shall we validate? 1495 if ( (pDom->pDocTypeNode) 1496 && (pDomNode->NodeBase.ulNodeType == DOMNODE_ELEMENT) 1497 ) 1498 pNew->pElementDecl = xmlFindElementDecl(pDom, 1499 &pDomNode->NodeBase.strNodeName); 1500 1501 lstPush(&pDom->llElementStack, 1502 pNew); 1503 } 1090 1504 } 1091 1505 … … 1118 1532 ULONG i; 1119 1533 1120 PDOMNODE pParent = NULL, 1121 pNew = NULL; 1122 1123 PLISTNODE pParentNode = lstPop(&pDom->llStack); 1124 1125 if (!pParentNode) 1126 pDom->arcDOM = ERROR_DOM_NO_DOCUMENT; 1127 else 1128 { 1129 // we have at least one node: 1130 pParent = (PDOMNODE)pParentNode->pItemData; 1534 PDOMSTACKITEM pSI = PopElementStack(pDom, 1535 NULL); // no free 1536 if (!pDom->arcDOM) 1537 { 1538 PDOMNODE pParent = pSI->pDomNode, 1539 pNew = NULL; 1131 1540 1132 1541 pDom->arcDOM = xmlCreateElementNode(pParent, … … 1135 1544 1136 1545 if (!pDom->arcDOM) 1546 // OK, node is valid: 1547 // push this on the stack so we can add child elements 1548 PushElementStack(pDom, 1549 pNew); 1550 1551 // shall we validate? 1552 if ( (!pDom->arcDOM) 1553 && (pDom->pDocTypeNode) 1554 ) 1555 ValidateElement(pDom, 1556 pNew, // new element 1557 pSI->pElementDecl); // parent's elem decl 1558 1559 if (!pDom->arcDOM) 1137 1560 { 1561 PCMATTRIBUTEDECLBASE pAttribDeclBase = NULL; 1562 1563 // shall we validate? 1564 if (pDom->pDocTypeNode) 1565 // yes: get attrib decl base for speed 1566 pAttribDeclBase 1567 = xmlFindAttribDeclBase(pDom, 1568 &pNew->NodeBase.strNodeName); 1569 1570 // now for the attribs 1571 for (i = 0; 1572 (papcszAttribs[i]) && (!pDom->arcDOM); 1573 i += 2) 1574 { 1575 PDOMNODE pAttrib; 1576 pDom->arcDOM = xmlCreateAttributeNode(pNew, // element, 1577 papcszAttribs[i], // attr name 1578 papcszAttribs[i + 1], // attr value 1579 &pAttrib); 1580 1581 // shall we validate? 1582 if (pDom->pDocTypeNode) 1583 ValidateAttributeType(pDom, 1584 pAttrib, 1585 &pAttribDeclBase); 1586 } 1587 1588 // OK, now we got all attributes: 1589 // now look for defaults in the DTD, 1590 // if we shall validate 1591 if ( (pDom->pDocTypeNode) 1592 && (!pDom->arcDOM) 1593 && (pAttribDeclBase) 1594 ) 1595 ValidateAllAttributes(pDom, 1596 pAttribDeclBase, 1597 pNew); 1598 } 1599 } 1600 1601 pDom->pLastWasTextNode = NULL; 1602 } 1603 } 1604 1605 /* 1606 *@@ EndElementHandler: 1607 * @expat handler for when parsing an element is done. 1608 * We pop the element off of our stack then. 1609 */ 1610 1611 void EXPATENTRY EndElementHandler(void *pUserData, // in: our PXMLDOM really 1612 const XML_Char *name) 1613 { 1614 PXMLDOM pDom = (PXMLDOM)pUserData; 1615 // continue parsing only if we had no errors so far 1616 if (!pDom->arcDOM) 1617 { 1618 PLISTNODE pStackLN = NULL; 1619 PDOMSTACKITEM pSI = PopElementStack(pDom, 1620 &pStackLN); 1621 1622 if (!pDom->arcDOM) 1623 { 1624 // shall we validate? 1625 /* if (pDom->pDocTypeNode) 1626 // yes: 1627 ValidateElementChildren(pDom, 1628 pSI->pDomNode); */ 1629 1630 lstRemoveNode(&pDom->llElementStack, pStackLN); // auto-free 1631 } 1632 else 1633 pDom->arcDOM = ERROR_DOM_INTEGRITY; 1634 1635 pDom->pLastWasTextNode = NULL; 1636 } 1637 } 1638 1639 /* 1640 *@@ CharacterDataHandler: 1641 * @expat handler for character data (@content). 1642 * 1643 * Note: expat passes chunks of content without zero-terminating 1644 * them. We must concatenate the chunks to a full text node. 1645 */ 1646 1647 void EXPATENTRY CharacterDataHandler(void *pUserData, // in: our PXMLDOM really 1648 const XML_Char *s, 1649 int len) 1650 { 1651 PXMLDOM pDom = (PXMLDOM)pUserData; 1652 1653 // continue parsing only if we had no errors so far 1654 if (!pDom->arcDOM) 1655 { 1656 ULONG i; 1657 1658 if (len) 1659 { 1660 // we need a new text node: 1661 PDOMSTACKITEM pSI = PopElementStack(pDom, 1662 NULL); // no free 1663 if (!pDom->arcDOM) 1664 { 1665 PDOMNODE pParent = pSI->pDomNode, 1666 pNew = NULL; 1667 1138 1668 // shall we validate? 1139 1669 if (pDom->pDocTypeNode) 1140 1670 { 1141 // yes: 1142 ValidateElement(pDom, 1143 pNew); 1144 } 1145 1146 if (!pDom->arcDOM) 1147 { 1148 // OK, node is valid: 1149 // push this on the stack so we can add child elements 1150 lstPush(&pDom->llStack, pNew); 1151 1152 // now for the attribs 1153 for (i = 0; 1154 (papcszAttribs[i]) && (!pDom->arcDOM); 1155 i += 2) 1671 // yes: check if the parent element allows 1672 // for content at all (must be "mixed" model) 1673 1674 // get the element decl from the tree 1675 PCMELEMENTDECLNODE pElementDecl = pSI->pElementDecl; 1676 1677 if (pElementDecl) 1156 1678 { 1157 PDOMNODE pAttrib; 1158 1159 pDom->arcDOM = xmlCreateAttributeNode(pNew, // element, 1160 papcszAttribs[i], // attr name 1161 papcszAttribs[i + 1], // attr value 1162 &pAttrib); 1163 1164 // shall we validate? 1165 if (pDom->pDocTypeNode) 1679 switch (pElementDecl->Particle.NodeBase.ulNodeType) 1166 1680 { 1167 ValidateAttribute(pDom, 1168 pAttrib); 1681 case ELEMENTPARTICLE_ANY: 1682 case ELEMENTPARTICLE_MIXED: 1683 // those two are okay 1684 break; 1685 1686 case ELEMENTPARTICLE_EMPTY: 1687 // that's an error for sure 1688 pDom->arcDOM = ERROR_ELEMENT_CANNOT_HAVE_CONTENT; 1689 break; 1690 1691 default: 1692 { 1693 // ELEMENTPARTICLE_CHOICE: 1694 // ELEMENTPARTICLE_SEQ: 1695 // with these two, we accept whitespace, but nothing 1696 // else... so if we have characters other than 1697 // whitespace, terminate 1698 ULONG ul; 1699 const char *p = s; 1700 for (ul = 0; 1701 ul < len; 1702 ul++, p++) 1703 if (!strchr("\r\n\t ", *p)) 1704 { 1705 // other character: 1706 xmlSetError(pDom, 1707 ERROR_ELEMENT_CANNOT_HAVE_CONTENT, 1708 pParent->NodeBase.strNodeName.psz, 1709 TRUE); 1710 break; 1711 } 1712 } 1169 1713 } 1170 1714 } 1171 1715 } 1716 1717 if (pDom->pLastWasTextNode) 1718 { 1719 // we had a text node, and no elements or other 1720 // stuff in between: 1721 xstrcat(pDom->pLastWasTextNode->pstrNodeValue, 1722 s, 1723 len); 1724 } 1725 else 1726 { 1727 pDom->arcDOM = xmlCreateTextNode(pParent, 1728 s, 1729 len, 1730 &pDom->pLastWasTextNode); 1731 } 1172 1732 } 1173 1733 } 1174 1175 pDom->pLastWasTextNode = NULL; 1176 } 1177 } 1178 1179 /* 1180 *@@ EndElementHandler: 1181 * @expat handler for when parsing an element is done. 1182 * We pop the element off of our stack then. 1183 */ 1184 1185 void EXPATENTRY EndElementHandler(void *pUserData, // in: our PXMLDOM really 1186 const XML_Char *name) 1734 } 1735 } 1736 1737 /* 1738 *@@ CommentHandler: 1739 * @expat handler for @comments. 1740 * 1741 * Note: This is only set if DF_PARSECOMMENTS is 1742 * flagged with xmlCreateDOM. 1743 * 1744 *@@added V0.9.9 (2001-02-14) [umoeller] 1745 */ 1746 1747 void EXPATENTRY CommentHandler(void *pUserData, // in: our PXMLDOM really 1748 const XML_Char *data) 1187 1749 { 1188 1750 PXMLDOM pDom = (PXMLDOM)pUserData; 1751 1189 1752 // continue parsing only if we had no errors so far 1190 1753 if (!pDom->arcDOM) 1191 1754 { 1192 PLISTNODE pNode = lstPop(&pDom->llStack); 1193 if (pNode) 1194 lstRemoveNode(&pDom->llStack, pNode); 1195 1196 pDom->pLastWasTextNode = NULL; 1197 } 1198 } 1199 1200 /* 1201 *@@ CharacterDataHandler: 1202 * @expat handler for character data (@content). 1203 * 1204 * Note: expat passes chunks of content without zero-terminating 1205 * them. We must concatenate the chunks to a full text node. 1206 */ 1207 1208 void EXPATENTRY CharacterDataHandler(void *pUserData, // in: our PXMLDOM really 1209 const XML_Char *s, 1210 int len) 1211 { 1212 PXMLDOM pDom = (PXMLDOM)pUserData; 1213 1214 // continue parsing only if we had no errors so far 1215 if (!pDom->arcDOM) 1216 { 1217 ULONG i; 1218 1219 if (len) 1220 { 1221 if (pDom->pLastWasTextNode) 1222 { 1223 // we had a text node, and no elements or other 1224 // stuff in between: 1225 xstrcat(pDom->pLastWasTextNode->pstrNodeValue, 1226 s, 1227 len); 1228 } 1229 else 1230 { 1231 // we need a new text node: 1232 PDOMNODE pNew, 1233 pParent; 1234 // non-root level: 1235 PLISTNODE pParentNode = lstPop(&pDom->llStack); 1236 pParent = (PDOMNODE)pParentNode->pItemData; 1237 1238 pDom->arcDOM = xmlCreateTextNode(pParent, 1239 s, 1240 len, 1241 &pDom->pLastWasTextNode); 1242 } 1243 } 1244 } 1245 } 1246 1247 /* 1248 *@@ CommentHandler: 1249 * @expat handler for @comments. 1250 * 1251 * Note: This is only set if DF_PARSECOMMENTS is 1252 * flagged with xmlCreateDOM. 1253 * 1254 *@@added V0.9.9 (2001-02-14) [umoeller] 1255 */ 1256 1257 void EXPATENTRY CommentHandler(void *pUserData, // in: our PXMLDOM really 1258 const XML_Char *data) 1259 { 1260 PXMLDOM pDom = (PXMLDOM)pUserData; 1261 1262 // continue parsing only if we had no errors so far 1263 if (!pDom->arcDOM) 1264 { 1265 PLISTNODE pParentNode = lstPop(&pDom->llStack); 1266 1267 if (pParentNode) 1268 { 1269 // non-root level: 1270 PDOMNODE pParent = (PDOMNODE)pParentNode->pItemData; 1271 PDOMNODE pComment; 1755 // we need a new text node: 1756 PDOMSTACKITEM pSI = PopElementStack(pDom, 1757 NULL); // no free 1758 if (!pDom->arcDOM) 1759 { 1760 PDOMNODE pParent = pSI->pDomNode, 1761 pNew = NULL; 1272 1762 1273 1763 pDom->arcDOM = xmlCreateCommentNode(pParent, 1274 1764 data, 1275 &p Comment);1765 &pNew); 1276 1766 } 1277 1767 } … … 1307 1797 else 1308 1798 { 1309 pDom->arcDOM = xmlCreateDocumentTypeNode(pDocumentNode, 1310 pcszDoctypeName, 1311 pcszSysid, 1312 pcszPubid, 1313 fHasInternalSubset, 1314 &pDom->pDocTypeNode); 1315 1316 // push this on the stack so we can add child elements 1317 lstPush(&pDom->llStack, pDom->pDocTypeNode); 1799 // doctype must be null 1800 if (pDom->pDocTypeNode) 1801 pDom->arcDOM = ERROR_DOM_DUPLICATE_DOCTYPE; 1802 else 1803 { 1804 pDom->arcDOM = xmlCreateDocumentTypeNode(pDocumentNode, 1805 pcszDoctypeName, 1806 pcszSysid, 1807 pcszPubid, 1808 fHasInternalSubset, 1809 &pDom->pDocTypeNode); 1810 } 1318 1811 } 1319 1812 } … … 1332 1825 PXMLDOM pDom = (PXMLDOM)pUserData; 1333 1826 1334 PLISTNODE pListNode = lstPop(&pDom->llStack); 1335 if (!pListNode) 1336 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1337 else 1338 { 1339 PDOMNODE pDomNode = (PDOMNODE)pListNode->pItemData; 1340 if (pDomNode->NodeBase.ulNodeType != DOMNODE_DOCUMENT_TYPE) 1827 // continue parsing only if we had no errors so far 1828 /* if (!pDom->arcDOM) 1829 { 1830 PLISTNODE pStackLN = NULL; 1831 PDOMSTACKITEM pSI = PopElementStack(pDom, 1832 &pStackLN); 1833 1834 if (pDom->arcDOM) 1341 1835 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1342 1343 lstRemoveNode(&pDom->llStack, pListNode); 1344 } 1345 1346 // continue parsing only if we had no errors so far 1347 if (!pDom->arcDOM) 1348 { 1349 1350 } 1836 else 1837 { 1838 if (pSI->pDomNode->NodeBase.ulNodeType != DOMNODE_DOCUMENT_TYPE) 1839 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1840 1841 lstRemoveNode(&pDom->llElementStack, pStackLN); // auto-free 1842 } 1843 } */ 1351 1844 } 1352 1845 … … 1354 1847 *@@ NotationDeclHandler: 1355 1848 * @expat handler for @notation_declarations. 1849 * 1850 * ### 1356 1851 * 1357 1852 *@@added V0.9.9 (2001-02-14) [umoeller] … … 1393 1888 * 1394 1889 * The pcszSystemId is the system identifier specified in the 1395 * entity declaration and is never null. 1890 * entity declaration and is never null. This is an exact copy 1891 * of what was specified in the reference. 1396 1892 * 1397 1893 * There are a couple of ways in which this handler differs … … 1430 1926 const XML_Char *pcszPublicId) 1431 1927 { 1432 int i = 1; 1928 int i = 0; 1929 1930 FILE *f = fopen("log", "w"); 1931 fprintf(f, "sysid: %s\n", pcszSystemId); 1932 fclose(f); 1433 1933 1434 1934 /* PXMLDOM pDom = (PXMLDOM)pUserData; … … 1467 1967 if (!pDom->arcDOM) 1468 1968 { 1469 // pop the last DOMNODE off the stack and check if it's a DOCTYPE1470 P LISTNODE pListNode = lstPop(&pDom->llStack);1471 if (!p ListNode)1969 // OK, we're in a DOCTYPE node: 1970 PDOMDOCTYPENODE pDocType = pDom->pDocTypeNode; 1971 if (!pDocType) 1472 1972 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1473 1973 else 1474 1974 { 1475 PDOMNODE pDomNode = (PDOMNODE)pListNode->pItemData; 1476 if (pDomNode->NodeBase.ulNodeType != DOMNODE_DOCUMENT_TYPE) 1477 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1478 else 1975 // create an element declaration and push it unto the 1976 // declarations tree 1977 PCMELEMENTDECLNODE pNew = NULL; 1978 pDom->arcDOM = xmlCreateElementDecl(pcszName, 1979 pModel, 1980 &pNew); 1981 // this recurses!! 1982 // after this, pModel is invalid 1983 1984 if (pDom->arcDOM == NO_ERROR) 1479 1985 { 1480 // OK, we're in a DOCTYPE node: 1481 PDOMDOCTYPENODE pDocType = (PDOMDOCTYPENODE)pDomNode; 1482 1483 // create an element declaration and push it unto the 1484 // declarations tree 1485 PCMELEMENTDECLNODE pNew = NULL; 1486 pDom->arcDOM = xmlCreateElementDecl(pcszName, 1487 pModel, 1488 &pNew); 1489 // this recurses!! 1490 1491 if (pDom->arcDOM == NO_ERROR) 1492 { 1493 // add this to the doctype's declarations tree 1494 if (treeInsertNode(&pDocType->ElementDeclsTree, 1495 (TREE*)pNew, 1496 CompareCMNodeNodes, 1497 FALSE) 1498 == TREE_DUPLICATE) 1499 // element already declared: 1500 // according to the XML specs, this is a validity 1501 // constraint, so we report a validation error 1502 xmlSetError(pDom, 1503 ERROR_DOM_DUPLICATE_ELEMENT_DECL, 1504 pNew->Particle.CMNode.strNodeName.psz, 1505 TRUE); 1506 } 1986 // add this to the doctype's declarations tree 1987 if (treeInsertNode(&pDocType->ElementDeclsTree, 1988 (TREE*)pNew, 1989 CompareNodeBaseNodes, 1990 FALSE) 1991 == TREE_DUPLICATE) 1992 // element already declared: 1993 // according to the XML specs, this is a validity 1994 // constraint, so we report a validation error 1995 xmlSetError(pDom, 1996 ERROR_DOM_DUPLICATE_ELEMENT_DECL, 1997 pNew->Particle.NodeBase.strNodeName.psz, 1998 TRUE); 1507 1999 } 1508 2000 } … … 1516 2008 */ 1517 2009 1518 VOID AddEnum(PCMATTRIBUTEDECL pNew, 1519 const char *p, 1520 const char *pNext) 1521 { 1522 PSZ pszType = strhSubstr(p, pNext); 1523 PNODEBASE pCMNode = (PNODEBASE)malloc(sizeof(*pCMNode)); 1524 memset(pCMNode, 0, sizeof(*pCMNode)); 1525 pCMNode->ulNodeType = ATTRIBUTE_DECLARATION_ENUM; 1526 xstrInitSet(&pCMNode->strNodeName, pszType); 1527 1528 treeInsertNode(&pNew->ValuesTree, 1529 (TREE*)pCMNode, 1530 CompareCMNodeNodes, 1531 FALSE); 2010 APIRET AddEnum(PCMATTRIBUTEDECL pDecl, 2011 const char *p, // in: start of name 2012 const char *pNext) // in: end of name (not included) 2013 { 2014 // PSZ pszType = strhSubstr(p, pNext); 2015 PNODEBASE pNew = NULL; 2016 APIRET arc = xmlCreateNodeBase(ATTRIBUTE_DECLARATION_ENUM, 2017 sizeof(NODEBASE), 2018 p, 2019 (pNext - p), 2020 &pNew); 2021 if (!arc) 2022 treeInsertNode(&pDecl->ValuesTree, 2023 (TREE*)pNew, 2024 CompareNodeBaseNodes, 2025 FALSE); 2026 2027 return (arc); 1532 2028 } 1533 2029 … … 1572 2068 if (!pDom->arcDOM) 1573 2069 { 1574 // pop the last DOMNODE off the stack and check if it's a DOCTYPE1575 P LISTNODE pListNode = lstPop(&pDom->llStack);1576 if (!p ListNode)2070 // OK, we're in a DOCTYPE node: 2071 PDOMDOCTYPENODE pDocType = pDom->pDocTypeNode; 2072 if (!pDocType) 1577 2073 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1578 2074 else 1579 2075 { 1580 PDOMNODE pDomNode = (PDOMNODE)pListNode->pItemData; 1581 if (pDomNode->NodeBase.ulNodeType != DOMNODE_DOCUMENT_TYPE) 1582 pDom->arcDOM = ERROR_DOM_DOCTYPE_STRUCTURE; 1583 else 2076 PCMATTRIBUTEDECLBASE pThis = NULL, 2077 pCache = pDom->pAttListDeclCache; 2078 2079 // check if this is for the same attlist as the previous 2080 // call (we cache the pointer for speed) 2081 if ( (pCache) 2082 && (!strhcmp(pCache->NodeBase.strNodeName.psz, 2083 pcszElementName)) 2084 ) 2085 // this attdecl is for the same element: 2086 // use that (we won't have to search the tree) 2087 pThis = pDom->pAttListDeclCache; 2088 2089 if (!pThis) 1584 2090 { 1585 // OK, we're in a DOCTYPE node: 1586 PDOMDOCTYPENODE pDocType = (PDOMDOCTYPENODE)pDomNode; 1587 PCMATTRIBUTEDEDECLBASE pThis = NULL, 1588 pCache = pDom->pAttListDeclCache; 1589 1590 // check if this is for the same attlist as the previous 1591 // call (we cache the pointer for speed) 1592 if ( (pCache) 1593 && (!strhcmp(pCache->CMNode.strNodeName.psz, 1594 pcszElementName)) 1595 ) 1596 // this attdecl is for the same element: 1597 // use that (we won't have to search the tree) 1598 pThis = pDom->pAttListDeclCache; 2091 // cache didn't match: look up attributes tree then 2092 pThis = (PCMATTRIBUTEDECLBASE)treeFindEQData( 2093 &pDocType->AttribDeclBasesTree, 2094 (void*)pcszElementName, 2095 CompareNodeBaseData); 1599 2096 1600 2097 if (!pThis) 1601 2098 { 1602 // cache didn't match: look up attributes tree then 1603 pThis = treeFindEQData(&pDocType->AttribDeclBasesTree, 1604 (void*)pcszElementName, 1605 CompareCMNodeData); 1606 1607 if (!pThis) 2099 // still not found: 2100 // we need a new node then 2101 pDom->arcDOM = xmlCreateNodeBase(ATTRIBUTE_DECLARATION_BASE, 2102 sizeof(CMATTRIBUTEDECLBASE), 2103 pcszElementName, 2104 0, 2105 (PNODEBASE*)&pThis); 2106 if (!pDom->arcDOM) 1608 2107 { 1609 // still not found: 1610 // we need a new node then 1611 pThis = (PCMATTRIBUTEDEDECLBASE)malloc(sizeof(*pThis)); 1612 if (!pThis) 1613 pDom->arcDOM = ERROR_NOT_ENOUGH_MEMORY; 1614 else 2108 // initialize the subtree 2109 treeInit(&pThis->AttribDeclsTree); 2110 2111 treeInsertNode(&pDocType->AttribDeclBasesTree, 2112 (TREE*)pThis, 2113 CompareNodeBaseNodes, 2114 FALSE); 2115 } 2116 } 2117 2118 pDom->pAttListDeclCache = pThis; 2119 } 2120 2121 if (pThis) 2122 { 2123 // pThis now has either an existing or a new CMATTRIBUTEDECLBASE; 2124 // add a new attribute def (CMATTRIBUTEDEDECL) to that 2125 PCMATTRIBUTEDECL pNew = NULL; 2126 pDom->arcDOM = xmlCreateNodeBase(ATTRIBUTE_DECLARATION, 2127 sizeof(CMATTRIBUTEDECL), 2128 pcszAttribName, 2129 0, 2130 (PNODEBASE*)&pNew); 2131 if (!pDom->arcDOM) 2132 { 2133 treeInit(&pNew->ValuesTree); 2134 2135 // check the type... expat is too lazy to parse this for 2136 // us, so we must check manually. Expat only normalizes 2137 // the "type" string to kick out whitespace, so we get: 2138 // (TYPE1|TYPE2|TYPE3) 2139 if (*pcszAttribType == '(') 2140 { 2141 // enumeration: 2142 const char *p = pcszAttribType + 1, 2143 *pNext; 2144 while ( (pNext = strchr(p, '|')) 2145 && (!pDom->arcDOM) 2146 ) 1615 2147 { 1616 p This->CMNode.ulNodeType = ATTRIBUTE_DECLARATION_BASE;1617 xstrInitCopy(&pThis->CMNode.strNodeName, pcszElementName, 0);1618 1619 // initialize the subtree 1620 treeInit(&pThis->AttribDeclsTree);1621 1622 treeInsertNode(&pDocType->AttribDeclBasesTree,1623 (TREE*)pThis,1624 CompareCMNodeNodes, 1625 FALSE);2148 pDom->arcDOM = AddEnum(pNew, p, pNext); 2149 p = pNext + 1; 2150 } 2151 2152 if (!pDom->arcDOM) 2153 { 2154 pNext = strchr(p, ')'); 2155 AddEnum(pNew, p, pNext); 2156 2157 pNew->ulAttrType = CMAT_ENUM; 1626 2158 } 1627 2159 } 1628 1629 pDom->pAttListDeclCache = pThis; 1630 } 1631 1632 if (pThis) 1633 { 1634 // pThis now has either an existing or a new CMATTRIBUTEDEDECLBASE; 1635 // add a new attribute def (CMATTRIBUTEDEDECL) to that 1636 PCMATTRIBUTEDECL pNew = (PCMATTRIBUTEDECL)malloc(sizeof(*pNew)); 1637 if (!pNew) 1638 pDom->arcDOM = ERROR_NOT_ENOUGH_MEMORY; 1639 else 2160 else if (!strcmp(pcszAttribType, "CDATA")) 2161 pNew->ulAttrType = CMAT_CDATA; 2162 else if (!strcmp(pcszAttribType, "ID")) 2163 pNew->ulAttrType = CMAT_ID; 2164 else if (!strcmp(pcszAttribType, "IDREF")) 2165 pNew->ulAttrType = CMAT_IDREF; 2166 else if (!strcmp(pcszAttribType, "IDREFS")) 2167 pNew->ulAttrType = CMAT_IDREFS; 2168 else if (!strcmp(pcszAttribType, "ENTITY")) 2169 pNew->ulAttrType = CMAT_ENTITY; 2170 else if (!strcmp(pcszAttribType, "ENTITIES")) 2171 pNew->ulAttrType = CMAT_ENTITIES; 2172 else if (!strcmp(pcszAttribType, "NMTOKEN")) 2173 pNew->ulAttrType = CMAT_NMTOKEN; 2174 else if (!strcmp(pcszAttribType, "NMTOKENS")) 2175 pNew->ulAttrType = CMAT_NMTOKENS; 2176 2177 if (!pDom->arcDOM) 1640 2178 { 1641 memset(pNew, 0, sizeof(*pNew));1642 pNew->CMNode.ulNodeType = ATTRIBUTE_DECLARATION;1643 1644 xstrInitCopy(&pNew->CMNode.strNodeName,1645 pcszAttribName,1646 0);1647 1648 // fill the other fields1649 /* xstrInitCopy(&pNew->strType,1650 pcszAttribType,1651 0); */1652 1653 treeInit(&pNew->ValuesTree);1654 1655 // check the type... expat is too lazy to parse this for1656 // us, so we must check manually. Expat only normalizes1657 // the "type" string to kick out whitespace, so we get:1658 // (TYPE1|TYPE2|TYPE3)1659 if (*pcszAttribType == '(')1660 {1661 // enumeration:1662 const char *p = pcszAttribType + 1,1663 *pNext;1664 while (pNext = strchr(p, '|'))1665 {1666 AddEnum(pNew, p, pNext);1667 p = pNext + 1;1668 }1669 1670 pNext = strchr(p, ')');1671 AddEnum(pNew, p, pNext);1672 1673 pNew->ulAttrType = CMAT_ENUM;1674 }1675 else if (!strcmp(pcszAttribType, "CDATA"))1676 pNew->ulAttrType = CMAT_CDATA;1677 else if (!strcmp(pcszAttribType, "ID"))1678 pNew->ulAttrType = CMAT_ID;1679 else if (!strcmp(pcszAttribType, "IDREF"))1680 pNew->ulAttrType = CMAT_IDREF;1681 else if (!strcmp(pcszAttribType, "IDREFS"))1682 pNew->ulAttrType = CMAT_IDREFS;1683 else if (!strcmp(pcszAttribType, "ENTITY"))1684 pNew->ulAttrType = CMAT_ENTITY;1685 else if (!strcmp(pcszAttribType, "ENTITIES"))1686 pNew->ulAttrType = CMAT_ENTITIES;1687 else if (!strcmp(pcszAttribType, "NMTOKEN"))1688 pNew->ulAttrType = CMAT_NMTOKEN;1689 else if (!strcmp(pcszAttribType, "NMTOKENS"))1690 pNew->ulAttrType = CMAT_NMTOKENS;1691 1692 2179 if (pcszDefault) 1693 2180 { … … 1711 2198 if (treeInsertNode(&pThis->AttribDeclsTree, 1712 2199 (TREE*)pNew, 1713 Compare CMNodeNodes,2200 CompareNodeBaseNodes, 1714 2201 FALSE) 1715 2202 == TREE_DUPLICATE) … … 1820 2307 memset(pDom, 0, sizeof(XMLDOM)); 1821 2308 1822 lstInit(&pDom->ll Stack,1823 FALSE); // noauto-free2309 lstInit(&pDom->llElementStack, 2310 TRUE); // auto-free 1824 2311 1825 2312 // create the document node 1826 arc = xmlCreate Node(NULL, // no parent2313 arc = xmlCreateDomNode(NULL, // no parent 1827 2314 DOMNODE_DOCUMENT, 2315 NULL, 2316 0, 1828 2317 &pDocument); 1829 2318 … … 1835 2324 // push the document on the stack so the handlers 1836 2325 // will append to that 1837 lstPush(&pDom->llStack,1838 pDom->pDocumentNode);2326 PushElementStack(pDom, 2327 pDocument); 1839 2328 1840 2329 pDom->pParser = XML_ParserCreate(NULL); … … 1958 2447 if (pDom->pDocumentNode) 1959 2448 { 1960 xmlDeleteNode((P DOMNODE)pDom->pDocumentNode);2449 xmlDeleteNode((PNODEBASE)pDom->pDocumentNode); 1961 2450 pDom->pDocumentNode = NULL; 1962 2451 } … … 1983 2472 1984 2473 // clean up the stack (but not the DOM itself) 1985 lstClear(&pDom->ll Stack);2474 lstClear(&pDom->llElementStack); 1986 2475 } 1987 2476 } -
trunk/src/helpers/xmldefs.c
r38 r39 700 700 * -- A "list" is defined as an enumeration of content particles, 701 701 * enclosed in parentheses, where the content particles are 702 * separated by list separators.703 * 704 * There are two types of list separators:702 * separated by "connectors". 703 * 704 * There are two types of "connectors": 705 705 * 706 706 * -- Commas (",") indicate that the elements must appear … … 710 710 * occur alternatively ("choice"). 711 711 * 712 * The list separators cannot be mixed; the list must be712 * The connectors cannot be mixed; the list must be 713 713 * either completely "sequence" or "choice". 714 714 * … … 743 743 * 744 744 * Now, a nested example: 745 * 746 + <!ELEMENT poem (title?, (stanza+ | couplet+ | line+) ) > 747 * 748 * That is, a poem consists of an optional title, followed by one or 749 * several stanzas, or one or several couplets, or one or several lines. 750 * This is different from: 751 * 752 + <!ELEMENT poem (title?, (stanza | couplet | line)+ ) > 753 * 754 * The latter allows for a single poem to contain a mixture of stanzas, 755 * couplets or lines. 756 * 757 * And for WarpIN: 745 758 * 746 759 + <!ELEMENT WARPIN (REXX*, VARPROMPT*, MSG?, TITLE?, (GROUP | PCK)+), PAGE+) > -
trunk/src/helpers/xmlparse.c
r38 r39 1053 1053 1054 1054 #ifdef XML_DTD 1055 intoldParamEntityParsing = paramEntityParsing;1055 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; 1056 1056 1057 1057 #endif -
trunk/src/helpers/xstring.c
r38 r39 376 376 * With ulSourceLength, specify the length of pcszSource. 377 377 * If you specify 0, this function will run strlen(pcszSource) 378 * itself. If you already know the length of pcszSource (or 379 * only want to copy a substring), you can speed this function 380 * up a bit this way. 378 * itself. 379 * 380 * If you already know the length of pcszSource, you can 381 * speed this function up a bit this way. 382 * 383 * You are required to specify ulSourceLength if you only want 384 * to copy a substring, or pcszSource is not zero-terminated. 381 385 * 382 386 * Returns the length of the new string (excluding the null … … 396 400 *@@changed V0.9.9 (2001-01-28) [lafaix]: fixed memory leak and NULL source behavior 397 401 *@@changed V0.9.9 (2001-02-14) [umoeller]: fixed NULL target crash 402 *@@changed V0.9.9 (2001-02-16) [umoeller]: now supporting non-zero-terminated pcszSource 398 403 */ 399 404 … … 432 437 // else: we have enough memory 433 438 434 // strcpy(pxstr->psz, pcszSource);435 439 memcpy(pxstr->psz, 436 440 pcszSource, 437 ulSourceLength + 1); // V0.9.9 (2001-01-31) [umoeller] 441 ulSourceLength); 442 *(pxstr->psz + ulSourceLength) = '\0'; 443 // V0.9.9 (2001-02-16) [umoeller] 444 // we must do this or otherwise we require pcszSource 445 // to be zero-terminated... not a good idea 438 446 } 439 447 else … … 480 488 * With ulSourceLength, specify the length of pcszSource. 481 489 * If you specify 0, this function will run strlen(pcszSource) 482 * itself. If you already know the length of pcszSource (or 483 * only want to copy a substring), you can speed this function 484 * up a bit this way. 490 * itself. 491 * 492 * If you already know the length of pcszSource, you can 493 * speed this function up a bit this way. 494 * 495 * You are required to specify ulSourceLength if you only want 496 * to copy a substring, or pcszSource is not zero-terminated. 485 497 * 486 498 * Returns the length of the new string (excluding the null … … 508 520 *@@changed V0.9.7 (2000-12-10) [umoeller]: return value was wrong 509 521 *@@changed V0.9.7 (2001-01-15) [umoeller]: added ulSourceLength 522 *@@changed V0.9.9 (2001-02-16) [umoeller]: now supporting non-zero-terminated pcszSource 510 523 */ 511 524 … … 559 572 memcpy(pxstr->psz + pxstr->ulLength, 560 573 pcszSource, 561 ulSourceLength + 1); // null terminator 574 ulSourceLength); // null terminator 575 576 *(pxstr->psz + pxstr->ulLength + ulSourceLength) = '\0'; 577 // V0.9.9 (2001-02-16) [umoeller] 578 // we must do this or otherwise we require pcszSource 579 // to be zero-terminated... not a good idea 562 580 563 581 // in all cases, set new length
Note:
See TracChangeset
for help on using the changeset viewer.