1/* 2 * tclexpat.c -- 3 * 4 * TclXML driver for James Clark's expat XML parser 5 * 6 * Copyright (c) 1998-2003 Steve Ball, Zveno Pty Ltd 7 * 8 * Zveno Pty Ltd makes this software and associated documentation 9 * available free of charge for any purpose. You may make copies 10 * of the software but you must include all of this notice on any copy. 11 * 12 * Zveno Pty Ltd does not warrant that this software is error free 13 * or fit for any purpose. Zveno Pty Ltd disclaims any liability for 14 * all claims, expenses, losses, damages and costs any user may incur 15 * as a result of using, copying or modifying the software. 16 * 17 * $Id: tclexpat.c,v 1.15 2003/02/25 04:09:00 balls Exp $ 18 * 19 */ 20 21#include <tcl.h> 22#include "tclxml.h" 23#include <xmlparse.h> 24 25#undef TCL_STORAGE_CLASS 26#define TCL_STORAGE_CLASS DLLEXPORT 27 28/* 29 * The structure below is used to refer to an expat parser object. 30 */ 31 32typedef struct TclExpatInfo { 33 XML_Parser parser; /* The expat parser structure */ 34 Tcl_Interp *interp; /* Interpreter for this instance */ 35 36 TclXML_Info *xmlinfo; /* Generic data structure */ 37 38} TclExpatInfo; 39 40/* 41 * Prototypes for procedures defined later in this file: 42 */ 43 44static ClientData TclExpatCreate _ANSI_ARGS_((Tcl_Interp *interp, 45 TclXML_Info *xmlinfo)); 46static ClientData TclExpatCreateEntityParser _ANSI_ARGS_(( 47 Tcl_Interp *interp, ClientData clientData)); 48static int TclExpatDelete _ANSI_ARGS_((ClientData clientData)); 49static int TclExpatParse _ANSI_ARGS_((ClientData clientData, 50 char *data, int len, int final)); 51static int TclExpatConfigure _ANSI_ARGS_((ClientData clientdata, 52 int objc, Tcl_Obj *CONST objv[])); 53static int TclExpatCget _ANSI_ARGS_((ClientData clientData, 54 int objc, Tcl_Obj *CONST objv[])); 55static int TclExpatGet _ANSI_ARGS_((ClientData clientData, 56 int objc, Tcl_Obj *CONST objv[])); 57 58static void TclExpatElementStartHandler _ANSI_ARGS_(( 59 void *userData, 60 const XML_Char *name, 61 const XML_Char **atts)); 62static void TclExpatElementEndHandler _ANSI_ARGS_(( 63 void *userData, 64 const XML_Char *name)); 65static void TclExpatCharacterDataHandler _ANSI_ARGS_(( 66 void *userData, 67 const XML_Char *s, 68 int len)); 69static void TclExpatProcessingInstructionHandler _ANSI_ARGS_(( 70 void *userData, 71 const XML_Char *target, 72 const XML_Char *data)); 73static void TclExpatDefaultHandler _ANSI_ARGS_(( 74 void *userData, 75 const XML_Char *s, 76 int len)); 77static void TclExpatUnparsedDeclHandler _ANSI_ARGS_(( 78 void *userData, 79 const XML_Char *entityName, 80 const XML_Char *base, 81 const XML_Char *systemId, 82 const XML_Char *publicId, 83 const XML_Char *notationName)); 84static void TclExpatNotationDeclHandler _ANSI_ARGS_(( 85 void *userData, 86 const XML_Char *notationName, 87 const XML_Char *base, 88 const XML_Char *systemId, 89 const XML_Char *publicId)); 90static void TclExpatCommentHandler _ANSI_ARGS_(( 91 void *userData, 92 const XML_Char *data)); 93static int TclExpatNotStandaloneHandler _ANSI_ARGS_(( 94 void *userData)); 95static void TclExpatStartCdataSectionHandler _ANSI_ARGS_(( 96 void *userData)); 97static void TclExpatEndCdataSectionHandler _ANSI_ARGS_(( 98 void *userData)); 99static void TclExpatElementDeclHandler _ANSI_ARGS_(( 100 void *userData, 101 const XML_Char *name, 102 XML_Char ***contentspec)); 103static void TclExpatAttlistDeclHandler _ANSI_ARGS_(( 104 void *userData, 105 const XML_Char *name, 106 XML_Char ***attributes)); 107static void TclExpatStartDoctypeDeclHandler _ANSI_ARGS_(( 108 void *userData, 109 const XML_Char *doctypeName)); 110static void TclExpatEndDoctypeDeclHandler _ANSI_ARGS_(( 111 void *userData)); 112 113static int TclExpatExternalEntityRefHandler _ANSI_ARGS_(( 114 XML_Parser parser, 115 const XML_Char *context, 116 const XML_Char *base, 117 const XML_Char *systemId, 118 const XML_Char *publicId)); 119static int TclExpatUnknownEncodingHandler _ANSI_ARGS_(( 120 void *encodingHandlerData, 121 const XML_Char *name, 122 XML_Encoding *info 123)); 124 125EXTERN int Tclexpat_Init _ANSI_ARGS_((Tcl_Interp *interp)); 126 127/* 128 *---------------------------------------------------------------------------- 129 * 130 * Tclexpat_Init -- 131 * 132 * Initialisation routine for loadable module 133 * 134 * Results: 135 * None. 136 * 137 * Side effects: 138 * Registers xerces XML parser. 139 * 140 *---------------------------------------------------------------------------- 141 */ 142 143int 144Tclexpat_Init (interp) 145 Tcl_Interp *interp; /* Interpreter to initialise. */ 146{ 147 TclXML_ParserClassInfo *classinfo; 148 149#ifdef USE_TCL_STUBS 150 if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { 151 return TCL_ERROR; 152 } 153#endif 154#ifdef USE_TCLXML_STUBS 155 if (TclXML_InitStubs(interp, TCLXML_VERSION, 1) == NULL) { 156 return TCL_ERROR; 157 } 158#endif 159 160 classinfo = (TclXML_ParserClassInfo *) ckalloc(sizeof(TclXML_ParserClassInfo)); 161 classinfo->name = Tcl_NewStringObj("expat", -1); 162 classinfo->create = TclExpatCreate; 163 classinfo->createCmd = NULL; 164 classinfo->createEntity = TclExpatCreateEntityParser; 165 classinfo->createEntityCmd = NULL; 166 classinfo->parse = TclExpatParse; 167 classinfo->parseCmd = NULL; 168 classinfo->configure = TclExpatConfigure; 169 classinfo->configureCmd = NULL; 170 classinfo->get = TclExpatGet; 171 classinfo->getCmd = NULL; 172 classinfo->destroy = TclExpatDelete; 173 classinfo->destroyCmd = NULL; 174 classinfo->reset = NULL; 175 classinfo->resetCmd = NULL; 176 177 if (TclXML_RegisterXMLParser(interp, classinfo) != TCL_OK) { 178 Tcl_SetResult(interp, "unable to register parser", NULL); 179 return TCL_ERROR; 180 } 181 182 if (Tcl_PkgProvide(interp, "xml::expat", TCLXML_VERSION) != TCL_OK) { 183 return TCL_ERROR; 184 } 185 186 return TCL_OK; 187} 188 189/* 190 *---------------------------------------------------------------------------- 191 * 192 * TclExpatCreate -- 193 * 194 * Create an expat parser instance. 195 * 196 * Results: 197 * Standard Tcl result. 198 * 199 * Side effects: 200 * This creates an expat parser. 201 * 202 *---------------------------------------------------------------------------- 203 */ 204 205static ClientData 206TclExpatCreate(interp, xmlinfo) 207 Tcl_Interp *interp; 208 TclXML_Info *xmlinfo; 209{ 210 TclExpatInfo *expat; 211 212 /* 213 * Create the data structures for this parser. 214 */ 215 216 if (!(expat = (TclExpatInfo *) ckalloc(sizeof(TclExpatInfo)))) { 217 ckfree((char *)expat); 218 Tcl_SetResult(interp, "unable to create parser", NULL); 219 return NULL; 220 } 221 expat->interp = interp; 222 expat->xmlinfo = xmlinfo; 223 224 if (!(expat->parser = XML_ParserCreate(NULL))) { 225 Tcl_SetResult(interp, "unable to create expat parser", NULL); 226 ckfree((char *)expat); 227 return NULL; 228 } 229 230 /* 231 * Set all handlers for the parser. 232 */ 233 234 XML_SetElementHandler(expat->parser, TclExpatElementStartHandler, 235 TclExpatElementEndHandler); 236 XML_SetCharacterDataHandler(expat->parser, TclExpatCharacterDataHandler); 237 XML_SetProcessingInstructionHandler(expat->parser, 238 TclExpatProcessingInstructionHandler); 239 XML_SetDefaultHandler(expat->parser, TclExpatDefaultHandler); 240 241 XML_SetUnparsedEntityDeclHandler(expat->parser, 242 TclExpatUnparsedDeclHandler); 243 XML_SetNotationDeclHandler(expat->parser, TclExpatNotationDeclHandler); 244 245 XML_SetExternalEntityRefHandler(expat->parser, 246 TclExpatExternalEntityRefHandler); 247 248 XML_SetUnknownEncodingHandler(expat->parser, TclExpatUnknownEncodingHandler, 249 (void *) xmlinfo); 250 251 /* Added by ericm@scriptics.com, 1999.6.25 */ 252 /* Tell expat to use the TclExpat comment handler */ 253 XML_SetCommentHandler(expat->parser, TclExpatCommentHandler); 254 255 /* Tell expat to use the TclExpat "not standalone" handler */ 256 XML_SetNotStandaloneHandler(expat->parser, TclExpatNotStandaloneHandler); 257 258#ifdef TCLXML_CDATASECTIONS 259 /* Tell expat to use the TclExpat CdataSection handlers */ 260 XML_SetCdataSectionHandler(expat->parser, TclExpatStartCdataSectionHandler, 261 TclExpatEndCdataSectionHandler); 262#endif /* TCLXML_CDATASECTIONS */ 263 264 /* Tell expat to use the TclExpat Element decl handler */ 265 XML_SetElementDeclHandler(expat->parser, TclExpatElementDeclHandler); 266 267 /* Tell expat to use the TclExpat Attlist decl handler */ 268 XML_SetAttlistDeclHandler(expat->parser, TclExpatAttlistDeclHandler); 269 270 /* Tell expat to use the TclExpat DOCTYPE decl handlers */ 271 XML_SetDoctypeDeclHandler(expat->parser, 272 TclExpatStartDoctypeDeclHandler, 273 TclExpatEndDoctypeDeclHandler); 274 275 XML_SetUserData(expat->parser, (void *) expat); 276 277 return (ClientData) expat; 278} 279 280/* 281 *---------------------------------------------------------------------- 282 * 283 * TclExpatCreateEntity -- 284 * 285 * Create an expat entity parser, based on the original 286 * parser referred to by parent. 287 * 288 * Results: 289 * New external entity parser created and initialized. 290 * 291 * Side effects: 292 * The TclExpatInfo struct pointed to by expat is modified. 293 * 294 *---------------------------------------------------------------------- 295 */ 296 297static ClientData 298TclExpatCreateEntityParser(interp, clientData) 299 Tcl_Interp *interp; 300 ClientData clientData; 301{ 302 TclExpatInfo *parent = (TclExpatInfo *) clientData; 303 TclExpatInfo *expat; 304 305 if (!(expat = (TclExpatInfo *) ckalloc(sizeof(TclExpatInfo)))) { 306 ckfree((char *)expat); 307 Tcl_SetResult(interp, "unable to create parser", NULL); 308 return NULL; 309 } 310 expat->interp = parent->interp; 311 expat->xmlinfo = parent->xmlinfo; 312 313 if (!(expat->parser = XML_ExternalEntityParserCreate(parent->parser, 314 (XML_Char *) Tcl_GetUnicode(parent->xmlinfo->context), NULL))) { 315 Tcl_SetResult(interp, "unable to create expat external entity parser", 316 NULL); 317 return NULL; 318 } 319 320 XML_SetUserData(expat->parser, (void *) expat); 321 return (ClientData) expat; 322} 323 324/* 325 *---------------------------------------------------------------------------- 326 * 327 * TclExpatDelete -- 328 * 329 * Destroy the expat parser structure. 330 * 331 * Results: 332 * None. 333 * 334 * Side effects: 335 * Frees any memory allocated for the XML parser. 336 * 337 *---------------------------------------------------------------------------- 338 */ 339 340static int 341TclExpatDelete(clientData) 342 ClientData clientData; 343{ 344 TclExpatInfo *expat = (TclExpatInfo *) clientData; 345 346 XML_ParserFree(expat->parser); 347 ckfree((char *)expat); 348 349 return TCL_OK; 350} 351 352/* 353 *---------------------------------------------------------------------------- 354 * 355 * TclExpatParse -- 356 * 357 * Wrapper to invoke expat parser and check return result. 358 * 359 * Results: 360 * TCL_OK if no errors, TCL_ERROR otherwise. 361 * 362 * Side effects: 363 * Sets interpreter result as appropriate. 364 * 365 *---------------------------------------------------------------------------- 366 */ 367 368static int 369TclExpatParse(clientData, data, len, final) 370 ClientData clientData; 371 char *data; 372 int len; 373{ 374 TclExpatInfo *expat = (TclExpatInfo *) clientData; 375 int result; 376 char s[255]; 377 378 result = XML_Parse(expat->parser, 379 data, len, 380 final); 381 382 if (!result) { 383 Tcl_ResetResult(expat->interp); 384 sprintf(s, "%d", XML_GetCurrentLineNumber(expat->parser)); 385 Tcl_AppendResult(expat->interp, "error \"", 386 XML_ErrorString(XML_GetErrorCode(expat->parser)), 387 "\" at line ", s, " character ", NULL); 388 sprintf(s, "%d", XML_GetCurrentColumnNumber(expat->parser)); 389 Tcl_AppendResult(expat->interp, s, NULL); 390 391 return TCL_ERROR; 392 } 393 394 return TCL_OK; 395} 396 397/* 398 *---------------------------------------------------------------------------- 399 * 400 * TclExpatConfigure -- 401 * 402 * Implements instance command for expat class objects. 403 * 404 * Results: 405 * Depends on the method. 406 * 407 * Side effects: 408 * Depends on the method. 409 * 410 *---------------------------------------------------------------------------- 411 */ 412 413static int 414TclExpatConfigure (clientData, objc, objv) 415 ClientData clientData; 416 int objc; 417 Tcl_Obj *CONST objv[]; 418{ 419 TclExpatInfo *expat = (TclExpatInfo *) clientData; 420 421 static CONST84 char *switches[] = { 422 "-baseurl", 423 "-defaultexpandinternalentities", 424 "-paramentityparsing", 425 (char *) NULL 426 }; 427 enum switches { 428 EXPAT_BASE, 429 EXPAT_DEFAULTEXPANDINTERNALENTITIES, 430 EXPAT_PARAMENTITYPARSING, 431 }; 432 static CONST84 char *paramEntityParsingValues[] = { 433 "always", 434 "never", 435 "notstandalone" 436 }; 437 enum paramEntityParsingValues { 438 EXPAT_PARAMENTITYPARSINGALWAYS, 439 EXPAT_PARAMENTITYPARSINGNEVER, 440 EXPAT_PARAMENTITYPARSINGNOTSTANDALONE 441 }; 442 443 int index, value, bool; 444 Tcl_Obj *CONST *objPtr = objv; 445 446 while (objc > 1) { 447 if (Tcl_GetIndexFromObj(expat->interp, objPtr[0], switches, 448 "switch", 0, &index) != TCL_OK) { 449 Tcl_ResetResult(expat->interp); 450 return TCL_OK; 451 } 452 switch ((enum switches) index) { 453 454 case EXPAT_BASE: /* -base */ 455 456 if (XML_SetBase(expat->parser, (const XML_Char*)Tcl_GetString(objPtr[1])) == 0) { 457 Tcl_SetResult(expat->interp, "unable to set base URL", NULL); 458 return TCL_ERROR; 459 } 460 break; 461 462 case EXPAT_DEFAULTEXPANDINTERNALENTITIES: 463 464 /* -defaultexpandinternalentities */ 465 /* ericm@scriptics */ 466 if (Tcl_GetBooleanFromObj(expat->interp, objPtr[1], &bool) != TCL_OK) { 467 return TCL_ERROR; 468 } 469 470 XML_SetDefaultExpandInternalEntities(expat->parser, bool); 471 472 break; 473 474 case EXPAT_PARAMENTITYPARSING: /* -paramentityparsing */ 475 /* ericm@scriptics */ 476 if (Tcl_GetIndexFromObj(expat->interp, objPtr[1], paramEntityParsingValues, 477 "value", 0, &value) != TCL_OK) { 478 return TCL_ERROR; 479 } 480 switch ((enum paramEntityParsingValues) value) { 481 case EXPAT_PARAMENTITYPARSINGALWAYS: 482 XML_SetParamEntityParsing(expat->parser, 483 XML_PARAM_ENTITY_PARSING_ALWAYS); 484 break; 485 case EXPAT_PARAMENTITYPARSINGNEVER: 486 XML_SetParamEntityParsing(expat->parser, 487 XML_PARAM_ENTITY_PARSING_NEVER); 488 break; 489 case EXPAT_PARAMENTITYPARSINGNOTSTANDALONE: 490 XML_SetParamEntityParsing(expat->parser, 491 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); 492 break; 493 } 494 break; 495 496 default: 497 return TCL_OK; 498 break; 499 500 } 501 502 objPtr += 2; 503 objc -= 2; 504 505 } 506 507 return TCL_OK; 508} 509 510/* 511 *---------------------------------------------------------------------------- 512 * 513 * TclExpatGet -- 514 * 515 * Returns runtime parser information, depending on option 516 * ericm@scriptics.com, 1999.6.28 517 * 518 * Results: 519 * Option value. 520 * 521 * Side effects: 522 * None. 523 * 524 *---------------------------------------------------------------------------- 525 */ 526 527static int 528TclExpatGet (clientData, objc, objv) 529 ClientData clientData; 530 int objc; 531 Tcl_Obj *CONST objv[]; 532{ 533 TclExpatInfo *expat = (TclExpatInfo *) clientData; 534 static CONST84 char *switches[] = { 535 "-specifiedattributecount", 536 "-currentbytecount", 537 "-currentlinenumber", 538 "-currentcolumnnumber", 539 "-currentbyteindex", 540 (char *) NULL 541 }; 542 enum switches { 543 EXPAT_SPECIFIEDATTRCOUNT, 544 EXPAT_CURRENTBYTECOUNT, 545 EXPAT_CURRENTLINENUMBER, 546 EXPAT_CURRENTCOLUMNNUMBER, 547 EXPAT_CURRENTBYTEINDEX 548 }; 549 int index, doParse = 0; 550 Tcl_Obj *resultPtr; 551 552 if (objc > 1) { 553 Tcl_SetResult(expat->interp, "Only one value may be requested at a time", 554 TCL_STATIC); 555 return TCL_ERROR; 556 } 557 558 if (Tcl_GetIndexFromObj(expat->interp, objv[0], switches, 559 "switch", 0, &index) != TCL_OK) { 560 return TCL_ERROR; 561 } 562 563 resultPtr = Tcl_GetObjResult(expat->interp); 564 565 switch ((enum switches) index) { 566 567 case EXPAT_SPECIFIEDATTRCOUNT: 568 569 Tcl_SetIntObj(resultPtr, XML_GetSpecifiedAttributeCount(expat->parser)); 570 return TCL_OK; 571 break; 572 573 case EXPAT_CURRENTBYTECOUNT: 574 575 Tcl_SetIntObj(resultPtr, XML_GetCurrentByteCount(expat->parser)); 576 return TCL_OK; 577 break; 578 579 case EXPAT_CURRENTLINENUMBER: 580 581 Tcl_SetIntObj(resultPtr, XML_GetCurrentLineNumber(expat->parser)); 582 return TCL_OK; 583 break; 584 585 case EXPAT_CURRENTCOLUMNNUMBER: 586 587 Tcl_SetIntObj(resultPtr, XML_GetCurrentColumnNumber(expat->parser)); 588 return TCL_OK; 589 break; 590 591 case EXPAT_CURRENTBYTEINDEX: 592 593 Tcl_SetLongObj(resultPtr, XML_GetCurrentByteIndex(expat->parser)); 594 return TCL_OK; 595 break; 596 597 default: 598 599 return TCL_ERROR; 600 break; 601 } 602 603 return TCL_ERROR; 604} 605 606/* 607 *---------------------------------------------------------------------------- 608 * 609 * TclExpat*Handler -- 610 * 611 * Called by expat for various document features. 612 * 613 * Results: 614 * None. 615 * 616 * Side Effects: 617 * Event passed to TclXML generic layer. 618 * 619 *---------------------------------------------------------------------------- 620 */ 621 622static void TclExpatElementStartHandler(userdata, name, atts) 623 void *userdata; 624 const XML_Char *name; 625 const XML_Char **atts; 626{ 627 TclExpatInfo *expat = (TclExpatInfo *) userdata; 628 Tcl_Obj *attListObj; 629 int count; 630 631 attListObj = Tcl_NewListObj(0, NULL); 632 for (count = 0; atts[count]; count += 2) { 633 Tcl_ListObjAppendElement(NULL, attListObj, Tcl_NewStringObj((XML_Char*)atts[count], -1)); 634 Tcl_ListObjAppendElement(NULL, attListObj, Tcl_NewStringObj((XML_Char*)atts[count + 1], -1)); 635 } 636 637 TclXML_ElementStartHandler( 638 expat->xmlinfo, 639 Tcl_NewStringObj((XML_Char*)name, -1), 640 attListObj); 641} 642 643static void TclExpatElementEndHandler(userdata, name) 644 void *userdata; 645 const XML_Char *name; 646{ 647 TclExpatInfo *expat = (TclExpatInfo *) userdata; 648 649 TclXML_ElementEndHandler( 650 expat->xmlinfo, 651 Tcl_NewStringObj((XML_Char*)name, -1)); 652} 653 654static void TclExpatCharacterDataHandler(userdata, s, len) 655 void *userdata; 656 const XML_Char *s; 657 int len; 658{ 659 TclExpatInfo *expat = (TclExpatInfo *) userdata; 660 661 TclXML_CharacterDataHandler( 662 expat->xmlinfo, 663 Tcl_NewStringObj((XML_Char*)s, len)); 664} 665 666static void TclExpatProcessingInstructionHandler(userdata, target, data) 667 void *userdata; 668 const XML_Char *target; 669 const XML_Char *data; 670{ 671 TclExpatInfo *expat = (TclExpatInfo *) userdata; 672 673 TclXML_ProcessingInstructionHandler( 674 expat->xmlinfo, 675 Tcl_NewStringObj((XML_Char*)target, -1), 676 Tcl_NewStringObj((XML_Char*)data, -1)); 677} 678 679static void TclExpatDefaultHandler(userdata, s, len) 680 void *userdata; 681 const XML_Char *s; 682 int len; 683{ 684 TclExpatInfo *expat = (TclExpatInfo *) userdata; 685 686 TclXML_DefaultHandler( 687 expat->xmlinfo, 688 Tcl_NewStringObj((XML_Char*)s, len)); 689} 690 691static void TclExpatUnparsedDeclHandler(userdata, entityName, base, systemId, publicId, notationName) 692 void *userdata; 693 const XML_Char *entityName; 694 const XML_Char *base; 695 const XML_Char *systemId; 696 const XML_Char *publicId; 697 const XML_Char *notationName; 698{ 699 TclExpatInfo *expat = (TclExpatInfo *) userdata; 700 701 TclXML_UnparsedDeclHandler( 702 expat->xmlinfo, 703 Tcl_NewStringObj((XML_Char*)entityName, -1), 704 Tcl_NewStringObj((XML_Char*)base, -1), 705 Tcl_NewStringObj((XML_Char*)systemId, -1), 706 Tcl_NewStringObj((XML_Char*)publicId, -1), 707 Tcl_NewStringObj((XML_Char*)notationName, -1) 708 ); 709} 710 711static void TclExpatNotationDeclHandler(userdata, notationName, base, systemId, publicId) 712 void *userdata; 713 const XML_Char *notationName; 714 const XML_Char *base; 715 const XML_Char *systemId; 716 const XML_Char *publicId; 717{ 718 TclExpatInfo *expat = (TclExpatInfo *) userdata; 719 720 TclXML_NotationDeclHandler( 721 expat->xmlinfo, 722 Tcl_NewStringObj((XML_Char*)notationName, -1), 723 Tcl_NewStringObj((XML_Char*)base, -1), 724 Tcl_NewStringObj((XML_Char*)systemId, -1), 725 Tcl_NewStringObj((XML_Char*)publicId, -1) 726 ); 727} 728 729static void TclExpatCommentHandler(userdata, data) 730 void *userdata; 731 const XML_Char *data; 732{ 733 TclExpatInfo *expat = (TclExpatInfo *) userdata; 734 735 TclXML_CommentHandler( 736 expat->xmlinfo, 737 Tcl_NewStringObj((XML_Char*)data, -1)); 738} 739 740static int TclExpatNotStandaloneHandler(userdata) 741 void *userdata; 742{ 743 TclExpatInfo *expat = (TclExpatInfo *) userdata; 744 745 return TclXML_NotStandaloneHandler(expat->xmlinfo); 746} 747 748static void TclExpatStartCdataSectionHandler(userdata) 749 void *userdata; 750{ 751 TclExpatInfo *expat = (TclExpatInfo *) userdata; 752 753 /* 754 * TclXML makes no distinction between PCDATA and CDATA 755 */ 756} 757 758static void 759TclExpatEndCdataSectionHandler(userdata) 760 void *userdata; 761{ 762 TclExpatInfo *expat = (TclExpatInfo *) userdata; 763 764 /* 765 * TclXML makes no distinction between PCDATA and CDATA 766 */ 767} 768 769/* 770 *---------------------------------------------------------------------------- 771 * 772 * TclExpatExternalEntityRefHandler -- 773 * 774 * Called by expat for processing external entity references. 775 * 776 * Results: 777 * None. 778 * 779 * Side Effects: 780 * Callback script is invoked. 781 * 782 *---------------------------------------------------------------------------- 783 */ 784 785static int 786TclExpatExternalEntityRefHandler(parser, context, base, systemId, publicId) 787 XML_Parser parser; 788 const XML_Char *context; 789 const XML_Char *base; 790 const XML_Char *systemId; 791 const XML_Char *publicId; 792{ 793 TclExpatInfo *expat = (TclExpatInfo *) XML_GetUserData(parser); 794 795 TclXML_ExternalEntityRefHandler( 796 (ClientData) expat->xmlinfo, 797 Tcl_NewStringObj((XML_Char*)context, -1), 798 Tcl_NewStringObj((XML_Char*)base, -1), 799 Tcl_NewStringObj((XML_Char*)systemId, -1), 800 Tcl_NewStringObj((XML_Char*)publicId, -1)); 801 802 return 1; 803} 804 805/* 806 *---------------------------------------------------------------------------- 807 * 808 * TclExpatUnknownEncodingHandler -- 809 * 810 * Called by parser instance for processing a reference to a character in an 811 * unknown encoding. 812 * 813 * Results: 814 * None. 815 * 816 * Side Effects: 817 * Callback script is invoked. 818 * 819 *---------------------------------------------------------------------------- 820 */ 821 822static int 823TclExpatUnknownEncodingHandler(encodingHandlerData, name, info) 824 void *encodingHandlerData; 825 const XML_Char *name; 826 XML_Encoding *info; 827{ 828 int result; 829 830 result = TclXML_UnknownEncodingHandler( 831 encodingHandlerData, 832 Tcl_NewStringObj((XML_Char*)name, -1), 833 (ClientData) info); 834 835 return result; 836} 837 838static void TclExpatElementDeclHandler(userdata, name, contentspec) 839 void *userdata; 840 const XML_Char *name; 841 XML_Char ***contentspec; 842{ 843 TclExpatInfo *expat = (TclExpatInfo *) userdata; 844 Tcl_Obj *contentspecObj; 845 int count; 846 847 contentspecObj = Tcl_NewListObj(0, NULL); 848 for (count = 0; contentspec[0][count] != NULL; count++) { 849 Tcl_ListObjAppendElement(expat->interp, contentspecObj, Tcl_NewStringObj(contentspec[0][count], -1)); 850 } 851 852 TclXML_ElementDeclHandler( 853 expat->xmlinfo, 854 Tcl_NewStringObj((XML_Char*)name, -1), 855 contentspecObj); 856} 857 858static void TclExpatAttlistDeclHandler(userdata, name, attributes) 859 void *userdata; 860 const XML_Char *name; 861 XML_Char ***attributes; 862{ 863 TclExpatInfo *expat = (TclExpatInfo *) userdata; 864 Tcl_Obj *attdefnObj; 865 int count; 866 867 attdefnObj = Tcl_NewListObj(0, NULL); 868 for (count = 0; (*attributes)[count] != NULL; count++) { 869 Tcl_ListObjAppendElement(expat->interp, attdefnObj, Tcl_NewStringObj((*attributes)[count], -1)); 870 } 871 872 TclXML_AttlistDeclHandler( 873 expat->xmlinfo, 874 Tcl_NewStringObj((XML_Char*)name, -1), 875 attdefnObj); 876} 877 878static void TclExpatStartDoctypeDeclHandler(userdata, name) 879 void *userdata; 880 const XML_Char *name; 881{ 882 TclExpatInfo *expat = (TclExpatInfo *) userdata; 883 884 TclXML_StartDoctypeDeclHandler( 885 expat->xmlinfo, 886 Tcl_NewStringObj((XML_Char*)name, -1)); 887} 888 889static void TclExpatEndDoctypeDeclHandler(userdata) 890 void *userdata; 891{ 892 TclExpatInfo *expat = (TclExpatInfo *) userdata; 893 894 TclXML_EndDoctypeDeclHandler(expat->xmlinfo); 895} 896