From 5be9507b672e68aa4bc33768f56588674531a2bf Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 22 Jul 2020 08:50:32 +0200 Subject: Update to latest genx source --- libxsde/xsde/c/genx/LICENSE | 54 +++----- libxsde/xsde/c/genx/char-props.c | 5 +- libxsde/xsde/c/genx/genx.c | 292 +++++++++++++++++++++++++++++++++------ libxsde/xsde/c/genx/genx.h | 66 +++++++-- 4 files changed, 328 insertions(+), 89 deletions(-) diff --git a/libxsde/xsde/c/genx/LICENSE b/libxsde/xsde/c/genx/LICENSE index d50a401..6906d62 100644 --- a/libxsde/xsde/c/genx/LICENSE +++ b/libxsde/xsde/c/genx/LICENSE @@ -1,38 +1,22 @@ -Copyright (c) 2007-2020 Code Synthesis Tools CC. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -Original Version: +MIT License +Copyright (c) 2007-2020 Code Synthesis Tools CC. Copyright (c) Tim Bray and Sun Microsystems, 2004. -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libxsde/xsde/c/genx/char-props.c b/libxsde/xsde/c/genx/char-props.c index 94f4ddf..4359e1e 100644 --- a/libxsde/xsde/c/genx/char-props.c +++ b/libxsde/xsde/c/genx/char-props.c @@ -1,9 +1,8 @@ /* * Copyright (c) 2004 by Tim Bray and Sun Microsystems. - * Copyright (c) Code Synthesis Tools CC; see the accompanying LICENSE - * file for details. + * Copyright (c) Code Synthesis Tools CC (see the LICENSE file). * - * For copying permission, see the accompanying COPYING file. + * For copying permission, see the accompanying LICENSE file. */ /* diff --git a/libxsde/xsde/c/genx/genx.c b/libxsde/xsde/c/genx/genx.c index c7aac99..8fbecd8 100644 --- a/libxsde/xsde/c/genx/genx.c +++ b/libxsde/xsde/c/genx/genx.c @@ -1,27 +1,43 @@ /* * Copyright (c) 2004 by Tim Bray and Sun Microsystems. - * Copyright (c) Code Synthesis Tools CC; see the accompanying LICENSE - * file for details. + * Copyright (c) Code Synthesis Tools CC (see the LICENSE file). * - * For copying permission, see the accompanying COPYING file. + * For copying permission, see the accompanying LICENSE file. */ #include +#include + +#ifdef XSDE_SNPRINTF +# define GENX_SNPRINTF 1 +#else +# define GENX_SNPRINTF 0 +#endif + +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +# define GENX_CUSTOM_ALLOC xsde_alloc +# define GENX_CUSTOM_FREE xsde_free +#endif + #define GENX_VERSION "cs-1" +/* Use snprintf() unless instructed otherwise. */ +#ifndef GENX_SNPRINTF +# define GENX_SNPRINTF 1 +#endif + +#if defined(GENX_CUSTOM_ALLOC) != defined(GENX_CUSTOM_FREE) +# error both GENX_CUSTOM_ALLOC and GENX_CUSTOM_FREE must be defined +#endif + #include #include #include -#include - #include -#ifdef XSDE_CUSTOM_ALLOCATOR -# include -#endif - #define Boolean int #define True 1 #define False 0 @@ -89,7 +105,7 @@ struct genxNamespace_rec struct genxElement_rec { genxWriter writer; - utf8 type; + utf8 name; genxNamespace ns; }; @@ -140,6 +156,7 @@ struct genxWriter_rec /* Pretty-printing state */ int ppIndent; int ppDepth; + int ppSuspendDepth; /* Non-0 means we are suspended. */ Boolean ppSimple; /* Canonicalization. */ @@ -173,8 +190,8 @@ static void * allocate(genxWriter w, size_t bytes) if (w->alloc) return (void *) (*w->alloc)(w->userData, bytes); else -#ifdef XSDE_CUSTOM_ALLOCATOR - return (void *) xsde_alloc(bytes); +#ifdef GENX_CUSTOM_ALLOC + return (void *) GENX_CUSTOM_ALLOC(bytes); #else return (void *) malloc(bytes); #endif @@ -185,20 +202,24 @@ static void deallocate(genxWriter w, void * data) if (w->dealloc) (*w->dealloc)(w->userData, data); else if (w->alloc == NULL) -#ifdef XSDE_CUSTOM_ALLOCATOR - xsde_free(data); +#ifdef GENX_CUSTOM_FREE + GENX_CUSTOM_FREE(data); #else free(data); #endif + } static utf8 copy(genxWriter w, constUtf8 from) { utf8 temp; + size_t sl = strlen((const char *) from); - if ((temp = (utf8) allocate(w, strlen((const char *) from) + 1)) == NULL) + if ((temp = (utf8) allocate(w, sl + 1)) == NULL) return NULL; - strcpy((char *) temp, (const char *) from); + + memcpy(temp, from, sl); + temp[sl] = 0; return temp; } @@ -219,7 +240,7 @@ static genxStatus growCollector(genxWriter w, collector * c, size_t size) if ((newSpace = (utf8) allocate(w, c->space)) == NULL) return GENX_ALLOC_FAILED; - strncpy((char *) newSpace, (const char *) c->buf, c->used); + memcpy(newSpace, c->buf, c->used); newSpace[c->used] = 0; deallocate(w, c->buf); c->buf = newSpace; @@ -243,11 +264,13 @@ static genxStatus collectString(genxWriter w, collector * c, constUtf8 string) if ((w->status = growCollector(w, c, sl)) != GENX_SUCCESS) return GENX_ALLOC_FAILED; - strcpy((char *) c->buf, (const char *) string); + memcpy(c->buf, string, sl); + c->buf[sl] = 0; return GENX_SUCCESS; } -#define collectPiece(w,c,d,size) {if (((c)->used+(size))>=(c)->space){if (((w)->status=growCollector(w,c,(c)->used+(size)))!=GENX_SUCCESS) return (w)->status;}strncpy((char *)(c)->buf+(c)->used,d,size);(c)->used+=size;} +/* Note: does not add the trailing '\0' (done by endCollect() call). */ +#define collectPiece(w,c,d,size) {if (((c)->used+(size))>=(c)->space){if (((w)->status=growCollector(w,c,(c)->used+(size)))!=GENX_SUCCESS) return (w)->status;}memcpy((char *)(c)->buf+(c)->used,d,size);(c)->used+=size;} /******************************* * private list utilities @@ -333,7 +356,7 @@ static genxNamespace findNamespace(plist * pl, constUtf8 uri) return NULL; } -static genxElement findElement(plist * pl, constUtf8 xmlns, constUtf8 type) +static genxElement findElement(plist * pl, constUtf8 xmlns, constUtf8 name) { size_t i; genxElement * ee = (genxElement *) pl->pointers; @@ -342,15 +365,15 @@ static genxElement findElement(plist * pl, constUtf8 xmlns, constUtf8 type) { if (xmlns == NULL) { - if (ee[i]->ns == NULL && strcmp((const char *) type, - (const char *) ee[i]->type) == 0) + if (ee[i]->ns == NULL && strcmp((const char *) name, + (const char *) ee[i]->name) == 0) return ee[i]; } else { if (ee[i]->ns != NULL && strcmp((const char *) xmlns, (const char *) ee[i]->ns->name) == 0 && - strcmp((const char *) type, (const char *) ee[i]->type) == 0) + strcmp((const char *) name, (const char *) ee[i]->name) == 0) return ee[i]; } } @@ -373,7 +396,18 @@ static utf8 storePrefix(genxWriter w, constUtf8 prefix, Boolean force) prefix = (utf8) "xmlns"; else { - sprintf((char *) buf, "xmlns:%s", prefix); + size_t pl = strlen((const char *) prefix); + + if (pl > sizeof(buf) - (6 + 1)) + { + w->status = GENX_BAD_NAMESPACE_NAME; + return NULL; + } + + memcpy (buf, "xmlns:", 6); + memcpy (buf + 6, prefix, pl); + buf[pl + 6] = 0; + prefix = buf; } @@ -563,8 +597,8 @@ genxWriter genxNew(genxAlloc alloc, genxDealloc dealloc, void * userData) if (alloc) w = (genxWriter) (*alloc)(userData, sizeof(struct genxWriter_rec)); else -#ifdef XSDE_CUSTOM_ALLOCATOR - w = (genxWriter) xsde_alloc(sizeof(struct genxWriter_rec)); +#ifdef GENX_CUSTOM_ALLOC + w = (genxWriter) GENX_CUSTOM_ALLOC(sizeof(struct genxWriter_rec)); #else w = (genxWriter) malloc(sizeof(struct genxWriter_rec)); #endif @@ -714,6 +748,62 @@ int genxGetPrettyPrint(genxWriter w) } /* + * Suspend/resume pretty-printing. + */ +genxStatus genxSuspendPrettyPrint(genxWriter w) +{ + int d = w->ppDepth; + + if (w->ppIndent == 0) + return w->status = GENX_SEQUENCE_ERROR; + + switch (w->sequence) + { + case SEQUENCE_START_TAG: + case SEQUENCE_ATTRIBUTES: + d++; /* No start tag written, still outer depth. */ + case SEQUENCE_CONTENT: + break; + default: + return w->status = GENX_SEQUENCE_ERROR; + } + + if (w->ppSuspendDepth == 0) /* Ignore nested suspend/resume calls. */ + w->ppSuspendDepth = d; + + return w->status; +} + +genxStatus genxResumePrettyPrint(genxWriter w) +{ + int d = w->ppDepth; + + if (w->ppIndent == 0 || w->ppSuspendDepth == 0) + return w->status = GENX_SEQUENCE_ERROR; + + switch (w->sequence) + { + case SEQUENCE_START_TAG: + case SEQUENCE_ATTRIBUTES: + d++; /* No start tag written, still outer depth. */ + case SEQUENCE_CONTENT: + break; + default: + return w->status = GENX_SEQUENCE_ERROR; + } + + if (w->ppSuspendDepth == d) /* Ignore nested suspend/resume calls. */ + w->ppSuspendDepth = 0; + + return w->status; +} + +int genxPrettyPrintSuspended(genxWriter w) +{ + return w->ppSuspendDepth; +} + +/* * get/set canonicalization. */ genxStatus genxSetCanonical(genxWriter w, int flag) @@ -773,7 +863,7 @@ void genxDispose(genxWriter w) for (i = 0; i < w->elements.count; i++) { - deallocate(w, ee[i]->type); + deallocate(w, ee[i]->name); deallocate(w, ee[i]); } @@ -947,11 +1037,14 @@ genxNamespace genxDeclareNamespace(genxWriter w, constUtf8 uri, /* wasn't already declared */ else { - /* make a default prefix if none provided */ if (defaultPref == NULL) { +#if GENX_SNPRINTF + snprintf((char *) newPrefix, sizeof(newPrefix), "g%d", w->nextPrefix++); +#else sprintf((char *) newPrefix, "g%d", w->nextPrefix++); +#endif defaultPref = newPrefix; } @@ -1030,20 +1123,20 @@ utf8 genxGetNamespacePrefix(genxNamespace ns) * DeclareElement - see genx.h for details */ genxElement genxDeclareElement(genxWriter w, - genxNamespace ns, constUtf8 type, + genxNamespace ns, constUtf8 name, genxStatus * statusP) { genxElement old; genxElement el; - if ((w->status = checkNCName(w, type)) != GENX_SUCCESS) + if ((w->status = checkNCName(w, name)) != GENX_SUCCESS) { *statusP = w->status; return NULL; } /* already declared? */ - old = findElement(&w->elements, (ns == NULL) ? NULL : ns->name, type); + old = findElement(&w->elements, (ns == NULL) ? NULL : ns->name, name); if (old) return old; @@ -1055,7 +1148,7 @@ genxElement genxDeclareElement(genxWriter w, el->writer = w; el->ns = ns; - if ((el->type = copy(w, type)) == NULL) + if ((el->name = copy(w, name)) == NULL) { w->status = *statusP = GENX_ALLOC_FAILED; return NULL; @@ -1238,8 +1331,9 @@ genxStatus genxStartDocSender(genxWriter w, genxSender * sender) if (w->ppIndent) { - w->ppSimple = True; w->ppDepth = 0; + w->ppSuspendDepth = 0; + w->ppSimple = True; } return GENX_SUCCESS; @@ -1313,7 +1407,9 @@ static genxStatus writeStartTag(genxWriter w, Boolean close) if (w->ppIndent) { - if (w->ppDepth) + if (w->ppDepth && + /* Suspend depth could be at this element's depth (after ++ below). */ + (w->ppSuspendDepth == 0 || w->ppSuspendDepth > w->ppDepth)) if (writeIndentation (w) != GENX_SUCCESS) return w->status; @@ -1322,6 +1418,15 @@ static genxStatus writeStartTag(genxWriter w, Boolean close) w->ppDepth++; w->ppSimple = True; } + else + { + /* + * Conceptually we incremented/decremented the depth, so check if we + * need to resume pretty-printing. + */ + if (w->ppSuspendDepth > w->ppDepth) + w->ppSuspendDepth = 0; + } } SendCheck(w, "<"); @@ -1330,7 +1435,7 @@ static genxStatus writeStartTag(genxWriter w, Boolean close) SendCheck(w, e->ns->declaration->name + STRLEN_XMLNS_COLON); SendCheck(w, ":"); } - SendCheck(w, e->type); + SendCheck(w, e->name); /* If we are canonicalizing, then write sorted attributes. Otherwise write them in the order specified. */ @@ -1732,6 +1837,22 @@ genxStatus genxStartAttribute(genxAttribute a) return GENX_SUCCESS; } +genxStatus genxGetCurrentAttribute (genxWriter w, + constUtf8* xmlns, constUtf8* name) +{ + genxAttribute a; + + if (w->sequence != SEQUENCE_START_ATTR) + return w->status = GENX_SEQUENCE_ERROR; + + a = w->nowStartingAttr; + + *xmlns = a->ns ? a->ns->name : NULL; + *name = a->name; + + return GENX_SUCCESS; +} + genxStatus genxEndAttribute(genxWriter w) { genxAttribute a; @@ -1765,6 +1886,36 @@ genxStatus genxEndAttribute(genxWriter w) return GENX_SUCCESS; } +genxStatus genxGetCurrentElement (genxWriter w, + constUtf8* xmlns, constUtf8* name) +{ + int i; + genxElement e; + + switch (w->sequence) + { + case SEQUENCE_START_TAG: + case SEQUENCE_ATTRIBUTES: + e = w->nowStarting; + break; + case SEQUENCE_CONTENT: + /* Find the element. The same code as in EndElement() below. */ + for (i = (int) (w->stack.count) - 1; + w->stack.pointers[i] != NULL; + i -= 2) + ; + e = (genxElement) w->stack.pointers[--i]; + break; + default: + return w->status = GENX_SEQUENCE_ERROR; + } + + *xmlns = e->ns ? e->ns->name : NULL; + *name = e->name; + + return GENX_SUCCESS; +} + genxStatus genxEndElement(genxWriter w) { int i; @@ -1810,9 +1961,12 @@ genxStatus genxEndElement(genxWriter w) { w->ppDepth--; - if (!w->ppSimple) + if (!w->ppSimple && w->ppSuspendDepth == 0) if (writeIndentation (w) != GENX_SUCCESS) return w->status; + + if (w->ppSuspendDepth > w->ppDepth) + w->ppSuspendDepth = 0; /* Resume pretty-printing. */ } SendCheck(w, "ns->declaration->name + STRLEN_XMLNS_COLON); SendCheck(w, ":"); } - SendCheck(w, e->type); + SendCheck(w, e->name); SendCheck(w, ">"); } - if (w->ppIndent) + /* If this element is written while pretty-printing is suspended, + treat it as simple. As an example, think of an XHTML element + for which we suspend pretty-printing before writing the opening + tag and resume it after the closing one. */ + if (w->ppIndent && w->ppSuspendDepth == 0) w->ppSimple = False; /* @@ -2118,7 +2276,7 @@ genxStatus genxEndDocument(genxWriter w) return w->status = GENX_SEQUENCE_ERROR; /* Write a newline after the closing tag. */ - /* Disabled for xsde SendCheck (w, "\n");*/ + /* Disabled for xsde: SendCheck (w, "\n"); */ if ((w->status = (*w->sender->flush)(w->userData)) != GENX_SUCCESS) return w->status; @@ -2164,6 +2322,58 @@ genxStatus genxXmlDeclaration(genxWriter w, return GENX_SUCCESS; } +genxStatus genxDoctypeDeclaration(genxWriter w, + constUtf8 re, + constUtf8 pi, + constUtf8 si, + constUtf8 is) +{ + if (w->sequence != SEQUENCE_PRE_DOC) + return w->status = GENX_SEQUENCE_ERROR; + + if ((w->status = genxCheckText(w, re)) != GENX_SUCCESS) + return w->status; + + if (pi != NULL && (w->status = genxCheckText(w, pi)) != GENX_SUCCESS) + return w->status; + + if (si != NULL && (w->status = genxCheckText(w, si)) != GENX_SUCCESS) + return w->status; + + if (is != NULL && (w->status = genxCheckText(w, is)) != GENX_SUCCESS) + return w->status; + + SendCheck (w, "\n"); + return GENX_SUCCESS; +} + genxStatus genxComment(genxWriter w, constUtf8 text) { size_t i; @@ -2272,7 +2482,7 @@ genxStatus genxPI(genxWriter w, constUtf8 target, constUtf8 text) * Literal versions of the writing routines */ genxStatus genxStartElementLiteral(genxWriter w, - constUtf8 xmlns, constUtf8 type) + constUtf8 xmlns, constUtf8 name) { genxNamespace ns = NULL; genxElement e; @@ -2283,7 +2493,7 @@ genxStatus genxStartElementLiteral(genxWriter w, if (ns == NULL || w->status != GENX_SUCCESS) return w->status; } - e = genxDeclareElement(w, ns, type, &w->status); + e = genxDeclareElement(w, ns, name, &w->status); if (e == NULL || w->status != GENX_SUCCESS) return w->status; diff --git a/libxsde/xsde/c/genx/genx.h b/libxsde/xsde/c/genx/genx.h index 246d7a6..041815f 100644 --- a/libxsde/xsde/c/genx/genx.h +++ b/libxsde/xsde/c/genx/genx.h @@ -4,10 +4,9 @@ /* * Copyright (c) 2004 by Tim Bray and Sun Microsystems. - * Copyright (c) Code Synthesis Tools CC; see the accompanying LICENSE - * file for details. + * Copyright (c) Code Synthesis Tools CC (see the LICENSE file). * - * For copying permission, see the accompanying COPYING file. + * For copying permission, see the accompanying LICENSE file. */ #ifndef GENX_H @@ -119,6 +118,24 @@ genxStatus genxSetPrettyPrint(genxWriter w, int indentation); int genxGetPrettyPrint(genxWriter w); /* + * Suspend/resume pretty-printing. Pretty-printing can be suspended + * only inside an element and, unless explicitly resumed, it will + * remain suspended until the end of that element. You should only + * explicitly resume pretty-printing at the element nesting level + * of suspension. If pretty-printing is already suspended at an + * outer nesting level, then subsequent calls to suspend/resume + * are ignored. The PrettyPrintSuspended() function can be used + * to check if pretty-printing is currently suspended. If it is + * not, then this function returns 0. Otherwise, it returns the + * level at which pretty-printing was suspended, with root element + * being level 1. + */ +genxStatus genxSuspendPrettyPrint(genxWriter w); +genxStatus genxResumePrettyPrint(genxWriter w); +int genxPrettyPrintSuspended(genxWriter w); + + +/* * Set/get canonicalization. If true, then output explicit closing * tags and sort attributes. Default is false. */ @@ -163,7 +180,7 @@ genxNamespace genxDeclareNamespace(genxWriter w, * If something failed, returns NULL and sets the status code via statusP */ genxElement genxDeclareElement(genxWriter w, - genxNamespace ns, constUtf8 type, + genxNamespace ns, constUtf8 name, genxStatus * statusP); /* @@ -193,7 +210,7 @@ typedef struct genxStatus genxStartDocSender(genxWriter w, genxSender * sender); /* - * End a document. Calls "flush" + * End a document. Calls "flush". */ genxStatus genxEndDocument(genxWriter w); @@ -206,6 +223,19 @@ genxStatus genxXmlDeclaration(genxWriter w, constUtf8 encoding, constUtf8 standalone); /* + * Write DOCTYPE declaration. If public_id is not NULL, then this is + * a PUBLIC DOCTYPE declaration, otherwise, if system_id is not NULL, + * then this is a SYSTEM DOCTYPE. If both are NULL, then a DOCTYPE + * that only contains the root element and, if not NULL, internal + * subset is written. + */ +genxStatus genxDoctypeDeclaration(genxWriter w, + constUtf8 root_element, + constUtf8 public_id, + constUtf8 system_id, + constUtf8 internal_subset); + +/* * Write a comment */ genxStatus genxComment(genxWriter w, constUtf8 text); @@ -219,7 +249,7 @@ genxStatus genxPI(genxWriter w, constUtf8 target, constUtf8 text); * Start an element */ genxStatus genxStartElementLiteral(genxWriter w, - constUtf8 xmlns, constUtf8 type); + constUtf8 xmlns, constUtf8 name); /* * Start a predeclared element @@ -228,26 +258,42 @@ genxStatus genxStartElementLiteral(genxWriter w, genxStatus genxStartElement(genxElement e); /* + * Get current element. The returned values are valid until this + * element ceases to be current (i.e., EndElement() is called). + * If the element is unqualified, then xmlns is set to NULL. + */ +genxStatus genxGetCurrentElement (genxWriter w, + constUtf8* xmlns, constUtf8* name); + +/* * Write an attribute */ genxStatus genxAddAttributeLiteral(genxWriter w, constUtf8 xmlns, constUtf8 name, constUtf8 value); /* + * Write a predeclared attribute + */ +genxStatus genxAddAttribute(genxAttribute a, constUtf8 value); + +/* * Start an attribute */ genxStatus genxStartAttributeLiteral(genxWriter w, constUtf8 xmlns, constUtf8 name); /* - * Write a predeclared attribute + * Start a predeclared attribute */ -genxStatus genxAddAttribute(genxAttribute a, constUtf8 value); +genxStatus genxStartAttribute(genxAttribute a); /* - * Start a predeclared attribute + * Get current attribute. The returned values are valid until this + * attribute ceases to be current (i.e., EndAttribute() is called). + * If the attribute is unqualified, then xmlns is set to NULL. */ -genxStatus genxStartAttribute(genxAttribute a); +genxStatus genxGetCurrentAttribute (genxWriter w, + constUtf8* xmlns, constUtf8* name); /* * End an attribute -- cgit v1.1