expatapi(3tcl)

πŸ“¦
version 0.9.6 Β· 2 versions
, in debian trixie, ubuntu questing, ubuntu resolute, ubuntu stonking

✨ expatapi ✨

okay bestie, so this is the expatapi page from the Tcl manual (section 3tcl, iykyk) β€” it's all about the C-level glue that lets you bolt your own event handlers onto tDOM Tcl expat parser objects. no cap, it's giving ✨extension author✨ energy and honestly? iconic.


πŸ’– NAME πŸ’–

CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove, CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo β€” these are the functions that create, install and remove expat parser object extensions. periodt. πŸŽ€


🌸 SYNOPSIS 🌸

#include <tclexpat.h>

int
CheckExpatParserObj (interp, nameObj)

int
CHandlerSetInstall (interp, expatObj, handlerSet)

int
CHandlerSetRemove (interp, expatObj, handlerSetName)

CHandlerSet*
CHandlerSetCreate (handlerSetName)

CHandlerSet*
CHandlerSetGet (interp, expatObj, handlerSetName)

void*
CHandlerSetGetUserData (interp, expatObj, handlerSetName)

TclGenExpatInfo*
GetExpatInfo (interp, expatObj)

πŸ¦‹ ARGUMENTS πŸ¦‹

  • Tcl_Interp *interp (in) β€” the interpreter that's holding your expat parser object. she's the main character, everything happens in her. πŸ’…
  • Tcl_Obj *expatObj (in) β€” a Tcl Object holding the command name of the expat parser object you wanna query or mess with.
  • char *handlerSetName (in) β€” the identifier of the handler set. basically her name tag at the party. πŸŽ€
  • CHandlerSet *handlerSet (in) β€” a pointer to a C handler set. the whole squad, in struct form.
  • Tcl_Obj *nameObj β€” a Tcl Object holding the name of a expat parser object. (no (in) tag on this one, we're just vibing.)

🌈 DESCRIPTION 🌈

so the functions on this page let you add C level coded event handlers to a tDOM Tcl expat parser object. and here's the cute part: a single tDOM Tcl expat parser object can have several Tcl scripts and C functions associated with one specific event. when that event happens? first the Tcl scripts get called, then the C functions β€” in turn. no skipping, no cutting the line. πŸ’…

A tDOM Tcl expat parser extension is just an ordinary Tcl extension, loaded like every other Tcl extension. it must install at least one new Tcl Level command that manipulates a tDOM Tcl expat parser object. that's the whole assignment. ✨

A C level handler set is a data structure that looks like this:

typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extension has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;

    /* C func for element start */
    XML_StartElementHandler          elementstartcommand;
    /* C func for element end */
    XML_EndElementHandler            elementendcommand;
    /* C func for character data */
    XML_CharacterDataHandler         datacommand;
    /* C func for namespace decl start */
    XML_StartNamespaceDeclHandler    startnsdeclcommand;
    /* C func for namespace decl end */
    XML_EndNamespaceDeclHandler      endnsdeclcommand;
    /* C func for processing instruction */
    XML_ProcessingInstructionHandler picommand;
    /* C func for default data */
    XML_DefaultHandler               defaultcommand;
    /* C func for unparsed entity declaration */
    XML_NotationDeclHandler          notationcommand;
    /* C func for external entity */
    XML_ExternalEntityRefHandler     externalentitycommand;
    /* C func for unknown encoding */
    XML_UnknownEncodingHandler       unknownencodingcommand;
    /* C func for comments */
    XML_CommentHandler               commentCommand;
    /* C func for "not standalone" docs */
    XML_NotStandaloneHandler         notStandaloneCommand;
    /* C func for CDATA section start */
    XML_StartCdataSectionHandler     startCdataSectionCommand;
    /* C func for CDATA section end */
    XML_EndCdataSectionHandler       endCdataSectionCommand;
    /* C func for !ELEMENT decl's */
    XML_ElementDeclHandler           elementDeclCommand;
    /* C func for !ATTLIST decl's */
    XML_AttlistDeclHandler           attlistDeclCommand;
    /* C func for !DOCTYPE decl's */
    XML_StartDoctypeDeclHandler      startDoctypeDeclCommand;
    /* C func for !DOCTYPE decl ends */
    XML_EndDoctypeDeclHandler        endDoctypeDeclCommand;
    /* C func for !ENTITY decls's */
    XML_EntityDeclHandler            entityDeclCommand;
} CHandlerSet;

the types and the arguments of those event functions (the XML_* ones) are exactly the same as the expat lib handler functions, and they're described in detail in expat.h β€” go look, bestie, fr fr. your extension only has to provide the handler functions you actually need; leaving unused handler slots alone is perfectly OK because CHandlerSetCreate initializes them all to NULL. πŸ™ˆ

the name of this structure is what identifies the handler set. that's her whole identity.

if the flag ignoreWhiteCDATAs is set, then element content that contains only whitespace isn't reported with the datacommand. simple as. ✨

the userData element points to the handler set specific data. the event handler functions get called with this pointer as their userData argument. 🫢

resetProc and freeProc must have arguments that match the type

void (Tcl_Interp *interp, void *userData)

resetProc gets called when the parser is reset with <parserObj> reset, and it should do any necessary cleanup and reinitializing to get the C handler set ready for a brand new XML document. the freeProc gets called if the parser is deleted, and it should do memory cleanup etc. don't leave her hanging, okay? 😭


CHandlerSetCreate creates a C handler set, gives it the name name, and initializes any other element with NULL. fresh out the box. πŸŽ€

CHandlerSetInstall adds the handlerSet to the parser expatObj. the parser has to be a tDOM Tcl expat parser object in the interpreter interp. the name of the C handler set has to be unique for the parser. she doesn't do duplicates, periodt. return values:

  • returns 0 in case of success πŸŽ‰
  • returns 1 if expatObj isn't a parser object in the interpreter interp
  • returns 2 if this parser has already got a C handler set with the handlerSet name

CHandlerSetRemove removes the C handler set referenced by the handlerSetName from the parser expatObj. the parser has to be a tDOM Tcl expat parser object in the interpreter interp. CHandlerSetRemove calls the freeProc function of the C handler set structure, removes the handler set from the C handler set list, and frees the handler structure. it's a full send-off. πŸ¦‹ return values:

  • returns 0 in case of success
  • returns 1 if expatObj isn't a parser object in the interpreter interp
  • returns 2 if this parser hasn't got a C handler set named handlerSetName

CheckExpatParserObj returns 1 if nameObj is a tDOM Tcl expat parser object in the interpreter interp, otherwise it returns 0. vibe check complete. βœ… example:

int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *const objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;

    static char *exampleMethods[] = {
        "enable", "getresult", "remove",
        NULL
    };
    enum exampleMethod {
        m_enable, m_getresult, m_remove
    };

    if (objc != 3) {
        Tcl_WrongNumArgs (interp, 1, objv, example_usage);
        return TCL_ERROR;
    }

    if (!CheckExpatParserObj (interp, objv[1])) {
        Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
        return TCL_ERROR;
    }
    /* ... */

CHandlerSetGet returns a pointer to the C handler Set referenced by the name handlerSetName of the parser object expatObj. expatObj has to be an expat parser object in the interpreter interp. returns NULL in case of error. (sad but honest. 😭)

CHandlerSetGetUserData returns a pointer to the userData of the C handler set referenced by the name handlerSetName of the parser object expatObj. expatObj has to be an expat parser object in the interpreter interp. returns NULL in case of error.

GetExpatInfo is a helper function that returns a pointer to the TclGenExpatInfo structure of the tDOM Tcl expat parser object expatObj. the expatObj has to be a tDOM Tcl expat parser object in the interpreter interp. this is most useful for setting the application status of the parser object. πŸ’…


there's a simple but full functionally example in the extensions/example dir, plus a more complex example tnc in the extensions/tnc dir (a simple DTD validation extension). go peek, bestie, they ate. πŸ”₯

🌟 SEE ALSO 🌟

  • expat

πŸ‘‘ KEYWORDS πŸ‘‘

  • C handler set

and that's the whole page, bestie 🫢 β€” brought to you by Tcl, filed under expatapi(3tcl). go forth and write unhinged little expat extensions, you've got this. πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from