Annotation of XML/parser.c, revision 1.149

1.1       veillard    1: /*
1.3       veillard    2:  * parser.c : an XML 1.0 non-verifying parser
1.15      veillard    3:  *
                      4:  * See Copyright for the status of this software.
                      5:  *
1.60      daniel      6:  * Daniel.Veillard@w3.org
1.1       veillard    7:  */
                      8: 
1.26      daniel      9: #ifdef WIN32
1.138     daniel     10: #include "win32config.h"
1.26      daniel     11: #else
1.121     daniel     12: #include "config.h"
1.26      daniel     13: #endif
1.121     daniel     14: 
1.1       veillard   15: #include <stdio.h>
1.121     daniel     16: #include <string.h> /* for memset() only */
                     17: #ifdef HAVE_CTYPE_H
1.1       veillard   18: #include <ctype.h>
1.121     daniel     19: #endif
                     20: #ifdef HAVE_STDLIB_H
1.50      daniel     21: #include <stdlib.h>
1.121     daniel     22: #endif
                     23: #ifdef HAVE_SYS_STAT_H
1.9       httpng     24: #include <sys/stat.h>
1.121     daniel     25: #endif
1.9       httpng     26: #ifdef HAVE_FCNTL_H
                     27: #include <fcntl.h>
                     28: #endif
1.10      httpng     29: #ifdef HAVE_UNISTD_H
                     30: #include <unistd.h>
                     31: #endif
1.20      daniel     32: #ifdef HAVE_ZLIB_H
                     33: #include <zlib.h>
                     34: #endif
1.1       veillard   35: 
1.119     daniel     36: #include "xmlmemory.h"
1.14      veillard   37: #include "tree.h"
1.1       veillard   38: #include "parser.h"
1.14      veillard   39: #include "entities.h"
1.75      daniel     40: #include "encoding.h"
1.61      daniel     41: #include "valid.h"
1.69      daniel     42: #include "parserInternals.h"
1.91      daniel     43: #include "xmlIO.h"
1.122     daniel     44: #include "xml-error.h"
1.1       veillard   45: 
1.140     daniel     46: #define XML_PARSER_BIG_BUFFER_SIZE 1000
                     47: #define XML_PARSER_BUFFER_SIZE 100
                     48: 
1.86      daniel     49: const char *xmlParserVersion = LIBXML_VERSION;
                     50: 
1.139     daniel     51: /*
                     52:  * List of XML prefixed PI allowed by W3C specs
                     53:  */
                     54: 
                     55: const char *xmlW3CPIs[] = {
                     56:     "xml-stylesheet",
                     57:     NULL
                     58: };
1.91      daniel     59: 
                     60: /************************************************************************
                     61:  *                                                                     *
                     62:  *             Input handling functions for progressive parsing        *
                     63:  *                                                                     *
                     64:  ************************************************************************/
                     65: 
                     66: /* #define DEBUG_INPUT */
1.140     daniel     67: /* #define DEBUG_STACK */
                     68: /* #define DEBUG_PUSH */
                     69: 
1.91      daniel     70: 
1.110     daniel     71: #define INPUT_CHUNK    250
                     72: /* we need to keep enough input to show errors in context */
                     73: #define LINE_LEN        80
1.91      daniel     74: 
                     75: #ifdef DEBUG_INPUT
                     76: #define CHECK_BUFFER(in) check_buffer(in)
                     77: 
                     78: void check_buffer(xmlParserInputPtr in) {
                     79:     if (in->base != in->buf->buffer->content) {
                     80:         fprintf(stderr, "xmlParserInput: base mismatch problem\n");
                     81:     }
                     82:     if (in->cur < in->base) {
                     83:         fprintf(stderr, "xmlParserInput: cur < base problem\n");
                     84:     }
                     85:     if (in->cur > in->base + in->buf->buffer->use) {
                     86:         fprintf(stderr, "xmlParserInput: cur > base + use problem\n");
                     87:     }
                     88:     fprintf(stderr,"buffer %x : content %x, cur %d, use %d, size %d\n",
                     89:             (int) in, (int) in->buf->buffer->content, in->cur - in->base,
                     90:            in->buf->buffer->use, in->buf->buffer->size);
                     91: }
                     92: 
1.110     daniel     93: #else
                     94: #define CHECK_BUFFER(in) 
                     95: #endif
                     96: 
1.91      daniel     97: 
                     98: /**
                     99:  * xmlParserInputRead:
                    100:  * @in:  an XML parser input
                    101:  * @len:  an indicative size for the lookahead
                    102:  *
                    103:  * This function refresh the input for the parser. It doesn't try to
                    104:  * preserve pointers to the input buffer, and discard already read data
                    105:  *
1.123     daniel    106:  * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
1.91      daniel    107:  * end of this entity
                    108:  */
                    109: int
                    110: xmlParserInputRead(xmlParserInputPtr in, int len) {
                    111:     int ret;
                    112:     int used;
                    113:     int index;
                    114: 
                    115: #ifdef DEBUG_INPUT
                    116:     fprintf(stderr, "Read\n");
                    117: #endif
                    118:     if (in->buf == NULL) return(-1);
                    119:     if (in->base == NULL) return(-1);
                    120:     if (in->cur == NULL) return(-1);
                    121:     if (in->buf->buffer == NULL) return(-1);
                    122: 
                    123:     CHECK_BUFFER(in);
                    124: 
                    125:     used = in->cur - in->buf->buffer->content;
                    126:     ret = xmlBufferShrink(in->buf->buffer, used);
                    127:     if (ret > 0) {
                    128:        in->cur -= ret;
                    129:        in->consumed += ret;
                    130:     }
                    131:     ret = xmlParserInputBufferRead(in->buf, len);
                    132:     if (in->base != in->buf->buffer->content) {
                    133:         /*
                    134:         * the buffer has been realloced
                    135:         */
                    136:        index = in->cur - in->base;
                    137:        in->base = in->buf->buffer->content;
                    138:        in->cur = &in->buf->buffer->content[index];
                    139:     }
                    140: 
                    141:     CHECK_BUFFER(in);
                    142: 
                    143:     return(ret);
                    144: }
                    145: 
                    146: /**
                    147:  * xmlParserInputGrow:
                    148:  * @in:  an XML parser input
                    149:  * @len:  an indicative size for the lookahead
                    150:  *
                    151:  * This function increase the input for the parser. It tries to
                    152:  * preserve pointers to the input buffer, and keep already read data
                    153:  *
1.123     daniel    154:  * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
1.91      daniel    155:  * end of this entity
                    156:  */
                    157: int
                    158: xmlParserInputGrow(xmlParserInputPtr in, int len) {
                    159:     int ret;
                    160:     int index;
                    161: 
                    162: #ifdef DEBUG_INPUT
                    163:     fprintf(stderr, "Grow\n");
                    164: #endif
                    165:     if (in->buf == NULL) return(-1);
                    166:     if (in->base == NULL) return(-1);
                    167:     if (in->cur == NULL) return(-1);
                    168:     if (in->buf->buffer == NULL) return(-1);
                    169: 
                    170:     CHECK_BUFFER(in);
                    171: 
                    172:     index = in->cur - in->base;
                    173:     if (in->buf->buffer->use > index + INPUT_CHUNK) {
                    174: 
                    175:        CHECK_BUFFER(in);
                    176: 
                    177:         return(0);
                    178:     }
1.148     daniel    179:     if ((in->buf->httpIO != NULL) || (in->buf->ftpIO != NULL) ||
                    180:        (in->buf->file != NULL) ||
1.140     daniel    181: #ifdef HAVE_ZLIB_H
                    182:         (in->buf->gzfile != NULL) ||
                    183: #endif
                    184:         (in->buf->fd >= 0))
                    185:        ret = xmlParserInputBufferGrow(in->buf, len);
                    186:     else       
                    187:         return(0);
1.135     daniel    188: 
                    189:     /*
                    190:      * NOTE : in->base may be a "dandling" i.e. freed pointer in this
                    191:      *        block, but we use it really as an integer to do some
                    192:      *        pointer arithmetic. Insure will raise it as a bug but in
                    193:      *        that specific case, that's not !
                    194:      */
1.91      daniel    195:     if (in->base != in->buf->buffer->content) {
                    196:         /*
                    197:         * the buffer has been realloced
                    198:         */
                    199:        index = in->cur - in->base;
                    200:        in->base = in->buf->buffer->content;
                    201:        in->cur = &in->buf->buffer->content[index];
                    202:     }
                    203: 
                    204:     CHECK_BUFFER(in);
                    205: 
                    206:     return(ret);
                    207: }
                    208: 
                    209: /**
                    210:  * xmlParserInputShrink:
                    211:  * @in:  an XML parser input
                    212:  *
                    213:  * This function removes used input for the parser.
                    214:  */
                    215: void
                    216: xmlParserInputShrink(xmlParserInputPtr in) {
                    217:     int used;
                    218:     int ret;
                    219:     int index;
                    220: 
                    221: #ifdef DEBUG_INPUT
                    222:     fprintf(stderr, "Shrink\n");
                    223: #endif
                    224:     if (in->buf == NULL) return;
                    225:     if (in->base == NULL) return;
                    226:     if (in->cur == NULL) return;
                    227:     if (in->buf->buffer == NULL) return;
                    228: 
                    229:     CHECK_BUFFER(in);
                    230: 
                    231:     used = in->cur - in->buf->buffer->content;
                    232:     if (used > INPUT_CHUNK) {
1.110     daniel    233:        ret = xmlBufferShrink(in->buf->buffer, used - LINE_LEN);
1.91      daniel    234:        if (ret > 0) {
                    235:            in->cur -= ret;
                    236:            in->consumed += ret;
                    237:        }
                    238:     }
                    239: 
                    240:     CHECK_BUFFER(in);
                    241: 
                    242:     if (in->buf->buffer->use > INPUT_CHUNK) {
                    243:         return;
                    244:     }
                    245:     xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
                    246:     if (in->base != in->buf->buffer->content) {
                    247:         /*
                    248:         * the buffer has been realloced
                    249:         */
                    250:        index = in->cur - in->base;
                    251:        in->base = in->buf->buffer->content;
                    252:        in->cur = &in->buf->buffer->content[index];
                    253:     }
                    254: 
                    255:     CHECK_BUFFER(in);
                    256: }
                    257: 
1.45      daniel    258: /************************************************************************
                    259:  *                                                                     *
                    260:  *             Parser stacks related functions and macros              *
                    261:  *                                                                     *
                    262:  ************************************************************************/
1.79      daniel    263: 
                    264: int xmlSubstituteEntitiesDefaultValue = 0;
1.100     daniel    265: int xmlDoValidityCheckingDefaultValue = 0;
1.135     daniel    266: xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
                    267:                                      const xmlChar ** str);
1.79      daniel    268: 
1.1       veillard  269: /*
1.40      daniel    270:  * Generic function for accessing stacks in the Parser Context
1.1       veillard  271:  */
                    272: 
1.140     daniel    273: #define PUSH_AND_POP(scope, type, name)                                        \
                    274: scope int name##Push(xmlParserCtxtPtr ctxt, type value) {              \
1.31      daniel    275:     if (ctxt->name##Nr >= ctxt->name##Max) {                           \
                    276:        ctxt->name##Max *= 2;                                           \
1.119     daniel    277:         ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab,         \
1.40      daniel    278:                     ctxt->name##Max * sizeof(ctxt->name##Tab[0]));     \
                    279:         if (ctxt->name##Tab == NULL) {                                 \
1.31      daniel    280:            fprintf(stderr, "realloc failed !\n");                      \
1.145     daniel    281:            return(0);                                                  \
1.31      daniel    282:        }                                                               \
                    283:     }                                                                  \
1.40      daniel    284:     ctxt->name##Tab[ctxt->name##Nr] = value;                           \
                    285:     ctxt->name = value;                                                        \
                    286:     return(ctxt->name##Nr++);                                          \
1.31      daniel    287: }                                                                      \
1.140     daniel    288: scope type name##Pop(xmlParserCtxtPtr ctxt) {                          \
1.69      daniel    289:     type ret;                                                          \
1.40      daniel    290:     if (ctxt->name##Nr <= 0) return(0);                                        \
                    291:     ctxt->name##Nr--;                                                  \
1.50      daniel    292:     if (ctxt->name##Nr > 0)                                            \
                    293:        ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];               \
                    294:     else                                                               \
                    295:         ctxt->name = NULL;                                             \
1.69      daniel    296:     ret = ctxt->name##Tab[ctxt->name##Nr];                             \
                    297:     ctxt->name##Tab[ctxt->name##Nr] = 0;                               \
                    298:     return(ret);                                                       \
1.31      daniel    299: }                                                                      \
                    300: 
1.140     daniel    301: PUSH_AND_POP(extern, xmlParserInputPtr, input)
                    302: PUSH_AND_POP(extern, xmlNodePtr, node)
                    303: PUSH_AND_POP(extern, xmlChar*, name)
1.40      daniel    304: 
1.55      daniel    305: /*
                    306:  * Macros for accessing the content. Those should be used only by the parser,
                    307:  * and not exported.
                    308:  *
                    309:  * Dirty macros, i.e. one need to make assumption on the context to use them
                    310:  *
1.123     daniel    311:  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
                    312:  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
1.55      daniel    313:  *           in ISO-Latin or UTF-8, and the current 16 bit value if compiled
                    314:  *           in UNICODE mode. This should be used internally by the parser
                    315:  *           only to compare to ASCII values otherwise it would break when
                    316:  *           running with UTF-8 encoding.
1.123     daniel    317:  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
1.55      daniel    318:  *           to compare on ASCII based substring.
1.123     daniel    319:  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
1.55      daniel    320:  *           strings within the parser.
                    321:  *
1.77      daniel    322:  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
1.55      daniel    323:  *
                    324:  *   CURRENT Returns the current char value, with the full decoding of
                    325:  *           UTF-8 if we are using this mode. It returns an int.
                    326:  *   NEXT    Skip to the next character, this does the proper decoding
                    327:  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
1.77      daniel    328:  *   COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
1.55      daniel    329:  */
1.45      daniel    330: 
1.97      daniel    331: #define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur))
1.135     daniel    332: #define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val)
1.55      daniel    333: #define NXT(val) ctxt->input->cur[(val)]
                    334: #define CUR_PTR ctxt->input->cur
1.97      daniel    335: #define SHRINK  xmlParserInputShrink(ctxt->input);                     \
                    336:     if ((*ctxt->input->cur == 0) &&                                    \
                    337:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
                    338:            xmlPopInput(ctxt)
                    339: 
                    340: #define GROW  xmlParserInputGrow(ctxt->input, INPUT_CHUNK);            \
                    341:     if ((*ctxt->input->cur == 0) &&                                    \
                    342:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
                    343:            xmlPopInput(ctxt)
1.55      daniel    344: 
                    345: #define SKIP_BLANKS                                                    \
1.101     daniel    346:     do {                                                               \
                    347:        while (IS_BLANK(CUR)) NEXT;                                     \
1.142     daniel    348:        while ((CUR == 0) && (ctxt->inputNr > 1))                       \
                    349:            xmlPopInput(ctxt);                                          \
1.101     daniel    350:        if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
                    351:        if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);   \
                    352:     } while (IS_BLANK(CUR));
1.55      daniel    353: 
                    354: #define CURRENT (*ctxt->input->cur)
1.91      daniel    355: #define NEXT {                                                         \
1.97      daniel    356:     if (ctxt->token != 0) ctxt->token = 0;                             \
                    357:     else {                                                             \
1.91      daniel    358:     if ((*ctxt->input->cur == 0) &&                                    \
                    359:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {         \
                    360:            xmlPopInput(ctxt);                                          \
                    361:     } else {                                                           \
                    362:         if (*(ctxt->input->cur) == '\n') {                             \
                    363:            ctxt->input->line++; ctxt->input->col = 1;                  \
                    364:        } else ctxt->input->col++;                                      \
                    365:        ctxt->input->cur++;                                             \
1.135     daniel    366:        ctxt->nbChars++;                                                \
1.91      daniel    367:         if (*ctxt->input->cur == 0)                                    \
                    368:            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
1.96      daniel    369:     }                                                                  \
                    370:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
                    371:     if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);      \
1.97      daniel    372: }}
1.91      daniel    373: 
1.42      daniel    374: 
1.97      daniel    375: /************************************************************************
                    376:  *                                                                     *
                    377:  *     Commodity functions to handle entities processing               *
                    378:  *                                                                     *
                    379:  ************************************************************************/
1.40      daniel    380: 
1.50      daniel    381: /**
                    382:  * xmlPopInput:
                    383:  * @ctxt:  an XML parser context
                    384:  *
1.40      daniel    385:  * xmlPopInput: the current input pointed by ctxt->input came to an end
                    386:  *          pop it and return the next char.
1.45      daniel    387:  *
1.123     daniel    388:  * Returns the current xmlChar in the parser context
1.40      daniel    389:  */
1.123     daniel    390: xmlChar
1.55      daniel    391: xmlPopInput(xmlParserCtxtPtr ctxt) {
1.40      daniel    392:     if (ctxt->inputNr == 1) return(0); /* End of main Input */
1.69      daniel    393:     xmlFreeInputStream(inputPop(ctxt));
1.97      daniel    394:     if ((*ctxt->input->cur == 0) &&
                    395:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
                    396:            return(xmlPopInput(ctxt));
1.40      daniel    397:     return(CUR);
                    398: }
                    399: 
1.50      daniel    400: /**
                    401:  * xmlPushInput:
                    402:  * @ctxt:  an XML parser context
                    403:  * @input:  an XML parser input fragment (entity, XML fragment ...).
                    404:  *
1.40      daniel    405:  * xmlPushInput: switch to a new input stream which is stacked on top
                    406:  *               of the previous one(s).
                    407:  */
1.55      daniel    408: void
                    409: xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
1.40      daniel    410:     if (input == NULL) return;
                    411:     inputPush(ctxt, input);
                    412: }
                    413: 
1.50      daniel    414: /**
1.69      daniel    415:  * xmlFreeInputStream:
1.127     daniel    416:  * @input:  an xmlParserInputPtr
1.69      daniel    417:  *
                    418:  * Free up an input stream.
                    419:  */
                    420: void
                    421: xmlFreeInputStream(xmlParserInputPtr input) {
                    422:     if (input == NULL) return;
                    423: 
1.119     daniel    424:     if (input->filename != NULL) xmlFree((char *) input->filename);
                    425:     if (input->directory != NULL) xmlFree((char *) input->directory);
1.69      daniel    426:     if ((input->free != NULL) && (input->base != NULL))
1.123     daniel    427:         input->free((xmlChar *) input->base);
1.93      veillard  428:     if (input->buf != NULL) 
                    429:         xmlFreeParserInputBuffer(input->buf);
1.69      daniel    430:     memset(input, -1, sizeof(xmlParserInput));
1.119     daniel    431:     xmlFree(input);
1.69      daniel    432: }
                    433: 
                    434: /**
1.96      daniel    435:  * xmlNewInputStream:
                    436:  * @ctxt:  an XML parser context
                    437:  *
                    438:  * Create a new input stream structure
                    439:  * Returns the new input stream or NULL
                    440:  */
                    441: xmlParserInputPtr
                    442: xmlNewInputStream(xmlParserCtxtPtr ctxt) {
                    443:     xmlParserInputPtr input;
                    444: 
1.119     daniel    445:     input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
1.96      daniel    446:     if (input == NULL) {
1.123     daniel    447:         ctxt->errNo = XML_ERR_NO_MEMORY;
1.96      daniel    448:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel    449:            ctxt->sax->error(ctxt->userData, 
                    450:                             "malloc: couldn't allocate a new input stream\n");
1.123     daniel    451:        ctxt->errNo = XML_ERR_NO_MEMORY;
1.96      daniel    452:        return(NULL);
                    453:     }
                    454:     input->filename = NULL;
                    455:     input->directory = NULL;
                    456:     input->base = NULL;
                    457:     input->cur = NULL;
                    458:     input->buf = NULL;
                    459:     input->line = 1;
                    460:     input->col = 1;
                    461:     input->buf = NULL;
                    462:     input->free = NULL;
                    463:     input->consumed = 0;
1.140     daniel    464:     input->length = 0;
1.96      daniel    465:     return(input);
                    466: }
                    467: 
                    468: /**
1.50      daniel    469:  * xmlNewEntityInputStream:
                    470:  * @ctxt:  an XML parser context
                    471:  * @entity:  an Entity pointer
                    472:  *
1.82      daniel    473:  * Create a new input stream based on an xmlEntityPtr
1.113     daniel    474:  *
                    475:  * Returns the new input stream or NULL
1.45      daniel    476:  */
1.50      daniel    477: xmlParserInputPtr
                    478: xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
1.45      daniel    479:     xmlParserInputPtr input;
                    480: 
                    481:     if (entity == NULL) {
1.123     daniel    482:         ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.55      daniel    483:         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel    484:            ctxt->sax->error(ctxt->userData,
1.45      daniel    485:              "internal: xmlNewEntityInputStream entity = NULL\n");
1.123     daniel    486:        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.50      daniel    487:        return(NULL);
1.45      daniel    488:     }
                    489:     if (entity->content == NULL) {
1.113     daniel    490:        switch (entity->type) {
                    491:             case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1.123     daniel    492:                ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
1.113     daniel    493:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    494:                    ctxt->sax->error(ctxt->userData,
                    495:                      "xmlNewEntityInputStream unparsed entity !\n");
                    496:                 break;
                    497:             case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
                    498:             case XML_EXTERNAL_PARAMETER_ENTITY:
1.116     daniel    499:                return(xmlLoadExternalEntity((char *) entity->SystemID,
1.142     daniel    500:                       (char *) entity->ExternalID, ctxt));
1.113     daniel    501:             case XML_INTERNAL_GENERAL_ENTITY:
                    502:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    503:                    ctxt->sax->error(ctxt->userData,
                    504:          "Internal entity %s without content !\n", entity->name);
                    505:                 break;
                    506:             case XML_INTERNAL_PARAMETER_ENTITY:
1.123     daniel    507:                ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.113     daniel    508:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    509:                    ctxt->sax->error(ctxt->userData,
                    510:          "Internal parameter entity %s without content !\n", entity->name);
                    511:                 break;
                    512:             case XML_INTERNAL_PREDEFINED_ENTITY:
1.123     daniel    513:                ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.113     daniel    514:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    515:                    ctxt->sax->error(ctxt->userData,
                    516:              "Predefined entity %s without content !\n", entity->name);
                    517:                 break;
                    518:        }
1.50      daniel    519:        return(NULL);
1.45      daniel    520:     }
1.96      daniel    521:     input = xmlNewInputStream(ctxt);
1.45      daniel    522:     if (input == NULL) {
1.50      daniel    523:        return(NULL);
1.45      daniel    524:     }
1.123     daniel    525:     input->filename = (char *) entity->SystemID; /* TODO !!! char <- xmlChar */
1.45      daniel    526:     input->base = entity->content;
                    527:     input->cur = entity->content;
1.140     daniel    528:     input->length = entity->length;
1.50      daniel    529:     return(input);
1.45      daniel    530: }
                    531: 
1.59      daniel    532: /**
                    533:  * xmlNewStringInputStream:
                    534:  * @ctxt:  an XML parser context
1.96      daniel    535:  * @buffer:  an memory buffer
1.59      daniel    536:  *
                    537:  * Create a new input stream based on a memory buffer.
1.68      daniel    538:  * Returns the new input stream
1.59      daniel    539:  */
                    540: xmlParserInputPtr
1.123     daniel    541: xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
1.59      daniel    542:     xmlParserInputPtr input;
                    543: 
1.96      daniel    544:     if (buffer == NULL) {
1.123     daniel    545:        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.59      daniel    546:         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel    547:            ctxt->sax->error(ctxt->userData,
1.59      daniel    548:              "internal: xmlNewStringInputStream string = NULL\n");
                    549:        return(NULL);
                    550:     }
1.96      daniel    551:     input = xmlNewInputStream(ctxt);
1.59      daniel    552:     if (input == NULL) {
                    553:        return(NULL);
                    554:     }
1.96      daniel    555:     input->base = buffer;
                    556:     input->cur = buffer;
1.140     daniel    557:     input->length = xmlStrlen(buffer);
1.59      daniel    558:     return(input);
                    559: }
                    560: 
1.76      daniel    561: /**
                    562:  * xmlNewInputFromFile:
                    563:  * @ctxt:  an XML parser context
                    564:  * @filename:  the filename to use as entity
                    565:  *
                    566:  * Create a new input stream based on a file.
                    567:  *
                    568:  * Returns the new input stream or NULL in case of error
                    569:  */
                    570: xmlParserInputPtr
1.79      daniel    571: xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
1.91      daniel    572:     xmlParserInputBufferPtr buf;
1.76      daniel    573:     xmlParserInputPtr inputStream;
1.111     daniel    574:     char *directory = NULL;
1.76      daniel    575: 
1.96      daniel    576:     if (ctxt == NULL) return(NULL);
1.91      daniel    577:     buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1.94      daniel    578:     if (buf == NULL) {
1.140     daniel    579:        char name[XML_PARSER_BIG_BUFFER_SIZE];
1.106     daniel    580: 
1.94      daniel    581:         if ((ctxt->input != NULL) && (ctxt->input->directory != NULL)) {
                    582: #ifdef WIN32
                    583:             sprintf(name, "%s\\%s", ctxt->input->directory, filename);
                    584: #else
                    585:             sprintf(name, "%s/%s", ctxt->input->directory, filename);
                    586: #endif
                    587:             buf = xmlParserInputBufferCreateFilename(name,
                    588:                                                     XML_CHAR_ENCODING_NONE);
1.106     daniel    589:            if (buf != NULL)
1.142     daniel    590:                directory = xmlParserGetDirectory(name);
1.106     daniel    591:        }
                    592:        if ((buf == NULL) && (ctxt->directory != NULL)) {
                    593: #ifdef WIN32
                    594:             sprintf(name, "%s\\%s", ctxt->directory, filename);
                    595: #else
                    596:             sprintf(name, "%s/%s", ctxt->directory, filename);
                    597: #endif
                    598:             buf = xmlParserInputBufferCreateFilename(name,
                    599:                                                     XML_CHAR_ENCODING_NONE);
                    600:            if (buf != NULL)
1.142     daniel    601:                directory = xmlParserGetDirectory(name);
1.106     daniel    602:        }
                    603:        if (buf == NULL)
1.94      daniel    604:            return(NULL);
                    605:     }
                    606:     if (directory == NULL)
                    607:         directory = xmlParserGetDirectory(filename);
1.76      daniel    608: 
1.96      daniel    609:     inputStream = xmlNewInputStream(ctxt);
1.76      daniel    610:     if (inputStream == NULL) {
1.119     daniel    611:        if (directory != NULL) xmlFree((char *) directory);
1.76      daniel    612:        return(NULL);
                    613:     }
                    614: 
1.119     daniel    615:     inputStream->filename = xmlMemStrdup(filename);
1.94      daniel    616:     inputStream->directory = directory;
1.91      daniel    617:     inputStream->buf = buf;
1.76      daniel    618: 
1.91      daniel    619:     inputStream->base = inputStream->buf->buffer->content;
                    620:     inputStream->cur = inputStream->buf->buffer->content;
1.106     daniel    621:     if ((ctxt->directory == NULL) && (directory != NULL))
1.134     daniel    622:         ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
1.76      daniel    623:     return(inputStream);
                    624: }
                    625: 
1.77      daniel    626: /************************************************************************
                    627:  *                                                                     *
1.97      daniel    628:  *             Commodity functions to handle parser contexts           *
                    629:  *                                                                     *
                    630:  ************************************************************************/
                    631: 
                    632: /**
                    633:  * xmlInitParserCtxt:
                    634:  * @ctxt:  an XML parser context
                    635:  *
                    636:  * Initialize a parser context
                    637:  */
                    638: 
                    639: void
                    640: xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
                    641: {
                    642:     xmlSAXHandler *sax;
                    643: 
1.119     daniel    644:     sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
1.97      daniel    645:     if (sax == NULL) {
                    646:         fprintf(stderr, "xmlInitParserCtxt: out of memory\n");
                    647:     }
                    648: 
                    649:     /* Allocate the Input stack */
1.119     daniel    650:     ctxt->inputTab = (xmlParserInputPtr *) xmlMalloc(5 * sizeof(xmlParserInputPtr));
1.97      daniel    651:     ctxt->inputNr = 0;
                    652:     ctxt->inputMax = 5;
                    653:     ctxt->input = NULL;
                    654:     ctxt->version = NULL;
                    655:     ctxt->encoding = NULL;
                    656:     ctxt->standalone = -1;
1.98      daniel    657:     ctxt->hasExternalSubset = 0;
                    658:     ctxt->hasPErefs = 0;
1.97      daniel    659:     ctxt->html = 0;
1.98      daniel    660:     ctxt->external = 0;
1.140     daniel    661:     ctxt->instate = XML_PARSER_START;
1.97      daniel    662:     ctxt->token = 0;
1.106     daniel    663:     ctxt->directory = NULL;
1.97      daniel    664: 
                    665:     /* Allocate the Node stack */
1.119     daniel    666:     ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
1.97      daniel    667:     ctxt->nodeNr = 0;
                    668:     ctxt->nodeMax = 10;
                    669:     ctxt->node = NULL;
                    670: 
1.140     daniel    671:     /* Allocate the Name stack */
                    672:     ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
                    673:     ctxt->nameNr = 0;
                    674:     ctxt->nameMax = 10;
                    675:     ctxt->name = NULL;
                    676: 
1.97      daniel    677:     if (sax == NULL) ctxt->sax = &xmlDefaultSAXHandler;
                    678:     else {
                    679:         ctxt->sax = sax;
                    680:        memcpy(sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
                    681:     }
                    682:     ctxt->userData = ctxt;
                    683:     ctxt->myDoc = NULL;
                    684:     ctxt->wellFormed = 1;
1.99      daniel    685:     ctxt->valid = 1;
1.100     daniel    686:     ctxt->validate = xmlDoValidityCheckingDefaultValue;
                    687:     ctxt->vctxt.userData = ctxt;
1.149   ! daniel    688:     if (ctxt->validate) {
        !           689:        ctxt->vctxt.error = xmlParserValidityError;
        !           690:        ctxt->vctxt.warning = xmlParserValidityWarning;
        !           691:     } else {
        !           692:        ctxt->vctxt.error = NULL;
        !           693:        ctxt->vctxt.warning = NULL;
        !           694:     }
1.97      daniel    695:     ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
                    696:     ctxt->record_info = 0;
1.135     daniel    697:     ctxt->nbChars = 0;
1.140     daniel    698:     ctxt->checkIndex = 0;
                    699:     ctxt->errNo = XML_ERR_OK;
1.97      daniel    700:     xmlInitNodeInfoSeq(&ctxt->node_seq);
                    701: }
                    702: 
                    703: /**
                    704:  * xmlFreeParserCtxt:
                    705:  * @ctxt:  an XML parser context
                    706:  *
                    707:  * Free all the memory used by a parser context. However the parsed
                    708:  * document in ctxt->myDoc is not freed.
                    709:  */
                    710: 
                    711: void
                    712: xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
                    713: {
                    714:     xmlParserInputPtr input;
1.140     daniel    715:     xmlChar *oldname;
1.97      daniel    716: 
                    717:     if (ctxt == NULL) return;
                    718: 
                    719:     while ((input = inputPop(ctxt)) != NULL) {
                    720:         xmlFreeInputStream(input);
                    721:     }
1.140     daniel    722:     while ((oldname = namePop(ctxt)) != NULL) {
                    723:        xmlFree(oldname);
                    724:     }
                    725:     if (ctxt->nameTab != NULL) xmlFree(ctxt->nameTab);
1.119     daniel    726:     if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
                    727:     if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
                    728:     if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
                    729:     if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
1.97      daniel    730:     if ((ctxt->sax != NULL) && (ctxt->sax != &xmlDefaultSAXHandler))
1.119     daniel    731:         xmlFree(ctxt->sax);
                    732:     if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
                    733:     xmlFree(ctxt);
1.97      daniel    734: }
                    735: 
                    736: /**
                    737:  * xmlNewParserCtxt:
                    738:  *
                    739:  * Allocate and initialize a new parser context.
                    740:  *
                    741:  * Returns the xmlParserCtxtPtr or NULL
                    742:  */
                    743: 
                    744: xmlParserCtxtPtr
                    745: xmlNewParserCtxt()
                    746: {
                    747:     xmlParserCtxtPtr ctxt;
                    748: 
1.119     daniel    749:     ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
1.97      daniel    750:     if (ctxt == NULL) {
                    751:         fprintf(stderr, "xmlNewParserCtxt : cannot allocate context\n");
                    752:         perror("malloc");
                    753:        return(NULL);
                    754:     }
                    755:     xmlInitParserCtxt(ctxt);
                    756:     return(ctxt);
                    757: }
                    758: 
                    759: /**
                    760:  * xmlClearParserCtxt:
                    761:  * @ctxt:  an XML parser context
                    762:  *
                    763:  * Clear (release owned resources) and reinitialize a parser context
                    764:  */
                    765: 
                    766: void
                    767: xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
                    768: {
                    769:   xmlClearNodeInfoSeq(&ctxt->node_seq);
                    770:   xmlInitParserCtxt(ctxt);
                    771: }
                    772: 
                    773: /************************************************************************
                    774:  *                                                                     *
1.77      daniel    775:  *             Commodity functions to handle entities                  *
                    776:  *                                                                     *
                    777:  ************************************************************************/
                    778: 
1.97      daniel    779: void xmlParserHandleReference(xmlParserCtxtPtr ctxt);
                    780: void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
1.135     daniel    781: xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
                    782:                                        const xmlChar **str);
1.97      daniel    783: 
                    784: /**
                    785:  * xmlParseCharRef:
                    786:  * @ctxt:  an XML parser context
                    787:  *
                    788:  * parse Reference declarations
                    789:  *
                    790:  * [66] CharRef ::= '&#' [0-9]+ ';' |
                    791:  *                  '&#x' [0-9a-fA-F]+ ';'
                    792:  *
1.98      daniel    793:  * [ WFC: Legal Character ]
                    794:  * Characters referred to using character references must match the
                    795:  * production for Char. 
                    796:  *
1.135     daniel    797:  * Returns the value parsed (as an int), 0 in case of error
1.77      daniel    798:  */
1.97      daniel    799: int
                    800: xmlParseCharRef(xmlParserCtxtPtr ctxt) {
                    801:     int val = 0;
                    802: 
1.111     daniel    803:     if (ctxt->token != 0) {
                    804:        val = ctxt->token;
                    805:         ctxt->token = 0;
                    806:         return(val);
                    807:     }
1.97      daniel    808:     if ((CUR == '&') && (NXT(1) == '#') &&
                    809:         (NXT(2) == 'x')) {
                    810:        SKIP(3);
                    811:        while (CUR != ';') {
                    812:            if ((CUR >= '0') && (CUR <= '9')) 
                    813:                val = val * 16 + (CUR - '0');
                    814:            else if ((CUR >= 'a') && (CUR <= 'f'))
                    815:                val = val * 16 + (CUR - 'a') + 10;
                    816:            else if ((CUR >= 'A') && (CUR <= 'F'))
                    817:                val = val * 16 + (CUR - 'A') + 10;
                    818:            else {
1.123     daniel    819:                ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
1.97      daniel    820:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    821:                    ctxt->sax->error(ctxt->userData, 
                    822:                         "xmlParseCharRef: invalid hexadecimal value\n");
                    823:                ctxt->wellFormed = 0;
                    824:                val = 0;
                    825:                break;
                    826:            }
                    827:            NEXT;
                    828:        }
                    829:        if (CUR == ';')
1.126     daniel    830:            SKIP(1); /* on purpose to avoid reentrancy problems with NEXT */
1.97      daniel    831:     } else if  ((CUR == '&') && (NXT(1) == '#')) {
                    832:        SKIP(2);
                    833:        while (CUR != ';') {
                    834:            if ((CUR >= '0') && (CUR <= '9')) 
                    835:                val = val * 10 + (CUR - '0');
                    836:            else {
1.123     daniel    837:                ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
1.97      daniel    838:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    839:                    ctxt->sax->error(ctxt->userData, 
                    840:                         "xmlParseCharRef: invalid decimal value\n");
                    841:                ctxt->wellFormed = 0;
                    842:                val = 0;
                    843:                break;
                    844:            }
                    845:            NEXT;
                    846:        }
                    847:        if (CUR == ';')
1.126     daniel    848:            SKIP(1); /* on purpose to avoid reentrancy problems with NEXT */
1.97      daniel    849:     } else {
1.123     daniel    850:        ctxt->errNo = XML_ERR_INVALID_CHARREF;
1.97      daniel    851:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.98      daniel    852:            ctxt->sax->error(ctxt->userData,
                    853:               "xmlParseCharRef: invalid value\n");
1.97      daniel    854:        ctxt->wellFormed = 0;
                    855:     }
1.98      daniel    856: 
1.97      daniel    857:     /*
1.98      daniel    858:      * [ WFC: Legal Character ]
                    859:      * Characters referred to using character references must match the
                    860:      * production for Char. 
1.97      daniel    861:      */
                    862:     if (IS_CHAR(val)) {
                    863:         return(val);
                    864:     } else {
1.123     daniel    865:        ctxt->errNo = XML_ERR_INVALID_CHAR;
1.97      daniel    866:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.123     daniel    867:            ctxt->sax->error(ctxt->userData, "CharRef: invalid xmlChar value %d\n",
1.97      daniel    868:                             val);
                    869:        ctxt->wellFormed = 0;
                    870:     }
                    871:     return(0);
1.77      daniel    872: }
                    873: 
1.96      daniel    874: /**
1.135     daniel    875:  * xmlParseStringCharRef:
                    876:  * @ctxt:  an XML parser context
                    877:  * @str:  a pointer to an index in the string
                    878:  *
                    879:  * parse Reference declarations, variant parsing from a string rather
                    880:  * than an an input flow.
                    881:  *
                    882:  * [66] CharRef ::= '&#' [0-9]+ ';' |
                    883:  *                  '&#x' [0-9a-fA-F]+ ';'
                    884:  *
                    885:  * [ WFC: Legal Character ]
                    886:  * Characters referred to using character references must match the
                    887:  * production for Char. 
                    888:  *
                    889:  * Returns the value parsed (as an int), 0 in case of error, str will be
                    890:  *         updated to the current value of the index
                    891:  */
                    892: int
                    893: xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
                    894:     const xmlChar *ptr;
                    895:     xmlChar cur;
                    896:     int val = 0;
                    897: 
                    898:     if ((str == NULL) || (*str == NULL)) return(0);
                    899:     ptr = *str;
                    900:     cur = *ptr;
1.137     daniel    901:     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
1.135     daniel    902:        ptr += 3;
                    903:        cur = *ptr;
                    904:        while (cur != ';') {
                    905:            if ((cur >= '0') && (cur <= '9')) 
                    906:                val = val * 16 + (cur - '0');
                    907:            else if ((cur >= 'a') && (cur <= 'f'))
                    908:                val = val * 16 + (cur - 'a') + 10;
                    909:            else if ((cur >= 'A') && (cur <= 'F'))
                    910:                val = val * 16 + (cur - 'A') + 10;
                    911:            else {
                    912:                ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
                    913:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    914:                    ctxt->sax->error(ctxt->userData, 
                    915:                         "xmlParseCharRef: invalid hexadecimal value\n");
                    916:                ctxt->wellFormed = 0;
                    917:                val = 0;
                    918:                break;
                    919:            }
                    920:            ptr++;
                    921:            cur = *ptr;
                    922:        }
                    923:        if (cur == ';')
                    924:            ptr++;
1.145     daniel    925:     } else if  ((cur == '&') && (ptr[1] == '#')){
1.135     daniel    926:        ptr += 2;
                    927:        cur = *ptr;
                    928:        while (cur != ';') {
                    929:            if ((cur >= '0') && (cur <= '9')) 
                    930:                val = val * 10 + (cur - '0');
                    931:            else {
                    932:                ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
                    933:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    934:                    ctxt->sax->error(ctxt->userData, 
                    935:                         "xmlParseCharRef: invalid decimal value\n");
                    936:                ctxt->wellFormed = 0;
                    937:                val = 0;
                    938:                break;
                    939:            }
                    940:            ptr++;
                    941:            cur = *ptr;
                    942:        }
                    943:        if (cur == ';')
                    944:            ptr++;
                    945:     } else {
                    946:        ctxt->errNo = XML_ERR_INVALID_CHARREF;
                    947:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    948:            ctxt->sax->error(ctxt->userData,
                    949:               "xmlParseCharRef: invalid value\n");
                    950:        ctxt->wellFormed = 0;
                    951:        return(0);
                    952:     }
                    953:     *str = ptr;
                    954: 
                    955:     /*
                    956:      * [ WFC: Legal Character ]
                    957:      * Characters referred to using character references must match the
                    958:      * production for Char. 
                    959:      */
                    960:     if (IS_CHAR(val)) {
                    961:         return(val);
                    962:     } else {
                    963:        ctxt->errNo = XML_ERR_INVALID_CHAR;
                    964:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    965:            ctxt->sax->error(ctxt->userData,
                    966:                             "CharRef: invalid xmlChar value %d\n", val);
                    967:        ctxt->wellFormed = 0;
                    968:     }
                    969:     return(0);
                    970: }
                    971: 
                    972: /**
1.96      daniel    973:  * xmlParserHandleReference:
                    974:  * @ctxt:  the parser context
                    975:  * 
1.97      daniel    976:  * [67] Reference ::= EntityRef | CharRef
                    977:  *
1.96      daniel    978:  * [68] EntityRef ::= '&' Name ';'
                    979:  *
1.98      daniel    980:  * [ WFC: Entity Declared ]
                    981:  * the Name given in the entity reference must match that in an entity
                    982:  * declaration, except that well-formed documents need not declare any
                    983:  * of the following entities: amp, lt, gt, apos, quot. 
                    984:  *
                    985:  * [ WFC: Parsed Entity ]
                    986:  * An entity reference must not contain the name of an unparsed entity
                    987:  *
1.97      daniel    988:  * [66] CharRef ::= '&#' [0-9]+ ';' |
                    989:  *                  '&#x' [0-9a-fA-F]+ ';'
                    990:  *
1.96      daniel    991:  * A PEReference may have been detectect in the current input stream
                    992:  * the handling is done accordingly to 
                    993:  *      http://www.w3.org/TR/REC-xml#entproc
                    994:  */
                    995: void
                    996: xmlParserHandleReference(xmlParserCtxtPtr ctxt) {
1.97      daniel    997:     xmlParserInputPtr input;
1.123     daniel    998:     xmlChar *name;
1.97      daniel    999:     xmlEntityPtr ent = NULL;
                   1000: 
1.126     daniel   1001:     if (ctxt->token != 0) {
                   1002:         return;
                   1003:     }  
1.97      daniel   1004:     if (CUR != '&') return;
                   1005:     GROW;
                   1006:     if ((CUR == '&') && (NXT(1) == '#')) {
                   1007:        switch(ctxt->instate) {
1.140     daniel   1008:            case XML_PARSER_ENTITY_DECL:
                   1009:            case XML_PARSER_PI:
1.109     daniel   1010:            case XML_PARSER_CDATA_SECTION:
1.140     daniel   1011:            case XML_PARSER_COMMENT:
                   1012:                /* we just ignore it there */
                   1013:                return;
                   1014:            case XML_PARSER_START_TAG:
1.109     daniel   1015:                return;
1.140     daniel   1016:            case XML_PARSER_END_TAG:
1.97      daniel   1017:                return;
                   1018:            case XML_PARSER_EOF:
1.123     daniel   1019:                ctxt->errNo = XML_ERR_CHARREF_AT_EOF;
1.97      daniel   1020:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1021:                    ctxt->sax->error(ctxt->userData, "CharRef at EOF\n");
                   1022:                ctxt->wellFormed = 0;
                   1023:                return;
                   1024:            case XML_PARSER_PROLOG:
1.140     daniel   1025:            case XML_PARSER_START:
                   1026:            case XML_PARSER_MISC:
1.123     daniel   1027:                ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG;
1.97      daniel   1028:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1029:                    ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n");
                   1030:                ctxt->wellFormed = 0;
                   1031:                return;
                   1032:            case XML_PARSER_EPILOG:
1.123     daniel   1033:                ctxt->errNo = XML_ERR_CHARREF_IN_EPILOG;
1.97      daniel   1034:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1035:                    ctxt->sax->error(ctxt->userData, "CharRef in epilog!\n");
                   1036:                ctxt->wellFormed = 0;
                   1037:                return;
                   1038:            case XML_PARSER_DTD:
1.123     daniel   1039:                ctxt->errNo = XML_ERR_CHARREF_IN_DTD;
1.97      daniel   1040:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1041:                    ctxt->sax->error(ctxt->userData, 
                   1042:                           "CharRef are forbiden in DTDs!\n");
                   1043:                ctxt->wellFormed = 0;
                   1044:                return;
                   1045:            case XML_PARSER_ENTITY_VALUE:
                   1046:                /*
                   1047:                 * NOTE: in the case of entity values, we don't do the
1.127     daniel   1048:                 *       substitution here since we need the literal
1.97      daniel   1049:                 *       entity value to be able to save the internal
                   1050:                 *       subset of the document.
                   1051:                 *       This will be handled by xmlDecodeEntities
                   1052:                 */
                   1053:                return;
                   1054:            case XML_PARSER_CONTENT:
                   1055:            case XML_PARSER_ATTRIBUTE_VALUE:
1.116     daniel   1056:                /* !!! this may not be Ok for UTF-8, multibyte sequence */
1.97      daniel   1057:                ctxt->token = xmlParseCharRef(ctxt);
                   1058:                return;
                   1059:        }
                   1060:        return;
                   1061:     }
                   1062: 
                   1063:     switch(ctxt->instate) {
1.109     daniel   1064:        case XML_PARSER_CDATA_SECTION:
                   1065:            return;
1.140     daniel   1066:        case XML_PARSER_PI:
1.97      daniel   1067:         case XML_PARSER_COMMENT:
                   1068:            return;
1.140     daniel   1069:        case XML_PARSER_START_TAG:
                   1070:            return;
                   1071:        case XML_PARSER_END_TAG:
                   1072:            return;
1.97      daniel   1073:         case XML_PARSER_EOF:
1.123     daniel   1074:            ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF;
1.97      daniel   1075:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1076:                ctxt->sax->error(ctxt->userData, "Reference at EOF\n");
                   1077:            ctxt->wellFormed = 0;
                   1078:            return;
                   1079:         case XML_PARSER_PROLOG:
1.140     daniel   1080:        case XML_PARSER_START:
                   1081:        case XML_PARSER_MISC:
1.123     daniel   1082:            ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG;
1.97      daniel   1083:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1084:                ctxt->sax->error(ctxt->userData, "Reference in prolog!\n");
                   1085:            ctxt->wellFormed = 0;
                   1086:            return;
                   1087:         case XML_PARSER_EPILOG:
1.123     daniel   1088:            ctxt->errNo = XML_ERR_ENTITYREF_IN_EPILOG;
1.97      daniel   1089:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1090:                ctxt->sax->error(ctxt->userData, "Reference in epilog!\n");
                   1091:            ctxt->wellFormed = 0;
                   1092:            return;
                   1093:        case XML_PARSER_ENTITY_VALUE:
                   1094:            /*
                   1095:             * NOTE: in the case of entity values, we don't do the
1.127     daniel   1096:             *       substitution here since we need the literal
1.97      daniel   1097:             *       entity value to be able to save the internal
                   1098:             *       subset of the document.
                   1099:             *       This will be handled by xmlDecodeEntities
                   1100:             */
                   1101:            return;
                   1102:         case XML_PARSER_ATTRIBUTE_VALUE:
                   1103:            /*
                   1104:             * NOTE: in the case of attributes values, we don't do the
                   1105:             *       substitution here unless we are in a mode where
                   1106:             *       the parser is explicitely asked to substitute
                   1107:             *       entities. The SAX callback is called with values
                   1108:             *       without entity substitution.
                   1109:             *       This will then be handled by xmlDecodeEntities
                   1110:             */
1.113     daniel   1111:            return;
1.97      daniel   1112:        case XML_PARSER_ENTITY_DECL:
                   1113:            /*
                   1114:             * we just ignore it there
                   1115:             * the substitution will be done once the entity is referenced
                   1116:             */
                   1117:            return;
                   1118:         case XML_PARSER_DTD:
1.123     daniel   1119:            ctxt->errNo = XML_ERR_ENTITYREF_IN_DTD;
1.97      daniel   1120:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1121:                ctxt->sax->error(ctxt->userData, 
                   1122:                       "Entity references are forbiden in DTDs!\n");
                   1123:            ctxt->wellFormed = 0;
                   1124:            return;
                   1125:         case XML_PARSER_CONTENT:
1.113     daniel   1126:            return;
1.97      daniel   1127:     }
                   1128: 
                   1129:     NEXT;
                   1130:     name = xmlScanName(ctxt);
                   1131:     if (name == NULL) {
1.123     daniel   1132:        ctxt->errNo = XML_ERR_ENTITYREF_NO_NAME;
1.97      daniel   1133:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1134:            ctxt->sax->error(ctxt->userData, "Entity reference: no name\n");
                   1135:        ctxt->wellFormed = 0;
                   1136:        ctxt->token = '&';
                   1137:        return;
                   1138:     }
                   1139:     if (NXT(xmlStrlen(name)) != ';') {
1.123     daniel   1140:        ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
1.97      daniel   1141:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1142:            ctxt->sax->error(ctxt->userData, 
                   1143:                             "Entity reference: ';' expected\n");
                   1144:        ctxt->wellFormed = 0;
                   1145:        ctxt->token = '&';
1.119     daniel   1146:        xmlFree(name);
1.97      daniel   1147:        return;
                   1148:     }
                   1149:     SKIP(xmlStrlen(name) + 1);
                   1150:     if (ctxt->sax != NULL) {
                   1151:        if (ctxt->sax->getEntity != NULL)
                   1152:            ent = ctxt->sax->getEntity(ctxt->userData, name);
                   1153:     }
1.98      daniel   1154: 
                   1155:     /*
                   1156:      * [ WFC: Entity Declared ]
                   1157:      * the Name given in the entity reference must match that in an entity
                   1158:      * declaration, except that well-formed documents need not declare any
                   1159:      * of the following entities: amp, lt, gt, apos, quot. 
                   1160:      */
1.97      daniel   1161:     if (ent == NULL)
                   1162:        ent = xmlGetPredefinedEntity(name);
                   1163:     if (ent == NULL) {
1.123     daniel   1164:         ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
1.97      daniel   1165:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1166:            ctxt->sax->error(ctxt->userData, 
1.98      daniel   1167:                             "Entity reference: entity %s not declared\n",
                   1168:                             name);
1.97      daniel   1169:        ctxt->wellFormed = 0;
1.119     daniel   1170:        xmlFree(name);
1.97      daniel   1171:        return;
                   1172:     }
1.98      daniel   1173: 
                   1174:     /*
                   1175:      * [ WFC: Parsed Entity ]
                   1176:      * An entity reference must not contain the name of an unparsed entity
                   1177:      */
                   1178:     if (ent->type == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
1.123     daniel   1179:         ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
1.98      daniel   1180:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1181:            ctxt->sax->error(ctxt->userData, 
                   1182:                         "Entity reference to unparsed entity %s\n", name);
                   1183:        ctxt->wellFormed = 0;
                   1184:     }
                   1185: 
1.97      daniel   1186:     if (ent->type == XML_INTERNAL_PREDEFINED_ENTITY) {
                   1187:         ctxt->token = ent->content[0];
1.119     daniel   1188:        xmlFree(name);
1.97      daniel   1189:        return;
                   1190:     }
                   1191:     input = xmlNewEntityInputStream(ctxt, ent);
                   1192:     xmlPushInput(ctxt, input);
1.119     daniel   1193:     xmlFree(name);
1.96      daniel   1194:     return;
                   1195: }
                   1196: 
                   1197: /**
                   1198:  * xmlParserHandlePEReference:
                   1199:  * @ctxt:  the parser context
                   1200:  * 
                   1201:  * [69] PEReference ::= '%' Name ';'
                   1202:  *
1.98      daniel   1203:  * [ WFC: No Recursion ]
                   1204:  * TODO A parsed entity must not contain a recursive
                   1205:  * reference to itself, either directly or indirectly. 
                   1206:  *
                   1207:  * [ WFC: Entity Declared ]
                   1208:  * In a document without any DTD, a document with only an internal DTD
                   1209:  * subset which contains no parameter entity references, or a document
                   1210:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   1211:  * entity must precede any reference to it...
                   1212:  *
                   1213:  * [ VC: Entity Declared ]
                   1214:  * In a document with an external subset or external parameter entities
                   1215:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   1216:  * must precede any reference to it...
                   1217:  *
                   1218:  * [ WFC: In DTD ]
                   1219:  * Parameter-entity references may only appear in the DTD.
                   1220:  * NOTE: misleading but this is handled.
                   1221:  *
                   1222:  * A PEReference may have been detected in the current input stream
1.96      daniel   1223:  * the handling is done accordingly to 
                   1224:  *      http://www.w3.org/TR/REC-xml#entproc
                   1225:  * i.e. 
                   1226:  *   - Included in literal in entity values
                   1227:  *   - Included as Paraemeter Entity reference within DTDs
                   1228:  */
                   1229: void
                   1230: xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
1.123     daniel   1231:     xmlChar *name;
1.96      daniel   1232:     xmlEntityPtr entity = NULL;
                   1233:     xmlParserInputPtr input;
                   1234: 
1.126     daniel   1235:     if (ctxt->token != 0) {
                   1236:         return;
                   1237:     }  
1.111     daniel   1238:     if (CUR != '%') return;
1.96      daniel   1239:     switch(ctxt->instate) {
1.109     daniel   1240:        case XML_PARSER_CDATA_SECTION:
                   1241:            return;
1.97      daniel   1242:         case XML_PARSER_COMMENT:
                   1243:            return;
1.140     daniel   1244:        case XML_PARSER_START_TAG:
                   1245:            return;
                   1246:        case XML_PARSER_END_TAG:
                   1247:            return;
1.96      daniel   1248:         case XML_PARSER_EOF:
1.123     daniel   1249:            ctxt->errNo = XML_ERR_PEREF_AT_EOF;
1.96      daniel   1250:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1251:                ctxt->sax->error(ctxt->userData, "PEReference at EOF\n");
                   1252:            ctxt->wellFormed = 0;
                   1253:            return;
                   1254:         case XML_PARSER_PROLOG:
1.140     daniel   1255:        case XML_PARSER_START:
                   1256:        case XML_PARSER_MISC:
1.123     daniel   1257:            ctxt->errNo = XML_ERR_PEREF_IN_PROLOG;
1.96      daniel   1258:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1259:                ctxt->sax->error(ctxt->userData, "PEReference in prolog!\n");
                   1260:            ctxt->wellFormed = 0;
                   1261:            return;
1.97      daniel   1262:        case XML_PARSER_ENTITY_DECL:
1.96      daniel   1263:         case XML_PARSER_CONTENT:
                   1264:         case XML_PARSER_ATTRIBUTE_VALUE:
1.140     daniel   1265:         case XML_PARSER_PI:
1.96      daniel   1266:            /* we just ignore it there */
                   1267:            return;
                   1268:         case XML_PARSER_EPILOG:
1.123     daniel   1269:            ctxt->errNo = XML_ERR_PEREF_IN_EPILOG;
1.96      daniel   1270:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.97      daniel   1271:                ctxt->sax->error(ctxt->userData, "PEReference in epilog!\n");
1.96      daniel   1272:            ctxt->wellFormed = 0;
                   1273:            return;
1.97      daniel   1274:        case XML_PARSER_ENTITY_VALUE:
                   1275:            /*
                   1276:             * NOTE: in the case of entity values, we don't do the
1.127     daniel   1277:             *       substitution here since we need the literal
1.97      daniel   1278:             *       entity value to be able to save the internal
                   1279:             *       subset of the document.
                   1280:             *       This will be handled by xmlDecodeEntities
                   1281:             */
                   1282:            return;
1.96      daniel   1283:         case XML_PARSER_DTD:
1.98      daniel   1284:            /*
                   1285:             * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
                   1286:             * In the internal DTD subset, parameter-entity references
                   1287:             * can occur only where markup declarations can occur, not
                   1288:             * within markup declarations.
                   1289:             * In that case this is handled in xmlParseMarkupDecl
                   1290:             */
                   1291:            if ((ctxt->external == 0) && (ctxt->inputNr == 1))
                   1292:                return;
1.96      daniel   1293:     }
                   1294: 
                   1295:     NEXT;
                   1296:     name = xmlParseName(ctxt);
                   1297:     if (name == NULL) {
1.123     daniel   1298:         ctxt->errNo = XML_ERR_PEREF_NO_NAME;
1.96      daniel   1299:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1300:            ctxt->sax->error(ctxt->userData, "xmlHandlePEReference: no name\n");
                   1301:        ctxt->wellFormed = 0;
                   1302:     } else {
                   1303:        if (CUR == ';') {
                   1304:            NEXT;
1.98      daniel   1305:            if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
                   1306:                entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
1.96      daniel   1307:            if (entity == NULL) {
1.98      daniel   1308:                
                   1309:                /*
                   1310:                 * [ WFC: Entity Declared ]
                   1311:                 * In a document without any DTD, a document with only an
                   1312:                 * internal DTD subset which contains no parameter entity
                   1313:                 * references, or a document with "standalone='yes'", ...
                   1314:                 * ... The declaration of a parameter entity must precede
                   1315:                 * any reference to it...
                   1316:                 */
                   1317:                if ((ctxt->standalone == 1) ||
                   1318:                    ((ctxt->hasExternalSubset == 0) &&
                   1319:                     (ctxt->hasPErefs == 0))) {
                   1320:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1321:                        ctxt->sax->error(ctxt->userData,
                   1322:                         "PEReference: %%%s; not found\n", name);
                   1323:                    ctxt->wellFormed = 0;
                   1324:                } else {
                   1325:                    /*
                   1326:                     * [ VC: Entity Declared ]
                   1327:                     * In a document with an external subset or external
                   1328:                     * parameter entities with "standalone='no'", ...
                   1329:                     * ... The declaration of a parameter entity must precede
                   1330:                     * any reference to it...
                   1331:                     */
                   1332:                    if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   1333:                        ctxt->sax->warning(ctxt->userData,
                   1334:                         "PEReference: %%%s; not found\n", name);
                   1335:                    ctxt->valid = 0;
                   1336:                }
1.96      daniel   1337:            } else {
                   1338:                if ((entity->type == XML_INTERNAL_PARAMETER_ENTITY) ||
                   1339:                    (entity->type == XML_EXTERNAL_PARAMETER_ENTITY)) {
                   1340:                    /*
                   1341:                     * TODO !!!! handle the extra spaces added before and after
                   1342:                     * c.f. http://www.w3.org/TR/REC-xml#as-PE
                   1343:                     * TODO !!!! Avoid quote processing in parameters value
                   1344:                     * c.f. http://www.w3.org/TR/REC-xml#inliteral
                   1345:                     */
                   1346:                    input = xmlNewEntityInputStream(ctxt, entity);
                   1347:                    xmlPushInput(ctxt, input);
                   1348:                } else {
                   1349:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1350:                        ctxt->sax->error(ctxt->userData,
                   1351:                         "xmlHandlePEReference: %s is not a parameter entity\n",
                   1352:                                         name);
                   1353:                    ctxt->wellFormed = 0;
                   1354:                }
                   1355:            }
                   1356:        } else {
1.123     daniel   1357:            ctxt->errNo = XML_ERR_PEREF_SEMICOL_MISSING;
1.96      daniel   1358:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1359:                ctxt->sax->error(ctxt->userData,
                   1360:                                 "xmlHandlePEReference: expecting ';'\n");
                   1361:            ctxt->wellFormed = 0;
                   1362:        }
1.119     daniel   1363:        xmlFree(name);
1.97      daniel   1364:     }
                   1365: }
                   1366: 
                   1367: /*
                   1368:  * Macro used to grow the current buffer.
                   1369:  */
                   1370: #define growBuffer(buffer) {                                           \
                   1371:     buffer##_size *= 2;                                                        \
1.145     daniel   1372:     buffer = (xmlChar *)                                               \
                   1373:                xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));    \
1.97      daniel   1374:     if (buffer == NULL) {                                              \
                   1375:        perror("realloc failed");                                       \
1.145     daniel   1376:        return(NULL);                                                   \
1.97      daniel   1377:     }                                                                  \
1.96      daniel   1378: }
1.77      daniel   1379: 
                   1380: /**
                   1381:  * xmlDecodeEntities:
                   1382:  * @ctxt:  the parser context
                   1383:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
                   1384:  * @len:  the len to decode (in bytes !), -1 for no size limit
1.123     daniel   1385:  * @end:  an end marker xmlChar, 0 if none
                   1386:  * @end2:  an end marker xmlChar, 0 if none
                   1387:  * @end3:  an end marker xmlChar, 0 if none
1.77      daniel   1388:  * 
                   1389:  * [67] Reference ::= EntityRef | CharRef
                   1390:  *
                   1391:  * [69] PEReference ::= '%' Name ';'
                   1392:  *
                   1393:  * Returns A newly allocated string with the substitution done. The caller
                   1394:  *      must deallocate it !
                   1395:  */
1.123     daniel   1396: xmlChar *
1.77      daniel   1397: xmlDecodeEntities(xmlParserCtxtPtr ctxt, int len, int what,
1.123     daniel   1398:                   xmlChar end, xmlChar  end2, xmlChar end3) {
                   1399:     xmlChar *buffer = NULL;
1.78      daniel   1400:     int buffer_size = 0;
1.123     daniel   1401:     xmlChar *out = NULL;
1.78      daniel   1402: 
1.123     daniel   1403:     xmlChar *current = NULL;
1.77      daniel   1404:     xmlEntityPtr ent;
1.91      daniel   1405:     int nbchars = 0;
1.77      daniel   1406:     unsigned int max = (unsigned int) len;
1.123     daniel   1407:     xmlChar cur;
1.77      daniel   1408: 
                   1409:     /*
                   1410:      * allocate a translation buffer.
                   1411:      */
1.140     daniel   1412:     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
1.123     daniel   1413:     buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
1.77      daniel   1414:     if (buffer == NULL) {
                   1415:        perror("xmlDecodeEntities: malloc failed");
                   1416:        return(NULL);
                   1417:     }
                   1418:     out = buffer;
                   1419: 
1.78      daniel   1420:     /*
                   1421:      * Ok loop until we reach one of the ending char or a size limit.
                   1422:      */
1.97      daniel   1423:     cur = CUR;
                   1424:     while ((nbchars < max) && (cur != end) &&
                   1425:            (cur != end2) && (cur != end3)) {
1.77      daniel   1426: 
1.98      daniel   1427:        if (cur == 0) break;
                   1428:         if ((cur == '&') && (NXT(1) == '#')) {
                   1429:            int val = xmlParseCharRef(ctxt);
                   1430:            *out++ = val;
                   1431:            nbchars += 3; 
                   1432:        } else if ((cur == '&') && (what & XML_SUBSTITUTE_REF)) {
                   1433:            ent = xmlParseEntityRef(ctxt);
                   1434:            if ((ent != NULL) && 
                   1435:                (ctxt->replaceEntities != 0)) {
                   1436:                current = ent->content;
                   1437:                while (*current != 0) {
                   1438:                    *out++ = *current++;
1.140     daniel   1439:                    if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) {
1.98      daniel   1440:                        int index = out - buffer;
                   1441: 
                   1442:                        growBuffer(buffer);
                   1443:                        out = &buffer[index];
1.77      daniel   1444:                    }
                   1445:                }
1.98      daniel   1446:                nbchars += 3 + xmlStrlen(ent->name);
                   1447:            } else if (ent != NULL) {
                   1448:                int i = xmlStrlen(ent->name);
1.123     daniel   1449:                const xmlChar *cur = ent->name;
1.98      daniel   1450: 
                   1451:                nbchars += i + 2;
                   1452:                *out++ = '&';
1.140     daniel   1453:                if (out - buffer > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
1.98      daniel   1454:                    int index = out - buffer;
                   1455: 
                   1456:                    growBuffer(buffer);
                   1457:                    out = &buffer[index];
                   1458:                }
                   1459:                for (;i > 0;i--)
                   1460:                    *out++ = *cur++;
                   1461:                *out++ = ';';
1.77      daniel   1462:            }
1.97      daniel   1463:        } else if (cur == '%' && (what & XML_SUBSTITUTE_PEREF)) {
                   1464:            /*
1.77      daniel   1465:             * a PEReference induce to switch the entity flow,
                   1466:             * we break here to flush the current set of chars
                   1467:             * parsed if any. We will be called back later.
1.97      daniel   1468:             */
1.91      daniel   1469:            if (nbchars != 0) break;
1.77      daniel   1470: 
                   1471:            xmlParsePEReference(ctxt);
1.79      daniel   1472: 
1.97      daniel   1473:            /*
1.79      daniel   1474:             * Pop-up of finished entities.
1.97      daniel   1475:             */
1.79      daniel   1476:            while ((CUR == 0) && (ctxt->inputNr > 1))
                   1477:                xmlPopInput(ctxt);
                   1478: 
1.98      daniel   1479:            break;
1.77      daniel   1480:        } else {
1.116     daniel   1481:            /*  invalid for UTF-8 , use COPY(out); !!!!!! */
1.97      daniel   1482:            *out++ = cur;
1.91      daniel   1483:            nbchars++;
1.140     daniel   1484:            if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) {
1.86      daniel   1485:              int index = out - buffer;
                   1486:              
                   1487:              growBuffer(buffer);
                   1488:              out = &buffer[index];
                   1489:            }
1.77      daniel   1490:            NEXT;
                   1491:        }
1.97      daniel   1492:        cur = CUR;
1.77      daniel   1493:     }
                   1494:     *out++ = 0;
                   1495:     return(buffer);
                   1496: }
                   1497: 
1.135     daniel   1498: /**
                   1499:  * xmlStringDecodeEntities:
                   1500:  * @ctxt:  the parser context
                   1501:  * @str:  the input string
                   1502:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
                   1503:  * @end:  an end marker xmlChar, 0 if none
                   1504:  * @end2:  an end marker xmlChar, 0 if none
                   1505:  * @end3:  an end marker xmlChar, 0 if none
                   1506:  * 
                   1507:  * [67] Reference ::= EntityRef | CharRef
                   1508:  *
                   1509:  * [69] PEReference ::= '%' Name ';'
                   1510:  *
                   1511:  * Returns A newly allocated string with the substitution done. The caller
                   1512:  *      must deallocate it !
                   1513:  */
                   1514: xmlChar *
                   1515: xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
                   1516:                        xmlChar end, xmlChar  end2, xmlChar end3) {
                   1517:     xmlChar *buffer = NULL;
                   1518:     int buffer_size = 0;
                   1519:     xmlChar *out = NULL;
                   1520: 
                   1521:     xmlChar *current = NULL;
                   1522:     xmlEntityPtr ent;
                   1523:     xmlChar cur;
                   1524: 
                   1525:     /*
                   1526:      * allocate a translation buffer.
                   1527:      */
1.140     daniel   1528:     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
1.135     daniel   1529:     buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
                   1530:     if (buffer == NULL) {
                   1531:        perror("xmlDecodeEntities: malloc failed");
                   1532:        return(NULL);
                   1533:     }
                   1534:     out = buffer;
                   1535: 
                   1536:     /*
                   1537:      * Ok loop until we reach one of the ending char or a size limit.
                   1538:      */
                   1539:     cur = *str;
                   1540:     while ((cur != 0) && (cur != end) &&
                   1541:            (cur != end2) && (cur != end3)) {
                   1542: 
                   1543:        if (cur == 0) break;
                   1544:         if ((cur == '&') && (str[1] == '#')) {
                   1545:            int val = xmlParseStringCharRef(ctxt, &str);
                   1546:            if (val != 0)
                   1547:                *out++ = val;
                   1548:        } else if ((cur == '&') && (what & XML_SUBSTITUTE_REF)) {
                   1549:            ent = xmlParseStringEntityRef(ctxt, &str);
                   1550:            if ((ent != NULL) && 
                   1551:                (ctxt->replaceEntities != 0)) {
                   1552:                current = ent->content;
                   1553:                while (*current != 0) {
                   1554:                    *out++ = *current++;
1.140     daniel   1555:                    if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) {
1.135     daniel   1556:                        int index = out - buffer;
                   1557: 
                   1558:                        growBuffer(buffer);
                   1559:                        out = &buffer[index];
                   1560:                    }
                   1561:                }
                   1562:            } else if (ent != NULL) {
                   1563:                int i = xmlStrlen(ent->name);
                   1564:                const xmlChar *cur = ent->name;
                   1565: 
                   1566:                *out++ = '&';
1.140     daniel   1567:                if (out - buffer > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
1.135     daniel   1568:                    int index = out - buffer;
                   1569: 
                   1570:                    growBuffer(buffer);
                   1571:                    out = &buffer[index];
                   1572:                }
                   1573:                for (;i > 0;i--)
                   1574:                    *out++ = *cur++;
                   1575:                *out++ = ';';
                   1576:            }
                   1577:        } else if (cur == '%' && (what & XML_SUBSTITUTE_PEREF)) {
                   1578:            ent = xmlParseStringPEReference(ctxt, &str);
                   1579:            if (ent != NULL) {
                   1580:                current = ent->content;
                   1581:                while (*current != 0) {
                   1582:                    *out++ = *current++;
1.140     daniel   1583:                    if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) {
1.135     daniel   1584:                        int index = out - buffer;
                   1585: 
                   1586:                        growBuffer(buffer);
                   1587:                        out = &buffer[index];
                   1588:                    }
                   1589:                }
                   1590:            }
                   1591:        } else {
                   1592:            /*  invalid for UTF-8 , use COPY(out); !!!!!! */
                   1593:            *out++ = cur;
1.140     daniel   1594:            if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) {
1.135     daniel   1595:              int index = out - buffer;
                   1596:              
                   1597:              growBuffer(buffer);
                   1598:              out = &buffer[index];
                   1599:            }
                   1600:            str++;
                   1601:        }
                   1602:        cur = *str;
                   1603:     }
                   1604:     *out = 0;
                   1605:     return(buffer);
                   1606: }
                   1607: 
1.1       veillard 1608: 
1.28      daniel   1609: /************************************************************************
                   1610:  *                                                                     *
1.75      daniel   1611:  *             Commodity functions to handle encodings                 *
                   1612:  *                                                                     *
                   1613:  ************************************************************************/
                   1614: 
                   1615: /**
                   1616:  * xmlSwitchEncoding:
                   1617:  * @ctxt:  the parser context
1.124     daniel   1618:  * @enc:  the encoding value (number)
1.75      daniel   1619:  *
                   1620:  * change the input functions when discovering the character encoding
                   1621:  * of a given entity.
                   1622:  */
                   1623: void
                   1624: xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
                   1625: {
                   1626:     switch (enc) {
                   1627:         case XML_CHAR_ENCODING_ERROR:
1.123     daniel   1628:            ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
1.75      daniel   1629:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1630:                ctxt->sax->error(ctxt->userData, "encoding unknown\n");
                   1631:            ctxt->wellFormed = 0;
                   1632:             break;
                   1633:         case XML_CHAR_ENCODING_NONE:
                   1634:            /* let's assume it's UTF-8 without the XML decl */
                   1635:             return;
                   1636:         case XML_CHAR_ENCODING_UTF8:
                   1637:            /* default encoding, no conversion should be needed */
                   1638:             return;
                   1639:         case XML_CHAR_ENCODING_UTF16LE:
1.123     daniel   1640:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1641:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1642:                 ctxt->sax->error(ctxt->userData,
                   1643:                  "char encoding UTF16 little endian not supported\n");
                   1644:             break;
                   1645:         case XML_CHAR_ENCODING_UTF16BE:
1.123     daniel   1646:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1647:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1648:                 ctxt->sax->error(ctxt->userData,
                   1649:                  "char encoding UTF16 big endian not supported\n");
                   1650:             break;
                   1651:         case XML_CHAR_ENCODING_UCS4LE:
1.123     daniel   1652:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1653:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1654:                 ctxt->sax->error(ctxt->userData,
                   1655:                  "char encoding USC4 little endian not supported\n");
                   1656:             break;
                   1657:         case XML_CHAR_ENCODING_UCS4BE:
1.123     daniel   1658:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1659:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1660:                 ctxt->sax->error(ctxt->userData,
                   1661:                  "char encoding USC4 big endian not supported\n");
                   1662:             break;
                   1663:         case XML_CHAR_ENCODING_EBCDIC:
1.123     daniel   1664:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1665:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1666:                 ctxt->sax->error(ctxt->userData,
                   1667:                  "char encoding EBCDIC not supported\n");
                   1668:             break;
                   1669:         case XML_CHAR_ENCODING_UCS4_2143:
1.123     daniel   1670:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1671:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1672:                 ctxt->sax->error(ctxt->userData,
                   1673:                  "char encoding UCS4 2143 not supported\n");
                   1674:             break;
                   1675:         case XML_CHAR_ENCODING_UCS4_3412:
1.123     daniel   1676:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1677:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1678:                 ctxt->sax->error(ctxt->userData,
                   1679:                  "char encoding UCS4 3412 not supported\n");
                   1680:             break;
                   1681:         case XML_CHAR_ENCODING_UCS2:
1.123     daniel   1682:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1683:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1684:                 ctxt->sax->error(ctxt->userData,
                   1685:                  "char encoding UCS2 not supported\n");
                   1686:             break;
                   1687:         case XML_CHAR_ENCODING_8859_1:
1.123     daniel   1688:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1689:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1690:                 ctxt->sax->error(ctxt->userData,
                   1691:                  "char encoding ISO_8859_1 ISO Latin 1 not supported\n");
                   1692:             break;
                   1693:         case XML_CHAR_ENCODING_8859_2:
1.123     daniel   1694:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1695:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1696:                 ctxt->sax->error(ctxt->userData,
                   1697:                  "char encoding ISO_8859_2 ISO Latin 2 not supported\n");
                   1698:             break;
                   1699:         case XML_CHAR_ENCODING_8859_3:
1.123     daniel   1700:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1701:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1702:                 ctxt->sax->error(ctxt->userData,
                   1703:                  "char encoding ISO_8859_3 not supported\n");
                   1704:             break;
                   1705:         case XML_CHAR_ENCODING_8859_4:
1.123     daniel   1706:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1707:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1708:                 ctxt->sax->error(ctxt->userData,
                   1709:                  "char encoding ISO_8859_4 not supported\n");
                   1710:             break;
                   1711:         case XML_CHAR_ENCODING_8859_5:
1.123     daniel   1712:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1713:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1714:                 ctxt->sax->error(ctxt->userData,
                   1715:                  "char encoding ISO_8859_5 not supported\n");
                   1716:             break;
                   1717:         case XML_CHAR_ENCODING_8859_6:
1.123     daniel   1718:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1719:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1720:                 ctxt->sax->error(ctxt->userData,
                   1721:                  "char encoding ISO_8859_6 not supported\n");
                   1722:             break;
                   1723:         case XML_CHAR_ENCODING_8859_7:
1.123     daniel   1724:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1725:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1726:                 ctxt->sax->error(ctxt->userData,
                   1727:                  "char encoding ISO_8859_7 not supported\n");
                   1728:             break;
                   1729:         case XML_CHAR_ENCODING_8859_8:
1.123     daniel   1730:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1731:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1732:                 ctxt->sax->error(ctxt->userData,
                   1733:                  "char encoding ISO_8859_8 not supported\n");
                   1734:             break;
                   1735:         case XML_CHAR_ENCODING_8859_9:
1.123     daniel   1736:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1737:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1738:                 ctxt->sax->error(ctxt->userData,
                   1739:                  "char encoding ISO_8859_9 not supported\n");
                   1740:             break;
                   1741:         case XML_CHAR_ENCODING_2022_JP:
1.123     daniel   1742:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1743:             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1744:                 ctxt->sax->error(ctxt->userData,
                   1745:                   "char encoding ISO-2022-JPnot supported\n");
                   1746:             break;
                   1747:         case XML_CHAR_ENCODING_SHIFT_JIS:
1.123     daniel   1748:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1749:             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1750:                 ctxt->sax->error(ctxt->userData,
                   1751:                   "char encoding Shift_JISnot supported\n");
                   1752:             break;
                   1753:         case XML_CHAR_ENCODING_EUC_JP:
1.123     daniel   1754:            ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
1.75      daniel   1755:             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1756:                 ctxt->sax->error(ctxt->userData,
                   1757:                   "char encoding EUC-JPnot supported\n");
                   1758:             break;
                   1759:     }
                   1760: }
                   1761: 
                   1762: /************************************************************************
                   1763:  *                                                                     *
1.123     daniel   1764:  *             Commodity functions to handle xmlChars                  *
1.28      daniel   1765:  *                                                                     *
                   1766:  ************************************************************************/
                   1767: 
1.50      daniel   1768: /**
                   1769:  * xmlStrndup:
1.123     daniel   1770:  * @cur:  the input xmlChar *
1.50      daniel   1771:  * @len:  the len of @cur
                   1772:  *
1.123     daniel   1773:  * a strndup for array of xmlChar's
1.68      daniel   1774:  *
1.123     daniel   1775:  * Returns a new xmlChar * or NULL
1.1       veillard 1776:  */
1.123     daniel   1777: xmlChar *
                   1778: xmlStrndup(const xmlChar *cur, int len) {
1.135     daniel   1779:     xmlChar *ret;
                   1780:     
                   1781:     if ((cur == NULL) || (len < 0)) return(NULL);
                   1782:     ret = xmlMalloc((len + 1) * sizeof(xmlChar));
1.1       veillard 1783:     if (ret == NULL) {
1.86      daniel   1784:         fprintf(stderr, "malloc of %ld byte failed\n",
1.123     daniel   1785:                (len + 1) * (long)sizeof(xmlChar));
1.1       veillard 1786:         return(NULL);
                   1787:     }
1.123     daniel   1788:     memcpy(ret, cur, len * sizeof(xmlChar));
1.1       veillard 1789:     ret[len] = 0;
                   1790:     return(ret);
                   1791: }
                   1792: 
1.50      daniel   1793: /**
                   1794:  * xmlStrdup:
1.123     daniel   1795:  * @cur:  the input xmlChar *
1.50      daniel   1796:  *
1.123     daniel   1797:  * a strdup for array of xmlChar's
1.68      daniel   1798:  *
1.123     daniel   1799:  * Returns a new xmlChar * or NULL
1.1       veillard 1800:  */
1.123     daniel   1801: xmlChar *
                   1802: xmlStrdup(const xmlChar *cur) {
                   1803:     const xmlChar *p = cur;
1.1       veillard 1804: 
1.135     daniel   1805:     if (cur == NULL) return(NULL);
1.1       veillard 1806:     while (IS_CHAR(*p)) p++;
                   1807:     return(xmlStrndup(cur, p - cur));
                   1808: }
                   1809: 
1.50      daniel   1810: /**
                   1811:  * xmlCharStrndup:
                   1812:  * @cur:  the input char *
                   1813:  * @len:  the len of @cur
                   1814:  *
1.123     daniel   1815:  * a strndup for char's to xmlChar's
1.68      daniel   1816:  *
1.123     daniel   1817:  * Returns a new xmlChar * or NULL
1.45      daniel   1818:  */
                   1819: 
1.123     daniel   1820: xmlChar *
1.55      daniel   1821: xmlCharStrndup(const char *cur, int len) {
1.45      daniel   1822:     int i;
1.135     daniel   1823:     xmlChar *ret;
                   1824:     
                   1825:     if ((cur == NULL) || (len < 0)) return(NULL);
                   1826:     ret = xmlMalloc((len + 1) * sizeof(xmlChar));
1.45      daniel   1827:     if (ret == NULL) {
1.86      daniel   1828:         fprintf(stderr, "malloc of %ld byte failed\n",
1.123     daniel   1829:                (len + 1) * (long)sizeof(xmlChar));
1.45      daniel   1830:         return(NULL);
                   1831:     }
                   1832:     for (i = 0;i < len;i++)
1.123     daniel   1833:         ret[i] = (xmlChar) cur[i];
1.45      daniel   1834:     ret[len] = 0;
                   1835:     return(ret);
                   1836: }
                   1837: 
1.50      daniel   1838: /**
                   1839:  * xmlCharStrdup:
                   1840:  * @cur:  the input char *
                   1841:  * @len:  the len of @cur
                   1842:  *
1.123     daniel   1843:  * a strdup for char's to xmlChar's
1.68      daniel   1844:  *
1.123     daniel   1845:  * Returns a new xmlChar * or NULL
1.45      daniel   1846:  */
                   1847: 
1.123     daniel   1848: xmlChar *
1.55      daniel   1849: xmlCharStrdup(const char *cur) {
1.45      daniel   1850:     const char *p = cur;
                   1851: 
1.135     daniel   1852:     if (cur == NULL) return(NULL);
1.45      daniel   1853:     while (*p != '\0') p++;
                   1854:     return(xmlCharStrndup(cur, p - cur));
                   1855: }
                   1856: 
1.50      daniel   1857: /**
                   1858:  * xmlStrcmp:
1.123     daniel   1859:  * @str1:  the first xmlChar *
                   1860:  * @str2:  the second xmlChar *
1.50      daniel   1861:  *
1.123     daniel   1862:  * a strcmp for xmlChar's
1.68      daniel   1863:  *
                   1864:  * Returns the integer result of the comparison
1.14      veillard 1865:  */
                   1866: 
1.55      daniel   1867: int
1.123     daniel   1868: xmlStrcmp(const xmlChar *str1, const xmlChar *str2) {
1.14      veillard 1869:     register int tmp;
                   1870: 
1.135     daniel   1871:     if ((str1 == NULL) && (str2 == NULL)) return(0);
                   1872:     if (str1 == NULL) return(-1);
                   1873:     if (str2 == NULL) return(1);
1.14      veillard 1874:     do {
                   1875:         tmp = *str1++ - *str2++;
                   1876:        if (tmp != 0) return(tmp);
                   1877:     } while ((*str1 != 0) && (*str2 != 0));
                   1878:     return (*str1 - *str2);
                   1879: }
                   1880: 
1.50      daniel   1881: /**
                   1882:  * xmlStrncmp:
1.123     daniel   1883:  * @str1:  the first xmlChar *
                   1884:  * @str2:  the second xmlChar *
1.50      daniel   1885:  * @len:  the max comparison length
                   1886:  *
1.123     daniel   1887:  * a strncmp for xmlChar's
1.68      daniel   1888:  *
                   1889:  * Returns the integer result of the comparison
1.14      veillard 1890:  */
                   1891: 
1.55      daniel   1892: int
1.123     daniel   1893: xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) {
1.14      veillard 1894:     register int tmp;
                   1895: 
                   1896:     if (len <= 0) return(0);
1.135     daniel   1897:     if ((str1 == NULL) && (str2 == NULL)) return(0);
                   1898:     if (str1 == NULL) return(-1);
                   1899:     if (str2 == NULL) return(1);
1.14      veillard 1900:     do {
                   1901:         tmp = *str1++ - *str2++;
                   1902:        if (tmp != 0) return(tmp);
                   1903:        len--;
                   1904:         if (len <= 0) return(0);
                   1905:     } while ((*str1 != 0) && (*str2 != 0));
                   1906:     return (*str1 - *str2);
                   1907: }
                   1908: 
1.50      daniel   1909: /**
                   1910:  * xmlStrchr:
1.123     daniel   1911:  * @str:  the xmlChar * array
                   1912:  * @val:  the xmlChar to search
1.50      daniel   1913:  *
1.123     daniel   1914:  * a strchr for xmlChar's
1.68      daniel   1915:  *
1.123     daniel   1916:  * Returns the xmlChar * for the first occurence or NULL.
1.14      veillard 1917:  */
                   1918: 
1.123     daniel   1919: const xmlChar *
                   1920: xmlStrchr(const xmlChar *str, xmlChar val) {
1.135     daniel   1921:     if (str == NULL) return(NULL);
1.14      veillard 1922:     while (*str != 0) {
1.123     daniel   1923:         if (*str == val) return((xmlChar *) str);
1.14      veillard 1924:        str++;
                   1925:     }
                   1926:     return(NULL);
1.89      daniel   1927: }
                   1928: 
                   1929: /**
                   1930:  * xmlStrstr:
1.123     daniel   1931:  * @str:  the xmlChar * array (haystack)
                   1932:  * @val:  the xmlChar to search (needle)
1.89      daniel   1933:  *
1.123     daniel   1934:  * a strstr for xmlChar's
1.89      daniel   1935:  *
1.123     daniel   1936:  * Returns the xmlChar * for the first occurence or NULL.
1.89      daniel   1937:  */
                   1938: 
1.123     daniel   1939: const xmlChar *
                   1940: xmlStrstr(const xmlChar *str, xmlChar *val) {
1.89      daniel   1941:     int n;
                   1942:     
                   1943:     if (str == NULL) return(NULL);
                   1944:     if (val == NULL) return(NULL);
                   1945:     n = xmlStrlen(val);
                   1946: 
                   1947:     if (n == 0) return(str);
                   1948:     while (*str != 0) {
                   1949:         if (*str == *val) {
1.123     daniel   1950:            if (!xmlStrncmp(str, val, n)) return((const xmlChar *) str);
1.89      daniel   1951:        }
                   1952:        str++;
                   1953:     }
                   1954:     return(NULL);
                   1955: }
                   1956: 
                   1957: /**
                   1958:  * xmlStrsub:
1.123     daniel   1959:  * @str:  the xmlChar * array (haystack)
1.89      daniel   1960:  * @start:  the index of the first char (zero based)
                   1961:  * @len:  the length of the substring
                   1962:  *
                   1963:  * Extract a substring of a given string
                   1964:  *
1.123     daniel   1965:  * Returns the xmlChar * for the first occurence or NULL.
1.89      daniel   1966:  */
                   1967: 
1.123     daniel   1968: xmlChar *
                   1969: xmlStrsub(const xmlChar *str, int start, int len) {
1.89      daniel   1970:     int i;
                   1971:     
                   1972:     if (str == NULL) return(NULL);
                   1973:     if (start < 0) return(NULL);
1.90      daniel   1974:     if (len < 0) return(NULL);
1.89      daniel   1975: 
                   1976:     for (i = 0;i < start;i++) {
                   1977:         if (*str == 0) return(NULL);
                   1978:        str++;
                   1979:     }
                   1980:     if (*str == 0) return(NULL);
                   1981:     return(xmlStrndup(str, len));
1.14      veillard 1982: }
1.28      daniel   1983: 
1.50      daniel   1984: /**
                   1985:  * xmlStrlen:
1.123     daniel   1986:  * @str:  the xmlChar * array
1.50      daniel   1987:  *
1.127     daniel   1988:  * length of a xmlChar's string
1.68      daniel   1989:  *
1.123     daniel   1990:  * Returns the number of xmlChar contained in the ARRAY.
1.45      daniel   1991:  */
                   1992: 
1.55      daniel   1993: int
1.123     daniel   1994: xmlStrlen(const xmlChar *str) {
1.45      daniel   1995:     int len = 0;
                   1996: 
                   1997:     if (str == NULL) return(0);
                   1998:     while (*str != 0) {
                   1999:        str++;
                   2000:        len++;
                   2001:     }
                   2002:     return(len);
                   2003: }
                   2004: 
1.50      daniel   2005: /**
                   2006:  * xmlStrncat:
1.123     daniel   2007:  * @cur:  the original xmlChar * array
                   2008:  * @add:  the xmlChar * array added
1.50      daniel   2009:  * @len:  the length of @add
                   2010:  *
1.123     daniel   2011:  * a strncat for array of xmlChar's
1.68      daniel   2012:  *
1.123     daniel   2013:  * Returns a new xmlChar * containing the concatenated string.
1.45      daniel   2014:  */
                   2015: 
1.123     daniel   2016: xmlChar *
                   2017: xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
1.45      daniel   2018:     int size;
1.123     daniel   2019:     xmlChar *ret;
1.45      daniel   2020: 
                   2021:     if ((add == NULL) || (len == 0))
                   2022:         return(cur);
                   2023:     if (cur == NULL)
                   2024:         return(xmlStrndup(add, len));
                   2025: 
                   2026:     size = xmlStrlen(cur);
1.123     daniel   2027:     ret = xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
1.45      daniel   2028:     if (ret == NULL) {
1.86      daniel   2029:         fprintf(stderr, "xmlStrncat: realloc of %ld byte failed\n",
1.123     daniel   2030:                (size + len + 1) * (long)sizeof(xmlChar));
1.45      daniel   2031:         return(cur);
                   2032:     }
1.123     daniel   2033:     memcpy(&ret[size], add, len * sizeof(xmlChar));
1.45      daniel   2034:     ret[size + len] = 0;
                   2035:     return(ret);
                   2036: }
                   2037: 
1.50      daniel   2038: /**
                   2039:  * xmlStrcat:
1.123     daniel   2040:  * @cur:  the original xmlChar * array
                   2041:  * @add:  the xmlChar * array added
1.50      daniel   2042:  *
1.123     daniel   2043:  * a strcat for array of xmlChar's
1.68      daniel   2044:  *
1.123     daniel   2045:  * Returns a new xmlChar * containing the concatenated string.
1.45      daniel   2046:  */
1.123     daniel   2047: xmlChar *
                   2048: xmlStrcat(xmlChar *cur, const xmlChar *add) {
                   2049:     const xmlChar *p = add;
1.45      daniel   2050: 
                   2051:     if (add == NULL) return(cur);
                   2052:     if (cur == NULL) 
                   2053:         return(xmlStrdup(add));
                   2054: 
                   2055:     while (IS_CHAR(*p)) p++;
                   2056:     return(xmlStrncat(cur, add, p - add));
                   2057: }
                   2058: 
                   2059: /************************************************************************
                   2060:  *                                                                     *
                   2061:  *             Commodity functions, cleanup needed ?                   *
                   2062:  *                                                                     *
                   2063:  ************************************************************************/
                   2064: 
1.50      daniel   2065: /**
                   2066:  * areBlanks:
                   2067:  * @ctxt:  an XML parser context
1.123     daniel   2068:  * @str:  a xmlChar *
1.50      daniel   2069:  * @len:  the size of @str
                   2070:  *
1.45      daniel   2071:  * Is this a sequence of blank chars that one can ignore ?
1.50      daniel   2072:  *
1.68      daniel   2073:  * Returns 1 if ignorable 0 otherwise.
1.45      daniel   2074:  */
                   2075: 
1.123     daniel   2076: static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
1.104     daniel   2077:     int i, ret;
1.45      daniel   2078:     xmlNodePtr lastChild;
                   2079: 
                   2080:     for (i = 0;i < len;i++)
                   2081:         if (!(IS_BLANK(str[i]))) return(0);
                   2082: 
                   2083:     if (CUR != '<') return(0);
1.72      daniel   2084:     if (ctxt->node == NULL) return(0);
1.104     daniel   2085:     if (ctxt->myDoc != NULL) {
                   2086:        ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
                   2087:         if (ret == 0) return(1);
                   2088:         if (ret == 1) return(0);
                   2089:     }
                   2090:     /*
                   2091:      * heuristic
                   2092:      */
1.45      daniel   2093:     lastChild = xmlGetLastChild(ctxt->node);
                   2094:     if (lastChild == NULL) {
                   2095:         if (ctxt->node->content != NULL) return(0);
                   2096:     } else if (xmlNodeIsText(lastChild))
                   2097:         return(0);
1.104     daniel   2098:     else if ((ctxt->node->childs != NULL) &&
                   2099:              (xmlNodeIsText(ctxt->node->childs)))
                   2100:         return(0);
1.45      daniel   2101:     return(1);
                   2102: }
                   2103: 
1.50      daniel   2104: /**
                   2105:  * xmlHandleEntity:
                   2106:  * @ctxt:  an XML parser context
                   2107:  * @entity:  an XML entity pointer.
                   2108:  *
                   2109:  * Default handling of defined entities, when should we define a new input
1.45      daniel   2110:  * stream ? When do we just handle that as a set of chars ?
1.99      daniel   2111:  *
                   2112:  * OBSOLETE: to be removed at some point.
1.45      daniel   2113:  */
                   2114: 
1.55      daniel   2115: void
                   2116: xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
1.45      daniel   2117:     int len;
1.50      daniel   2118:     xmlParserInputPtr input;
1.45      daniel   2119: 
                   2120:     if (entity->content == NULL) {
1.123     daniel   2121:        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.55      daniel   2122:         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   2123:            ctxt->sax->error(ctxt->userData, "xmlHandleEntity %s: content == NULL\n",
1.45      daniel   2124:                       entity->name);
1.59      daniel   2125:        ctxt->wellFormed = 0;
1.45      daniel   2126:         return;
                   2127:     }
                   2128:     len = xmlStrlen(entity->content);
                   2129:     if (len <= 2) goto handle_as_char;
                   2130: 
                   2131:     /*
                   2132:      * Redefine its content as an input stream.
                   2133:      */
1.50      daniel   2134:     input = xmlNewEntityInputStream(ctxt, entity);
                   2135:     xmlPushInput(ctxt, input);
1.45      daniel   2136:     return;
                   2137: 
                   2138: handle_as_char:
                   2139:     /*
                   2140:      * Just handle the content as a set of chars.
                   2141:      */
1.72      daniel   2142:     if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
1.74      daniel   2143:        ctxt->sax->characters(ctxt->userData, entity->content, len);
1.45      daniel   2144: 
                   2145: }
                   2146: 
                   2147: /*
                   2148:  * Forward definition for recusive behaviour.
                   2149:  */
1.77      daniel   2150: void xmlParsePEReference(xmlParserCtxtPtr ctxt);
                   2151: void xmlParseReference(xmlParserCtxtPtr ctxt);
1.45      daniel   2152: 
1.28      daniel   2153: /************************************************************************
                   2154:  *                                                                     *
                   2155:  *             Extra stuff for namespace support                       *
                   2156:  *     Relates to http://www.w3.org/TR/WD-xml-names                    *
                   2157:  *                                                                     *
                   2158:  ************************************************************************/
                   2159: 
1.50      daniel   2160: /**
                   2161:  * xmlNamespaceParseNCName:
                   2162:  * @ctxt:  an XML parser context
                   2163:  *
                   2164:  * parse an XML namespace name.
1.28      daniel   2165:  *
                   2166:  * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
                   2167:  *
                   2168:  * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
                   2169:  *                       CombiningChar | Extender
1.68      daniel   2170:  *
                   2171:  * Returns the namespace name or NULL
1.28      daniel   2172:  */
                   2173: 
1.123     daniel   2174: xmlChar *
1.55      daniel   2175: xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt) {
1.123     daniel   2176:     xmlChar buf[XML_MAX_NAMELEN];
1.91      daniel   2177:     int len = 0;
1.28      daniel   2178: 
1.40      daniel   2179:     if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
1.28      daniel   2180: 
1.40      daniel   2181:     while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
                   2182:            (CUR == '.') || (CUR == '-') ||
                   2183:           (CUR == '_') ||
                   2184:           (IS_COMBINING(CUR)) ||
1.91      daniel   2185:           (IS_EXTENDER(CUR))) {
                   2186:        buf[len++] = CUR;
1.40      daniel   2187:        NEXT;
1.91      daniel   2188:        if (len >= XML_MAX_NAMELEN) {
                   2189:            fprintf(stderr, 
                   2190:               "xmlNamespaceParseNCName: reached XML_MAX_NAMELEN limit\n");
                   2191:            while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
                   2192:                   (CUR == '.') || (CUR == '-') ||
                   2193:                   (CUR == '_') ||
                   2194:                   (IS_COMBINING(CUR)) ||
                   2195:                   (IS_EXTENDER(CUR)))
                   2196:                 NEXT;
                   2197:            break;
                   2198:        }
                   2199:     }
                   2200:     return(xmlStrndup(buf, len));
1.28      daniel   2201: }
                   2202: 
1.50      daniel   2203: /**
                   2204:  * xmlNamespaceParseQName:
                   2205:  * @ctxt:  an XML parser context
1.123     daniel   2206:  * @prefix:  a xmlChar ** 
1.50      daniel   2207:  *
                   2208:  * parse an XML qualified name
1.28      daniel   2209:  *
                   2210:  * [NS 5] QName ::= (Prefix ':')? LocalPart
                   2211:  *
                   2212:  * [NS 6] Prefix ::= NCName
                   2213:  *
                   2214:  * [NS 7] LocalPart ::= NCName
1.68      daniel   2215:  *
1.127     daniel   2216:  * Returns the local part, and prefix is updated
1.50      daniel   2217:  *   to get the Prefix if any.
1.28      daniel   2218:  */
                   2219: 
1.123     daniel   2220: xmlChar *
                   2221: xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, xmlChar **prefix) {
                   2222:     xmlChar *ret = NULL;
1.28      daniel   2223: 
                   2224:     *prefix = NULL;
                   2225:     ret = xmlNamespaceParseNCName(ctxt);
1.40      daniel   2226:     if (CUR == ':') {
1.28      daniel   2227:         *prefix = ret;
1.40      daniel   2228:        NEXT;
1.28      daniel   2229:        ret = xmlNamespaceParseNCName(ctxt);
                   2230:     }
                   2231: 
                   2232:     return(ret);
                   2233: }
                   2234: 
1.50      daniel   2235: /**
1.72      daniel   2236:  * xmlSplitQName:
                   2237:  * @name:  an XML parser context
1.123     daniel   2238:  * @prefix:  a xmlChar ** 
1.72      daniel   2239:  *
                   2240:  * parse an XML qualified name string
                   2241:  *
                   2242:  * [NS 5] QName ::= (Prefix ':')? LocalPart
                   2243:  *
                   2244:  * [NS 6] Prefix ::= NCName
                   2245:  *
                   2246:  * [NS 7] LocalPart ::= NCName
                   2247:  *
1.127     daniel   2248:  * Returns the local part, and prefix is updated
1.72      daniel   2249:  *   to get the Prefix if any.
                   2250:  */
                   2251: 
1.123     daniel   2252: xmlChar *
                   2253: xmlSplitQName(const xmlChar *name, xmlChar **prefix) {
                   2254:     xmlChar *ret = NULL;
                   2255:     const xmlChar *q;
                   2256:     const xmlChar *cur = name;
1.72      daniel   2257: 
                   2258:     *prefix = NULL;
1.113     daniel   2259: 
                   2260:     /* xml: prefix is not really a namespace */
                   2261:     if ((cur[0] == 'x') && (cur[1] == 'm') &&
                   2262:         (cur[2] == 'l') && (cur[3] == ':'))
                   2263:        return(xmlStrdup(name));
                   2264: 
1.72      daniel   2265:     if (!IS_LETTER(*cur) && (*cur != '_')) return(NULL);
                   2266:     q = cur++;
                   2267: 
                   2268:     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   2269:            (*cur == '.') || (*cur == '-') ||
                   2270:           (*cur == '_') ||
                   2271:           (IS_COMBINING(*cur)) ||
                   2272:           (IS_EXTENDER(*cur)))
                   2273:        cur++;
                   2274:     
                   2275:     ret = xmlStrndup(q, cur - q);
                   2276: 
                   2277:     if (*cur == ':') {
                   2278:        cur++;
                   2279:        if (!IS_LETTER(*cur) && (*cur != '_')) return(ret);
                   2280:         *prefix = ret;
                   2281: 
                   2282:        q = cur++;
                   2283: 
                   2284:        while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   2285:               (*cur == '.') || (*cur == '-') ||
                   2286:               (*cur == '_') ||
                   2287:               (IS_COMBINING(*cur)) ||
                   2288:               (IS_EXTENDER(*cur)))
                   2289:            cur++;
                   2290:        
                   2291:        ret = xmlStrndup(q, cur - q);
                   2292:     }
                   2293: 
                   2294:     return(ret);
                   2295: }
                   2296: /**
1.50      daniel   2297:  * xmlNamespaceParseNSDef:
                   2298:  * @ctxt:  an XML parser context
                   2299:  *
                   2300:  * parse a namespace prefix declaration
1.28      daniel   2301:  *
                   2302:  * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
                   2303:  *
                   2304:  * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
1.68      daniel   2305:  *
                   2306:  * Returns the namespace name
1.28      daniel   2307:  */
                   2308: 
1.123     daniel   2309: xmlChar *
1.55      daniel   2310: xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt) {
1.123     daniel   2311:     xmlChar *name = NULL;
1.28      daniel   2312: 
1.40      daniel   2313:     if ((CUR == 'x') && (NXT(1) == 'm') &&
                   2314:         (NXT(2) == 'l') && (NXT(3) == 'n') &&
                   2315:        (NXT(4) == 's')) {
                   2316:        SKIP(5);
                   2317:        if (CUR == ':') {
                   2318:            NEXT;
1.28      daniel   2319:            name = xmlNamespaceParseNCName(ctxt);
                   2320:        }
                   2321:     }
1.39      daniel   2322:     return(name);
1.28      daniel   2323: }
                   2324: 
1.50      daniel   2325: /**
                   2326:  * xmlParseQuotedString:
                   2327:  * @ctxt:  an XML parser context
                   2328:  *
1.45      daniel   2329:  * [OLD] Parse and return a string between quotes or doublequotes
1.110     daniel   2330:  * To be removed at next drop of binary compatibility
1.68      daniel   2331:  *
                   2332:  * Returns the string parser or NULL.
1.45      daniel   2333:  */
1.123     daniel   2334: xmlChar *
1.55      daniel   2335: xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
1.135     daniel   2336:     xmlChar *buf = NULL;
                   2337:     int len = 0;
1.140     daniel   2338:     int size = XML_PARSER_BUFFER_SIZE;
1.135     daniel   2339:     xmlChar c;
1.45      daniel   2340: 
1.135     daniel   2341:     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   2342:     if (buf == NULL) {
                   2343:        fprintf(stderr, "malloc of %d byte failed\n", size);
                   2344:        return(NULL);
                   2345:     }
1.45      daniel   2346:     if (CUR == '"') {
                   2347:         NEXT;
1.135     daniel   2348:        c = CUR;
                   2349:        while (IS_CHAR(c) && (c != '"')) {
                   2350:            if (len + 1 >= size) {
                   2351:                size *= 2;
                   2352:                buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   2353:                if (buf == NULL) {
                   2354:                    fprintf(stderr, "realloc of %d byte failed\n", size);
                   2355:                    return(NULL);
                   2356:                }
                   2357:            }
                   2358:            buf[len++] = c;
                   2359:            NEXT;
                   2360:            c = CUR;
                   2361:        }
                   2362:        if (c != '"') {
1.123     daniel   2363:            ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.55      daniel   2364:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.135     daniel   2365:                ctxt->sax->error(ctxt->userData, 
                   2366:                                 "String not closed \"%.50s\"\n", buf);
1.59      daniel   2367:            ctxt->wellFormed = 0;
1.55      daniel   2368:         } else {
1.45      daniel   2369:            NEXT;
                   2370:        }
                   2371:     } else if (CUR == '\''){
                   2372:         NEXT;
1.135     daniel   2373:        c = CUR;
                   2374:        while (IS_CHAR(c) && (c != '\'')) {
                   2375:            if (len + 1 >= size) {
                   2376:                size *= 2;
                   2377:                buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   2378:                if (buf == NULL) {
                   2379:                    fprintf(stderr, "realloc of %d byte failed\n", size);
                   2380:                    return(NULL);
                   2381:                }
                   2382:            }
                   2383:            buf[len++] = c;
                   2384:            NEXT;
                   2385:            c = CUR;
                   2386:        }
1.55      daniel   2387:        if (CUR != '\'') {
1.123     daniel   2388:            ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.55      daniel   2389:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.135     daniel   2390:                ctxt->sax->error(ctxt->userData,
                   2391:                                 "String not closed \"%.50s\"\n", buf);
1.59      daniel   2392:            ctxt->wellFormed = 0;
1.55      daniel   2393:         } else {
1.45      daniel   2394:            NEXT;
                   2395:        }
                   2396:     }
1.135     daniel   2397:     return(buf);
1.45      daniel   2398: }
                   2399: 
1.50      daniel   2400: /**
                   2401:  * xmlParseNamespace:
                   2402:  * @ctxt:  an XML parser context
                   2403:  *
1.45      daniel   2404:  * [OLD] xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
                   2405:  *
                   2406:  * This is what the older xml-name Working Draft specified, a bunch of
                   2407:  * other stuff may still rely on it, so support is still here as
1.127     daniel   2408:  * if it was declared on the root of the Tree:-(
1.110     daniel   2409:  *
                   2410:  * To be removed at next drop of binary compatibility
1.45      daniel   2411:  */
                   2412: 
1.55      daniel   2413: void
                   2414: xmlParseNamespace(xmlParserCtxtPtr ctxt) {
1.123     daniel   2415:     xmlChar *href = NULL;
                   2416:     xmlChar *prefix = NULL;
1.45      daniel   2417:     int garbage = 0;
                   2418: 
                   2419:     /*
                   2420:      * We just skipped "namespace" or "xml:namespace"
                   2421:      */
                   2422:     SKIP_BLANKS;
                   2423: 
                   2424:     while (IS_CHAR(CUR) && (CUR != '>')) {
                   2425:        /*
                   2426:         * We can have "ns" or "prefix" attributes
                   2427:         * Old encoding as 'href' or 'AS' attributes is still supported
                   2428:         */
                   2429:        if ((CUR == 'n') && (NXT(1) == 's')) {
                   2430:            garbage = 0;
                   2431:            SKIP(2);
                   2432:            SKIP_BLANKS;
                   2433: 
                   2434:            if (CUR != '=') continue;
                   2435:            NEXT;
                   2436:            SKIP_BLANKS;
                   2437: 
                   2438:            href = xmlParseQuotedString(ctxt);
                   2439:            SKIP_BLANKS;
                   2440:        } else if ((CUR == 'h') && (NXT(1) == 'r') &&
                   2441:            (NXT(2) == 'e') && (NXT(3) == 'f')) {
                   2442:            garbage = 0;
                   2443:            SKIP(4);
                   2444:            SKIP_BLANKS;
                   2445: 
                   2446:            if (CUR != '=') continue;
                   2447:            NEXT;
                   2448:            SKIP_BLANKS;
                   2449: 
                   2450:            href = xmlParseQuotedString(ctxt);
                   2451:            SKIP_BLANKS;
                   2452:        } else if ((CUR == 'p') && (NXT(1) == 'r') &&
                   2453:                   (NXT(2) == 'e') && (NXT(3) == 'f') &&
                   2454:                   (NXT(4) == 'i') && (NXT(5) == 'x')) {
                   2455:            garbage = 0;
                   2456:            SKIP(6);
                   2457:            SKIP_BLANKS;
                   2458: 
                   2459:            if (CUR != '=') continue;
                   2460:            NEXT;
                   2461:            SKIP_BLANKS;
                   2462: 
                   2463:            prefix = xmlParseQuotedString(ctxt);
                   2464:            SKIP_BLANKS;
                   2465:        } else if ((CUR == 'A') && (NXT(1) == 'S')) {
                   2466:            garbage = 0;
                   2467:            SKIP(2);
                   2468:            SKIP_BLANKS;
                   2469: 
                   2470:            if (CUR != '=') continue;
                   2471:            NEXT;
                   2472:            SKIP_BLANKS;
                   2473: 
                   2474:            prefix = xmlParseQuotedString(ctxt);
                   2475:            SKIP_BLANKS;
                   2476:        } else if ((CUR == '?') && (NXT(1) == '>')) {
                   2477:            garbage = 0;
1.91      daniel   2478:            NEXT;
1.45      daniel   2479:        } else {
                   2480:             /*
                   2481:             * Found garbage when parsing the namespace
                   2482:             */
1.122     daniel   2483:            if (!garbage) {
1.55      daniel   2484:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   2485:                    ctxt->sax->error(ctxt->userData,
                   2486:                                     "xmlParseNamespace found garbage\n");
                   2487:            }
1.123     daniel   2488:            ctxt->errNo = XML_ERR_NS_DECL_ERROR;
1.59      daniel   2489:            ctxt->wellFormed = 0;
1.45      daniel   2490:             NEXT;
                   2491:         }
                   2492:     }
                   2493: 
                   2494:     MOVETO_ENDTAG(CUR_PTR);
                   2495:     NEXT;
                   2496: 
                   2497:     /*
                   2498:      * Register the DTD.
1.72      daniel   2499:     if (href != NULL)
                   2500:        if ((ctxt->sax != NULL) && (ctxt->sax->globalNamespace != NULL))
1.74      daniel   2501:            ctxt->sax->globalNamespace(ctxt->userData, href, prefix);
1.45      daniel   2502:      */
                   2503: 
1.119     daniel   2504:     if (prefix != NULL) xmlFree(prefix);
                   2505:     if (href != NULL) xmlFree(href);
1.45      daniel   2506: }
                   2507: 
1.28      daniel   2508: /************************************************************************
                   2509:  *                                                                     *
                   2510:  *                     The parser itself                               *
                   2511:  *     Relates to http://www.w3.org/TR/REC-xml                         *
                   2512:  *                                                                     *
                   2513:  ************************************************************************/
1.14      veillard 2514: 
1.50      daniel   2515: /**
1.97      daniel   2516:  * xmlScanName:
                   2517:  * @ctxt:  an XML parser context
                   2518:  *
                   2519:  * Trickery: parse an XML name but without consuming the input flow
                   2520:  * Needed for rollback cases.
                   2521:  *
                   2522:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
                   2523:  *                  CombiningChar | Extender
                   2524:  *
                   2525:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
                   2526:  *
                   2527:  * [6] Names ::= Name (S Name)*
                   2528:  *
                   2529:  * Returns the Name parsed or NULL
                   2530:  */
                   2531: 
1.123     daniel   2532: xmlChar *
1.97      daniel   2533: xmlScanName(xmlParserCtxtPtr ctxt) {
1.123     daniel   2534:     xmlChar buf[XML_MAX_NAMELEN];
1.97      daniel   2535:     int len = 0;
                   2536: 
                   2537:     GROW;
                   2538:     if (!IS_LETTER(CUR) && (CUR != '_') &&
                   2539:         (CUR != ':')) {
                   2540:        return(NULL);
                   2541:     }
                   2542: 
                   2543:     while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
                   2544:            (NXT(len) == '.') || (NXT(len) == '-') ||
                   2545:           (NXT(len) == '_') || (NXT(len) == ':') || 
                   2546:           (IS_COMBINING(NXT(len))) ||
                   2547:           (IS_EXTENDER(NXT(len)))) {
                   2548:        buf[len] = NXT(len);
                   2549:        len++;
                   2550:        if (len >= XML_MAX_NAMELEN) {
                   2551:            fprintf(stderr, 
                   2552:               "xmlScanName: reached XML_MAX_NAMELEN limit\n");
                   2553:            while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
                   2554:                   (NXT(len) == '.') || (NXT(len) == '-') ||
                   2555:                   (NXT(len) == '_') || (NXT(len) == ':') || 
                   2556:                   (IS_COMBINING(NXT(len))) ||
                   2557:                   (IS_EXTENDER(NXT(len))))
                   2558:                 len++;
                   2559:            break;
                   2560:        }
                   2561:     }
                   2562:     return(xmlStrndup(buf, len));
                   2563: }
                   2564: 
                   2565: /**
1.50      daniel   2566:  * xmlParseName:
                   2567:  * @ctxt:  an XML parser context
                   2568:  *
                   2569:  * parse an XML name.
1.22      daniel   2570:  *
                   2571:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
                   2572:  *                  CombiningChar | Extender
                   2573:  *
                   2574:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
                   2575:  *
                   2576:  * [6] Names ::= Name (S Name)*
1.68      daniel   2577:  *
                   2578:  * Returns the Name parsed or NULL
1.1       veillard 2579:  */
                   2580: 
1.123     daniel   2581: xmlChar *
1.55      daniel   2582: xmlParseName(xmlParserCtxtPtr ctxt) {
1.123     daniel   2583:     xmlChar buf[XML_MAX_NAMELEN];
1.91      daniel   2584:     int len = 0;
1.123     daniel   2585:     xmlChar cur;
1.1       veillard 2586: 
1.91      daniel   2587:     GROW;
1.97      daniel   2588:     cur = CUR;
                   2589:     if (!IS_LETTER(cur) && (cur != '_') &&
                   2590:         (cur != ':')) {
1.91      daniel   2591:        return(NULL);
                   2592:     }
1.40      daniel   2593: 
1.97      daniel   2594:     while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||
                   2595:            (cur == '.') || (cur == '-') ||
                   2596:           (cur == '_') || (cur == ':') || 
                   2597:           (IS_COMBINING(cur)) ||
                   2598:           (IS_EXTENDER(cur))) {
                   2599:        buf[len++] = cur;
1.40      daniel   2600:        NEXT;
1.97      daniel   2601:        cur = CUR;
1.91      daniel   2602:        if (len >= XML_MAX_NAMELEN) {
                   2603:            fprintf(stderr, 
                   2604:               "xmlParseName: reached XML_MAX_NAMELEN limit\n");
1.97      daniel   2605:            while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||
                   2606:                   (cur == '.') || (cur == '-') ||
                   2607:                   (cur == '_') || (cur == ':') || 
                   2608:                   (IS_COMBINING(cur)) ||
                   2609:                   (IS_EXTENDER(cur))) {
                   2610:                NEXT;
                   2611:                cur = CUR;
                   2612:            }
1.91      daniel   2613:            break;
                   2614:        }
                   2615:     }
                   2616:     return(xmlStrndup(buf, len));
1.22      daniel   2617: }
                   2618: 
1.50      daniel   2619: /**
1.135     daniel   2620:  * xmlParseStringName:
                   2621:  * @ctxt:  an XML parser context
                   2622:  * @str:  a pointer to an index in the string
                   2623:  *
                   2624:  * parse an XML name.
                   2625:  *
                   2626:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
                   2627:  *                  CombiningChar | Extender
                   2628:  *
                   2629:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
                   2630:  *
                   2631:  * [6] Names ::= Name (S Name)*
                   2632:  *
                   2633:  * Returns the Name parsed or NULL. The str pointer 
                   2634:  * is updated to the current location in the string.
                   2635:  */
                   2636: 
                   2637: xmlChar *
                   2638: xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
                   2639:     const xmlChar *ptr;
                   2640:     const xmlChar *start;
                   2641:     xmlChar cur;
                   2642: 
                   2643:     if ((str == NULL) || (*str == NULL)) return(NULL);
                   2644: 
                   2645:     start = ptr = *str;
                   2646:     cur = *ptr;
                   2647:     if (!IS_LETTER(cur) && (cur != '_') &&
                   2648:         (cur != ':')) {
                   2649:        return(NULL);
                   2650:     }
                   2651: 
                   2652:     while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||
                   2653:            (cur == '.') || (cur == '-') ||
                   2654:           (cur == '_') || (cur == ':') || 
                   2655:           (IS_COMBINING(cur)) ||
                   2656:           (IS_EXTENDER(cur))) {
                   2657:        ptr++;
                   2658:        cur = *ptr;
                   2659:     }
                   2660:     *str = ptr;
                   2661:     return(xmlStrndup(start, ptr - start ));
                   2662: }
                   2663: 
                   2664: /**
1.50      daniel   2665:  * xmlParseNmtoken:
                   2666:  * @ctxt:  an XML parser context
                   2667:  * 
                   2668:  * parse an XML Nmtoken.
1.22      daniel   2669:  *
                   2670:  * [7] Nmtoken ::= (NameChar)+
                   2671:  *
                   2672:  * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
1.68      daniel   2673:  *
                   2674:  * Returns the Nmtoken parsed or NULL
1.22      daniel   2675:  */
                   2676: 
1.123     daniel   2677: xmlChar *
1.55      daniel   2678: xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
1.123     daniel   2679:     xmlChar buf[XML_MAX_NAMELEN];
1.91      daniel   2680:     int len = 0;
1.22      daniel   2681: 
1.91      daniel   2682:     GROW;
1.40      daniel   2683:     while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
                   2684:            (CUR == '.') || (CUR == '-') ||
                   2685:           (CUR == '_') || (CUR == ':') || 
                   2686:           (IS_COMBINING(CUR)) ||
1.91      daniel   2687:           (IS_EXTENDER(CUR))) {
                   2688:        buf[len++] = CUR;
1.40      daniel   2689:        NEXT;
1.91      daniel   2690:        if (len >= XML_MAX_NAMELEN) {
                   2691:            fprintf(stderr, 
                   2692:               "xmlParseNmtoken: reached XML_MAX_NAMELEN limit\n");
                   2693:            while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
                   2694:                   (CUR == '.') || (CUR == '-') ||
                   2695:                   (CUR == '_') || (CUR == ':') || 
                   2696:                   (IS_COMBINING(CUR)) ||
                   2697:                   (IS_EXTENDER(CUR)))
                   2698:                 NEXT;
                   2699:            break;
                   2700:        }
                   2701:     }
                   2702:     return(xmlStrndup(buf, len));
1.1       veillard 2703: }
                   2704: 
1.50      daniel   2705: /**
                   2706:  * xmlParseEntityValue:
                   2707:  * @ctxt:  an XML parser context
1.78      daniel   2708:  * @orig:  if non-NULL store a copy of the original entity value
1.50      daniel   2709:  *
                   2710:  * parse a value for ENTITY decl.
1.24      daniel   2711:  *
                   2712:  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
                   2713:  *                    "'" ([^%&'] | PEReference | Reference)* "'"
1.68      daniel   2714:  *
1.78      daniel   2715:  * Returns the EntityValue parsed with reference substitued or NULL
1.24      daniel   2716:  */
                   2717: 
1.123     daniel   2718: xmlChar *
                   2719: xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
1.135     daniel   2720:     xmlChar *buf = NULL;
                   2721:     int len = 0;
1.140     daniel   2722:     int size = XML_PARSER_BUFFER_SIZE;
1.135     daniel   2723:     xmlChar c;
                   2724:     xmlChar stop;
1.123     daniel   2725:     xmlChar *ret = NULL;
1.98      daniel   2726:     xmlParserInputPtr input;
1.24      daniel   2727: 
1.135     daniel   2728:     if (CUR == '"') stop = '"';
                   2729:     else if (CUR == '\'') stop = '\'';
                   2730:     else {
                   2731:        ctxt->errNo = XML_ERR_ENTITY_NOT_STARTED;
                   2732:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   2733:            ctxt->sax->error(ctxt->userData, "EntityValue: \" or ' expected\n");
                   2734:        ctxt->wellFormed = 0;
                   2735:        return(NULL);
                   2736:     }
                   2737:     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   2738:     if (buf == NULL) {
                   2739:        fprintf(stderr, "malloc of %d byte failed\n", size);
                   2740:        return(NULL);
                   2741:     }
1.94      daniel   2742: 
1.135     daniel   2743:     /*
                   2744:      * The content of the entity definition is copied in a buffer.
                   2745:      */
1.94      daniel   2746: 
1.135     daniel   2747:     ctxt->instate = XML_PARSER_ENTITY_VALUE;
                   2748:     input = ctxt->input;
                   2749:     GROW;
                   2750:     NEXT;
                   2751:     c = CUR;
                   2752:     /*
                   2753:      * NOTE: 4.4.5 Included in Literal
                   2754:      * When a parameter entity reference appears in a literal entity
                   2755:      * value, ... a single or double quote character in the replacement
                   2756:      * text is always treated as a normal data character and will not
                   2757:      * terminate the literal. 
                   2758:      * In practice it means we stop the loop only when back at parsing
                   2759:      * the initial entity and the quote is found
                   2760:      */
                   2761:     while (IS_CHAR(c) && ((c != stop) || (ctxt->input != input))) {
                   2762:        if (len + 1 >= size) {
                   2763:            size *= 2;
                   2764:            buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   2765:            if (buf == NULL) {
                   2766:                fprintf(stderr, "realloc of %d byte failed\n", size);
                   2767:                return(NULL);
1.94      daniel   2768:            }
1.79      daniel   2769:        }
1.135     daniel   2770:        buf[len++] = c;
                   2771:        NEXT;
1.98      daniel   2772:        /*
1.135     daniel   2773:         * Pop-up of finished entities.
1.98      daniel   2774:         */
1.135     daniel   2775:        while ((CUR == 0) && (ctxt->inputNr > 1))
                   2776:            xmlPopInput(ctxt);
                   2777:        c = CUR;
                   2778:        if (c == 0) {
1.94      daniel   2779:            GROW;
1.135     daniel   2780:            c = CUR;
1.79      daniel   2781:        }
1.135     daniel   2782:     }
                   2783:     buf[len] = 0;
                   2784: 
                   2785:     /*
                   2786:      * Then PEReference entities are substituted.
                   2787:      */
                   2788:     if (c != stop) {
                   2789:        ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
1.55      daniel   2790:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.135     daniel   2791:            ctxt->sax->error(ctxt->userData, "EntityValue: \" expected\n");
1.59      daniel   2792:        ctxt->wellFormed = 0;
1.135     daniel   2793:     } else {
                   2794:        NEXT;
                   2795:        /*
                   2796:         * NOTE: 4.4.7 Bypassed
                   2797:         * When a general entity reference appears in the EntityValue in
                   2798:         * an entity declaration, it is bypassed and left as is.
                   2799:         * so XML_SUBSTITUTE_REF is not set.
                   2800:         */
                   2801:        ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
                   2802:                                      0, 0, 0);
                   2803:        if (orig != NULL) 
                   2804:            *orig = buf;
                   2805:        else
                   2806:            xmlFree(buf);
1.24      daniel   2807:     }
                   2808:     
                   2809:     return(ret);
                   2810: }
                   2811: 
1.50      daniel   2812: /**
                   2813:  * xmlParseAttValue:
                   2814:  * @ctxt:  an XML parser context
                   2815:  *
                   2816:  * parse a value for an attribute
1.78      daniel   2817:  * Note: the parser won't do substitution of entities here, this
1.113     daniel   2818:  * will be handled later in xmlStringGetNodeList
1.29      daniel   2819:  *
                   2820:  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
                   2821:  *                   "'" ([^<&'] | Reference)* "'"
1.68      daniel   2822:  *
1.129     daniel   2823:  * 3.3.3 Attribute-Value Normalization:
                   2824:  * Before the value of an attribute is passed to the application or
                   2825:  * checked for validity, the XML processor must normalize it as follows: 
                   2826:  * - a character reference is processed by appending the referenced
                   2827:  *   character to the attribute value
                   2828:  * - an entity reference is processed by recursively processing the
                   2829:  *   replacement text of the entity 
                   2830:  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
                   2831:  *   appending #x20 to the normalized value, except that only a single
                   2832:  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
                   2833:  *   parsed entity or the literal entity value of an internal parsed entity 
                   2834:  * - other characters are processed by appending them to the normalized value 
1.130     daniel   2835:  * If the declared value is not CDATA, then the XML processor must further
                   2836:  * process the normalized attribute value by discarding any leading and
                   2837:  * trailing space (#x20) characters, and by replacing sequences of space
                   2838:  * (#x20) characters by a single space (#x20) character.  
                   2839:  * All attributes for which no declaration has been read should be treated
                   2840:  * by a non-validating parser as if declared CDATA.
1.129     daniel   2841:  *
                   2842:  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
1.29      daniel   2843:  */
                   2844: 
1.123     daniel   2845: xmlChar *
1.55      daniel   2846: xmlParseAttValue(xmlParserCtxtPtr ctxt) {
1.129     daniel   2847:     xmlChar limit = 0;
                   2848:     xmlChar *buffer = NULL;
                   2849:     int buffer_size = 0;
                   2850:     xmlChar *out = NULL;
                   2851: 
                   2852:     xmlChar *current = NULL;
                   2853:     xmlEntityPtr ent;
                   2854:     xmlChar cur;
                   2855: 
1.29      daniel   2856: 
1.91      daniel   2857:     SHRINK;
1.40      daniel   2858:     if (CUR == '"') {
1.96      daniel   2859:        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
1.129     daniel   2860:        limit = '"';
1.40      daniel   2861:         NEXT;
                   2862:     } else if (CUR == '\'') {
1.129     daniel   2863:        limit = '\'';
1.96      daniel   2864:        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
1.40      daniel   2865:         NEXT;
1.29      daniel   2866:     } else {
1.123     daniel   2867:        ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_STARTED;
1.55      daniel   2868:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   2869:            ctxt->sax->error(ctxt->userData, "AttValue: \" or ' expected\n");
1.59      daniel   2870:        ctxt->wellFormed = 0;
1.129     daniel   2871:        return(NULL);
1.29      daniel   2872:     }
                   2873:     
1.129     daniel   2874:     /*
                   2875:      * allocate a translation buffer.
                   2876:      */
1.140     daniel   2877:     buffer_size = XML_PARSER_BUFFER_SIZE;
1.129     daniel   2878:     buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
                   2879:     if (buffer == NULL) {
                   2880:        perror("xmlParseAttValue: malloc failed");
                   2881:        return(NULL);
                   2882:     }
                   2883:     out = buffer;
                   2884: 
                   2885:     /*
                   2886:      * Ok loop until we reach one of the ending char or a size limit.
                   2887:      */
                   2888:     cur = CUR;
                   2889:     while ((cur != limit) && (cur != '<')) {
                   2890:        if (cur == 0) break;
                   2891:         if ((cur == '&') && (NXT(1) == '#')) {
                   2892:            int val = xmlParseCharRef(ctxt);
                   2893:            *out++ = val;
                   2894:        } else if (cur == '&') {
                   2895:            ent = xmlParseEntityRef(ctxt);
                   2896:            if ((ent != NULL) && 
                   2897:                (ctxt->replaceEntities != 0)) {
                   2898:                current = ent->content;
                   2899:                while (*current != 0) {
                   2900:                    *out++ = *current++;
                   2901:                    if (out - buffer > buffer_size - 10) {
                   2902:                        int index = out - buffer;
                   2903: 
                   2904:                        growBuffer(buffer);
                   2905:                        out = &buffer[index];
                   2906:                    }
                   2907:                }
                   2908:            } else if (ent != NULL) {
                   2909:                int i = xmlStrlen(ent->name);
                   2910:                const xmlChar *cur = ent->name;
                   2911: 
                   2912:                *out++ = '&';
                   2913:                if (out - buffer > buffer_size - i - 10) {
                   2914:                    int index = out - buffer;
                   2915: 
                   2916:                    growBuffer(buffer);
                   2917:                    out = &buffer[index];
                   2918:                }
                   2919:                for (;i > 0;i--)
                   2920:                    *out++ = *cur++;
                   2921:                *out++ = ';';
                   2922:            }
                   2923:        } else {
                   2924:            /*  invalid for UTF-8 , use COPY(out); !!!!!! */
                   2925:            if ((cur == 0x20) || (cur == 0xD) || (cur == 0xA) || (cur == 0x9)) {
1.130     daniel   2926:                *out++ = 0x20;
                   2927:                if (out - buffer > buffer_size - 10) {
                   2928:                  int index = out - buffer;
                   2929:                  
                   2930:                  growBuffer(buffer);
                   2931:                  out = &buffer[index];
1.129     daniel   2932:                }
                   2933:            } else {
                   2934:                *out++ = cur;
                   2935:                if (out - buffer > buffer_size - 10) {
                   2936:                  int index = out - buffer;
                   2937:                  
                   2938:                  growBuffer(buffer);
                   2939:                  out = &buffer[index];
                   2940:                }
                   2941:            }
                   2942:            NEXT;
                   2943:        }
                   2944:        cur = CUR;
                   2945:     }
                   2946:     *out++ = 0;
                   2947:     if (CUR == '<') {
                   2948:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   2949:            ctxt->sax->error(ctxt->userData,
                   2950:               "Unescaped '<' not allowed in attributes values\n");
                   2951:        ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
                   2952:        ctxt->wellFormed = 0;
                   2953:     } else if (CUR != limit) {
                   2954:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   2955:            ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
                   2956:        ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_FINISHED;
                   2957:        ctxt->wellFormed = 0;
                   2958:     } else
                   2959:        NEXT;
                   2960:     return(buffer);
1.29      daniel   2961: }
                   2962: 
1.50      daniel   2963: /**
                   2964:  * xmlParseSystemLiteral:
                   2965:  * @ctxt:  an XML parser context
                   2966:  * 
                   2967:  * parse an XML Literal
1.21      daniel   2968:  *
1.22      daniel   2969:  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
1.68      daniel   2970:  *
                   2971:  * Returns the SystemLiteral parsed or NULL
1.21      daniel   2972:  */
                   2973: 
1.123     daniel   2974: xmlChar *
1.55      daniel   2975: xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
1.135     daniel   2976:     xmlChar *buf = NULL;
                   2977:     int len = 0;
1.140     daniel   2978:     int size = XML_PARSER_BUFFER_SIZE;
1.135     daniel   2979:     xmlChar cur;
                   2980:     xmlChar stop;
1.21      daniel   2981: 
1.91      daniel   2982:     SHRINK;
1.40      daniel   2983:     if (CUR == '"') {
                   2984:         NEXT;
1.135     daniel   2985:        stop = '"';
1.40      daniel   2986:     } else if (CUR == '\'') {
                   2987:         NEXT;
1.135     daniel   2988:        stop = '\'';
1.21      daniel   2989:     } else {
1.55      daniel   2990:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   2991:            ctxt->sax->error(ctxt->userData,
                   2992:                             "SystemLiteral \" or ' expected\n");
1.123     daniel   2993:        ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
1.59      daniel   2994:        ctxt->wellFormed = 0;
1.135     daniel   2995:        return(NULL);
1.21      daniel   2996:     }
                   2997:     
1.135     daniel   2998:     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   2999:     if (buf == NULL) {
                   3000:        fprintf(stderr, "malloc of %d byte failed\n", size);
                   3001:        return(NULL);
                   3002:     }
                   3003:     cur = CUR;
                   3004:     while ((IS_CHAR(cur)) && (cur != stop)) {
                   3005:        if (len + 1 >= size) {
                   3006:            size *= 2;
                   3007:            buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   3008:            if (buf == NULL) {
                   3009:                fprintf(stderr, "realloc of %d byte failed\n", size);
                   3010:                return(NULL);
                   3011:            }
                   3012:        }
                   3013:        buf[len++] = cur;
                   3014:        NEXT;
                   3015:        cur = CUR;
                   3016:        if (cur == 0) {
                   3017:            GROW;
                   3018:            SHRINK;
                   3019:            cur = CUR;
                   3020:        }
                   3021:     }
                   3022:     buf[len] = 0;
                   3023:     if (!IS_CHAR(cur)) {
                   3024:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   3025:            ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
                   3026:        ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
                   3027:        ctxt->wellFormed = 0;
                   3028:     } else {
                   3029:        NEXT;
                   3030:     }
                   3031:     return(buf);
1.21      daniel   3032: }
                   3033: 
1.50      daniel   3034: /**
                   3035:  * xmlParsePubidLiteral:
                   3036:  * @ctxt:  an XML parser context
1.21      daniel   3037:  *
1.50      daniel   3038:  * parse an XML public literal
1.68      daniel   3039:  *
                   3040:  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
                   3041:  *
                   3042:  * Returns the PubidLiteral parsed or NULL.
1.21      daniel   3043:  */
                   3044: 
1.123     daniel   3045: xmlChar *
1.55      daniel   3046: xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
1.135     daniel   3047:     xmlChar *buf = NULL;
                   3048:     int len = 0;
1.140     daniel   3049:     int size = XML_PARSER_BUFFER_SIZE;
1.135     daniel   3050:     xmlChar cur;
                   3051:     xmlChar stop;
1.125     daniel   3052: 
1.91      daniel   3053:     SHRINK;
1.40      daniel   3054:     if (CUR == '"') {
                   3055:         NEXT;
1.135     daniel   3056:        stop = '"';
1.40      daniel   3057:     } else if (CUR == '\'') {
                   3058:         NEXT;
1.135     daniel   3059:        stop = '\'';
1.21      daniel   3060:     } else {
1.55      daniel   3061:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3062:            ctxt->sax->error(ctxt->userData,
                   3063:                             "SystemLiteral \" or ' expected\n");
1.123     daniel   3064:        ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
1.59      daniel   3065:        ctxt->wellFormed = 0;
1.135     daniel   3066:        return(NULL);
                   3067:     }
                   3068:     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   3069:     if (buf == NULL) {
                   3070:        fprintf(stderr, "malloc of %d byte failed\n", size);
                   3071:        return(NULL);
                   3072:     }
                   3073:     cur = CUR;
                   3074:     while ((IS_PUBIDCHAR(cur)) && (cur != stop)) {
                   3075:        if (len + 1 >= size) {
                   3076:            size *= 2;
                   3077:            buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   3078:            if (buf == NULL) {
                   3079:                fprintf(stderr, "realloc of %d byte failed\n", size);
                   3080:                return(NULL);
                   3081:            }
                   3082:        }
                   3083:        buf[len++] = cur;
                   3084:        NEXT;
                   3085:        cur = CUR;
                   3086:        if (cur == 0) {
                   3087:            GROW;
                   3088:            SHRINK;
                   3089:            cur = CUR;
                   3090:        }
                   3091:     }
                   3092:     buf[len] = 0;
                   3093:     if (cur != stop) {
                   3094:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   3095:            ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
                   3096:        ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
                   3097:        ctxt->wellFormed = 0;
                   3098:     } else {
                   3099:        NEXT;
1.21      daniel   3100:     }
1.135     daniel   3101:     return(buf);
1.21      daniel   3102: }
                   3103: 
1.50      daniel   3104: /**
                   3105:  * xmlParseCharData:
                   3106:  * @ctxt:  an XML parser context
                   3107:  * @cdata:  int indicating whether we are within a CDATA section
                   3108:  *
                   3109:  * parse a CharData section.
                   3110:  * if we are within a CDATA section ']]>' marks an end of section.
1.27      daniel   3111:  *
                   3112:  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
                   3113:  */
                   3114: 
1.55      daniel   3115: void
                   3116: xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
1.140     daniel   3117:     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE];
1.91      daniel   3118:     int nbchar = 0;
1.123     daniel   3119:     xmlChar cur;
1.27      daniel   3120: 
1.91      daniel   3121:     SHRINK;
1.97      daniel   3122:     cur = CUR;
                   3123:     while ((IS_CHAR(cur)) && (cur != '<') &&
                   3124:            (cur != '&')) {
                   3125:        if ((cur == ']') && (NXT(1) == ']') &&
1.59      daniel   3126:            (NXT(2) == '>')) {
                   3127:            if (cdata) break;
                   3128:            else {
                   3129:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.140     daniel   3130:                    ctxt->sax->warning(ctxt->userData,
1.59      daniel   3131:                       "Sequence ']]>' not allowed in content\n");
1.123     daniel   3132:                ctxt->errNo = XML_ERR_MISPLACED_CDATA_END;
1.59      daniel   3133:            }
                   3134:        }
1.91      daniel   3135:        buf[nbchar++] = CUR;
1.140     daniel   3136:        if (nbchar == XML_PARSER_BIG_BUFFER_SIZE) {
1.91      daniel   3137:            /*
                   3138:             * Ok the segment is to be consumed as chars.
                   3139:             */
                   3140:            if (ctxt->sax != NULL) {
                   3141:                if (areBlanks(ctxt, buf, nbchar)) {
                   3142:                    if (ctxt->sax->ignorableWhitespace != NULL)
                   3143:                        ctxt->sax->ignorableWhitespace(ctxt->userData,
                   3144:                                                       buf, nbchar);
                   3145:                } else {
                   3146:                    if (ctxt->sax->characters != NULL)
                   3147:                        ctxt->sax->characters(ctxt->userData, buf, nbchar);
                   3148:                }
                   3149:            }
                   3150:            nbchar = 0;
                   3151:        }
1.40      daniel   3152:         NEXT;
1.97      daniel   3153:        cur = CUR;
1.27      daniel   3154:     }
1.91      daniel   3155:     if (nbchar != 0) {
                   3156:        /*
                   3157:         * Ok the segment is to be consumed as chars.
                   3158:         */
                   3159:        if (ctxt->sax != NULL) {
                   3160:            if (areBlanks(ctxt, buf, nbchar)) {
                   3161:                if (ctxt->sax->ignorableWhitespace != NULL)
                   3162:                    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
                   3163:            } else {
                   3164:                if (ctxt->sax->characters != NULL)
                   3165:                    ctxt->sax->characters(ctxt->userData, buf, nbchar);
                   3166:            }
                   3167:        }
1.45      daniel   3168:     }
1.27      daniel   3169: }
                   3170: 
1.50      daniel   3171: /**
                   3172:  * xmlParseExternalID:
                   3173:  * @ctxt:  an XML parser context
1.123     daniel   3174:  * @publicID:  a xmlChar** receiving PubidLiteral
1.67      daniel   3175:  * @strict: indicate whether we should restrict parsing to only
                   3176:  *          production [75], see NOTE below
1.50      daniel   3177:  *
1.67      daniel   3178:  * Parse an External ID or a Public ID
                   3179:  *
                   3180:  * NOTE: Productions [75] and [83] interract badly since [75] can generate
                   3181:  *       'PUBLIC' S PubidLiteral S SystemLiteral
1.22      daniel   3182:  *
                   3183:  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
                   3184:  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
1.67      daniel   3185:  *
                   3186:  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
                   3187:  *
1.68      daniel   3188:  * Returns the function returns SystemLiteral and in the second
1.67      daniel   3189:  *                case publicID receives PubidLiteral, is strict is off
                   3190:  *                it is possible to return NULL and have publicID set.
1.22      daniel   3191:  */
                   3192: 
1.123     daniel   3193: xmlChar *
                   3194: xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
                   3195:     xmlChar *URI = NULL;
1.22      daniel   3196: 
1.91      daniel   3197:     SHRINK;
1.40      daniel   3198:     if ((CUR == 'S') && (NXT(1) == 'Y') &&
                   3199:          (NXT(2) == 'S') && (NXT(3) == 'T') &&
                   3200:         (NXT(4) == 'E') && (NXT(5) == 'M')) {
                   3201:         SKIP(6);
1.59      daniel   3202:        if (!IS_BLANK(CUR)) {
                   3203:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3204:                ctxt->sax->error(ctxt->userData,
1.59      daniel   3205:                    "Space required after 'SYSTEM'\n");
1.123     daniel   3206:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3207:            ctxt->wellFormed = 0;
                   3208:        }
1.42      daniel   3209:         SKIP_BLANKS;
1.39      daniel   3210:        URI = xmlParseSystemLiteral(ctxt);
1.59      daniel   3211:        if (URI == NULL) {
1.55      daniel   3212:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3213:                ctxt->sax->error(ctxt->userData,
1.39      daniel   3214:                  "xmlParseExternalID: SYSTEM, no URI\n");
1.123     daniel   3215:            ctxt->errNo = XML_ERR_URI_REQUIRED;
1.59      daniel   3216:            ctxt->wellFormed = 0;
                   3217:         }
1.40      daniel   3218:     } else if ((CUR == 'P') && (NXT(1) == 'U') &&
                   3219:               (NXT(2) == 'B') && (NXT(3) == 'L') &&
                   3220:               (NXT(4) == 'I') && (NXT(5) == 'C')) {
                   3221:         SKIP(6);
1.59      daniel   3222:        if (!IS_BLANK(CUR)) {
                   3223:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3224:                ctxt->sax->error(ctxt->userData,
1.59      daniel   3225:                    "Space required after 'PUBLIC'\n");
1.123     daniel   3226:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3227:            ctxt->wellFormed = 0;
                   3228:        }
1.42      daniel   3229:         SKIP_BLANKS;
1.39      daniel   3230:        *publicID = xmlParsePubidLiteral(ctxt);
1.59      daniel   3231:        if (*publicID == NULL) {
1.55      daniel   3232:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3233:                ctxt->sax->error(ctxt->userData, 
1.39      daniel   3234:                  "xmlParseExternalID: PUBLIC, no Public Identifier\n");
1.123     daniel   3235:            ctxt->errNo = XML_ERR_PUBID_REQUIRED;
1.59      daniel   3236:            ctxt->wellFormed = 0;
                   3237:        }
1.67      daniel   3238:        if (strict) {
                   3239:            /*
                   3240:             * We don't handle [83] so "S SystemLiteral" is required.
                   3241:             */
                   3242:            if (!IS_BLANK(CUR)) {
                   3243:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3244:                    ctxt->sax->error(ctxt->userData,
1.67      daniel   3245:                        "Space required after the Public Identifier\n");
1.123     daniel   3246:                ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.67      daniel   3247:                ctxt->wellFormed = 0;
                   3248:            }
                   3249:        } else {
                   3250:            /*
                   3251:             * We handle [83] so we return immediately, if 
                   3252:             * "S SystemLiteral" is not detected. From a purely parsing
                   3253:             * point of view that's a nice mess.
                   3254:             */
1.135     daniel   3255:            const xmlChar *ptr;
                   3256:            GROW;
                   3257: 
                   3258:            ptr = CUR_PTR;
1.67      daniel   3259:            if (!IS_BLANK(*ptr)) return(NULL);
                   3260:            
                   3261:            while (IS_BLANK(*ptr)) ptr++;
                   3262:            if ((*ptr != '\'') || (*ptr != '"')) return(NULL);
1.59      daniel   3263:        }
1.42      daniel   3264:         SKIP_BLANKS;
1.39      daniel   3265:        URI = xmlParseSystemLiteral(ctxt);
1.59      daniel   3266:        if (URI == NULL) {
1.55      daniel   3267:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3268:                ctxt->sax->error(ctxt->userData, 
1.39      daniel   3269:                   "xmlParseExternalID: PUBLIC, no URI\n");
1.123     daniel   3270:            ctxt->errNo = XML_ERR_URI_REQUIRED;
1.59      daniel   3271:            ctxt->wellFormed = 0;
                   3272:         }
1.22      daniel   3273:     }
1.39      daniel   3274:     return(URI);
1.22      daniel   3275: }
                   3276: 
1.50      daniel   3277: /**
                   3278:  * xmlParseComment:
1.69      daniel   3279:  * @ctxt:  an XML parser context
1.50      daniel   3280:  *
1.3       veillard 3281:  * Skip an XML (SGML) comment <!-- .... -->
1.38      daniel   3282:  *  The spec says that "For compatibility, the string "--" (double-hyphen)
                   3283:  *  must not occur within comments. "
1.22      daniel   3284:  *
                   3285:  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
1.3       veillard 3286:  */
1.72      daniel   3287: void
1.114     daniel   3288: xmlParseComment(xmlParserCtxtPtr ctxt) {
1.135     daniel   3289:     xmlChar *buf = NULL;
                   3290:     int len = 0;
1.140     daniel   3291:     int size = XML_PARSER_BUFFER_SIZE;
1.135     daniel   3292:     xmlChar q;
                   3293:     xmlChar r;
                   3294:     xmlChar cur;
1.140     daniel   3295:     xmlParserInputState state;
1.3       veillard 3296: 
                   3297:     /*
1.22      daniel   3298:      * Check that there is a comment right here.
1.3       veillard 3299:      */
1.40      daniel   3300:     if ((CUR != '<') || (NXT(1) != '!') ||
1.72      daniel   3301:         (NXT(2) != '-') || (NXT(3) != '-')) return;
1.3       veillard 3302: 
1.140     daniel   3303:     state = ctxt->instate;
1.97      daniel   3304:     ctxt->instate = XML_PARSER_COMMENT;
1.91      daniel   3305:     SHRINK;
1.40      daniel   3306:     SKIP(4);
1.135     daniel   3307:     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   3308:     if (buf == NULL) {
                   3309:        fprintf(stderr, "malloc of %d byte failed\n", size);
1.140     daniel   3310:        ctxt->instate = state;
1.135     daniel   3311:        return;
                   3312:     }
                   3313:     q = CUR;
1.40      daniel   3314:     NEXT;
1.135     daniel   3315:     r = CUR;
1.40      daniel   3316:     NEXT;
1.135     daniel   3317:     cur = CUR;
                   3318:     while (IS_CHAR(cur) &&
                   3319:            ((cur != '>') ||
                   3320:            (r != '-') || (q != '-'))) {
                   3321:        if ((r == '-') && (q == '-')) {
1.55      daniel   3322:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3323:                ctxt->sax->error(ctxt->userData,
1.38      daniel   3324:               "Comment must not contain '--' (double-hyphen)`\n");
1.123     daniel   3325:            ctxt->errNo = XML_ERR_HYPHEN_IN_COMMENT;
1.59      daniel   3326:            ctxt->wellFormed = 0;
                   3327:        }
1.135     daniel   3328:        if (len + 1 >= size) {
                   3329:            size *= 2;
                   3330:            buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   3331:            if (buf == NULL) {
                   3332:                fprintf(stderr, "realloc of %d byte failed\n", size);
1.140     daniel   3333:                ctxt->instate = state;
1.135     daniel   3334:                return;
                   3335:            }
                   3336:        }
                   3337:        buf[len++] = q;
                   3338:        q = r;
                   3339:        r = cur;
                   3340:         NEXT;
                   3341:        cur = CUR;
                   3342:        if (cur == 0) {
                   3343:            SHRINK;
                   3344:            GROW;
                   3345:            cur = CUR;
                   3346:        }
1.3       veillard 3347:     }
1.135     daniel   3348:     buf[len] = 0;
                   3349:     if (!IS_CHAR(cur)) {
1.55      daniel   3350:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3351:            ctxt->sax->error(ctxt->userData,
1.135     daniel   3352:                             "Comment not terminated \n<!--%.50s\n", buf);
1.123     daniel   3353:        ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
1.59      daniel   3354:        ctxt->wellFormed = 0;
1.3       veillard 3355:     } else {
1.40      daniel   3356:         NEXT;
1.114     daniel   3357:        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL))
1.135     daniel   3358:            ctxt->sax->comment(ctxt->userData, buf);
                   3359:        xmlFree(buf);
1.3       veillard 3360:     }
1.140     daniel   3361:     ctxt->instate = state;
1.3       veillard 3362: }
                   3363: 
1.50      daniel   3364: /**
                   3365:  * xmlParsePITarget:
                   3366:  * @ctxt:  an XML parser context
                   3367:  * 
                   3368:  * parse the name of a PI
1.22      daniel   3369:  *
                   3370:  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
1.68      daniel   3371:  *
                   3372:  * Returns the PITarget name or NULL
1.22      daniel   3373:  */
                   3374: 
1.123     daniel   3375: xmlChar *
1.55      daniel   3376: xmlParsePITarget(xmlParserCtxtPtr ctxt) {
1.123     daniel   3377:     xmlChar *name;
1.22      daniel   3378: 
                   3379:     name = xmlParseName(ctxt);
1.139     daniel   3380:     if ((name != NULL) &&
1.22      daniel   3381:         ((name[0] == 'x') || (name[0] == 'X')) &&
1.31      daniel   3382:         ((name[1] == 'm') || (name[1] == 'M')) &&
                   3383:         ((name[2] == 'l') || (name[2] == 'L'))) {
1.139     daniel   3384:        int i;
                   3385:        for (i = 0;;i++) {
                   3386:            if (xmlW3CPIs[i] == NULL) break;
                   3387:            if (!xmlStrcmp(name, (const xmlChar *)xmlW3CPIs[i]))
                   3388:                return(name);
                   3389:        }
                   3390:        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) {
                   3391:            ctxt->sax->warning(ctxt->userData,
1.122     daniel   3392:                 "xmlParsePItarget: invalid name prefix 'xml'\n");
1.123     daniel   3393:            ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
1.122     daniel   3394:        }
1.22      daniel   3395:     }
                   3396:     return(name);
                   3397: }
                   3398: 
1.50      daniel   3399: /**
                   3400:  * xmlParsePI:
                   3401:  * @ctxt:  an XML parser context
                   3402:  * 
                   3403:  * parse an XML Processing Instruction.
1.22      daniel   3404:  *
                   3405:  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
1.68      daniel   3406:  *
1.69      daniel   3407:  * The processing is transfered to SAX once parsed.
1.3       veillard 3408:  */
                   3409: 
1.55      daniel   3410: void
                   3411: xmlParsePI(xmlParserCtxtPtr ctxt) {
1.135     daniel   3412:     xmlChar *buf = NULL;
                   3413:     int len = 0;
1.140     daniel   3414:     int size = XML_PARSER_BUFFER_SIZE;
1.135     daniel   3415:     xmlChar cur;
1.123     daniel   3416:     xmlChar *target;
1.140     daniel   3417:     xmlParserInputState state;
1.22      daniel   3418: 
1.40      daniel   3419:     if ((CUR == '<') && (NXT(1) == '?')) {
1.140     daniel   3420:        state = ctxt->instate;
                   3421:         ctxt->instate = XML_PARSER_PI;
1.3       veillard 3422:        /*
                   3423:         * this is a Processing Instruction.
                   3424:         */
1.40      daniel   3425:        SKIP(2);
1.91      daniel   3426:        SHRINK;
1.3       veillard 3427: 
                   3428:        /*
1.22      daniel   3429:         * Parse the target name and check for special support like
                   3430:         * namespace.
1.3       veillard 3431:         */
1.22      daniel   3432:         target = xmlParsePITarget(ctxt);
                   3433:        if (target != NULL) {
1.135     daniel   3434:            buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   3435:            if (buf == NULL) {
                   3436:                fprintf(stderr, "malloc of %d byte failed\n", size);
1.140     daniel   3437:                ctxt->instate = state;
1.135     daniel   3438:                return;
                   3439:            }
                   3440:            cur = CUR;
                   3441:            if (!IS_BLANK(cur)) {
1.114     daniel   3442:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   3443:                    ctxt->sax->error(ctxt->userData,
                   3444:                      "xmlParsePI: PI %s space expected\n", target);
1.123     daniel   3445:                ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.114     daniel   3446:                ctxt->wellFormed = 0;
                   3447:            }
                   3448:             SKIP_BLANKS;
1.135     daniel   3449:            cur = CUR;
                   3450:            while (IS_CHAR(cur) &&
                   3451:                   ((cur != '?') || (NXT(1) != '>'))) {
                   3452:                if (len + 1 >= size) {
                   3453:                    size *= 2;
                   3454:                    buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   3455:                    if (buf == NULL) {
                   3456:                        fprintf(stderr, "realloc of %d byte failed\n", size);
1.140     daniel   3457:                        ctxt->instate = state;
1.135     daniel   3458:                        return;
                   3459:                    }
                   3460:                }
                   3461:                buf[len++] = cur;
1.72      daniel   3462:                NEXT;
1.135     daniel   3463:                cur = CUR;
                   3464:                if (cur == 0) {
                   3465:                    SHRINK;
                   3466:                    GROW;
                   3467:                    cur = CUR;
                   3468:                }
                   3469:            }
                   3470:            buf[len] = 0;
                   3471:            if (!IS_CHAR(cur)) {
1.72      daniel   3472:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3473:                    ctxt->sax->error(ctxt->userData,
1.72      daniel   3474:                      "xmlParsePI: PI %s never end ...\n", target);
1.123     daniel   3475:                ctxt->errNo = XML_ERR_PI_NOT_FINISHED;
1.72      daniel   3476:                ctxt->wellFormed = 0;
1.22      daniel   3477:            } else {
1.72      daniel   3478:                SKIP(2);
1.44      daniel   3479: 
1.72      daniel   3480:                /*
                   3481:                 * SAX: PI detected.
                   3482:                 */
                   3483:                if ((ctxt->sax) &&
                   3484:                    (ctxt->sax->processingInstruction != NULL))
1.99      daniel   3485:                    ctxt->sax->processingInstruction(ctxt->userData,
1.135     daniel   3486:                                                     target, buf);
1.22      daniel   3487:            }
1.135     daniel   3488:            xmlFree(buf);
1.119     daniel   3489:            xmlFree(target);
1.3       veillard 3490:        } else {
1.55      daniel   3491:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.99      daniel   3492:                ctxt->sax->error(ctxt->userData,
                   3493:                       "xmlParsePI : no target name\n");
1.123     daniel   3494:            ctxt->errNo = XML_ERR_PI_NOT_STARTED;
1.59      daniel   3495:            ctxt->wellFormed = 0;
1.22      daniel   3496:        }
1.140     daniel   3497:        ctxt->instate = state;
1.22      daniel   3498:     }
                   3499: }
                   3500: 
1.50      daniel   3501: /**
                   3502:  * xmlParseNotationDecl:
                   3503:  * @ctxt:  an XML parser context
                   3504:  *
                   3505:  * parse a notation declaration
1.22      daniel   3506:  *
                   3507:  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
                   3508:  *
                   3509:  * Hence there is actually 3 choices:
                   3510:  *     'PUBLIC' S PubidLiteral
                   3511:  *     'PUBLIC' S PubidLiteral S SystemLiteral
                   3512:  * and 'SYSTEM' S SystemLiteral
1.50      daniel   3513:  *
1.67      daniel   3514:  * See the NOTE on xmlParseExternalID().
1.22      daniel   3515:  */
                   3516: 
1.55      daniel   3517: void
                   3518: xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   3519:     xmlChar *name;
                   3520:     xmlChar *Pubid;
                   3521:     xmlChar *Systemid;
1.22      daniel   3522:     
1.40      daniel   3523:     if ((CUR == '<') && (NXT(1) == '!') &&
                   3524:         (NXT(2) == 'N') && (NXT(3) == 'O') &&
                   3525:         (NXT(4) == 'T') && (NXT(5) == 'A') &&
                   3526:         (NXT(6) == 'T') && (NXT(7) == 'I') &&
1.67      daniel   3527:         (NXT(8) == 'O') && (NXT(9) == 'N')) {
1.91      daniel   3528:        SHRINK;
1.40      daniel   3529:        SKIP(10);
1.67      daniel   3530:        if (!IS_BLANK(CUR)) {
                   3531:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3532:                ctxt->sax->error(ctxt->userData,
                   3533:                                 "Space required after '<!NOTATION'\n");
1.123     daniel   3534:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.67      daniel   3535:            ctxt->wellFormed = 0;
                   3536:            return;
                   3537:        }
                   3538:        SKIP_BLANKS;
1.22      daniel   3539: 
                   3540:         name = xmlParseName(ctxt);
                   3541:        if (name == NULL) {
1.55      daniel   3542:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3543:                ctxt->sax->error(ctxt->userData,
                   3544:                                 "NOTATION: Name expected here\n");
1.123     daniel   3545:            ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
1.67      daniel   3546:            ctxt->wellFormed = 0;
                   3547:            return;
                   3548:        }
                   3549:        if (!IS_BLANK(CUR)) {
                   3550:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3551:                ctxt->sax->error(ctxt->userData, 
1.67      daniel   3552:                     "Space required after the NOTATION name'\n");
1.123     daniel   3553:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3554:            ctxt->wellFormed = 0;
1.22      daniel   3555:            return;
                   3556:        }
1.42      daniel   3557:        SKIP_BLANKS;
1.67      daniel   3558: 
1.22      daniel   3559:        /*
1.67      daniel   3560:         * Parse the IDs.
1.22      daniel   3561:         */
1.67      daniel   3562:        Systemid = xmlParseExternalID(ctxt, &Pubid, 1);
                   3563:        SKIP_BLANKS;
                   3564: 
                   3565:        if (CUR == '>') {
1.40      daniel   3566:            NEXT;
1.72      daniel   3567:            if ((ctxt->sax != NULL) && (ctxt->sax->notationDecl != NULL))
1.74      daniel   3568:                ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
1.67      daniel   3569:        } else {
                   3570:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3571:                ctxt->sax->error(ctxt->userData,
1.67      daniel   3572:                       "'>' required to close NOTATION declaration\n");
1.123     daniel   3573:            ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
1.67      daniel   3574:            ctxt->wellFormed = 0;
                   3575:        }
1.119     daniel   3576:        xmlFree(name);
                   3577:        if (Systemid != NULL) xmlFree(Systemid);
                   3578:        if (Pubid != NULL) xmlFree(Pubid);
1.22      daniel   3579:     }
                   3580: }
                   3581: 
1.50      daniel   3582: /**
                   3583:  * xmlParseEntityDecl:
                   3584:  * @ctxt:  an XML parser context
                   3585:  *
                   3586:  * parse <!ENTITY declarations
1.22      daniel   3587:  *
                   3588:  * [70] EntityDecl ::= GEDecl | PEDecl
                   3589:  *
                   3590:  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
                   3591:  *
                   3592:  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
                   3593:  *
                   3594:  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
                   3595:  *
                   3596:  * [74] PEDef ::= EntityValue | ExternalID
1.24      daniel   3597:  *
                   3598:  * [76] NDataDecl ::= S 'NDATA' S Name
1.99      daniel   3599:  *
                   3600:  * [ VC: Notation Declared ]
1.116     daniel   3601:  * The Name must match the declared name of a notation.
1.22      daniel   3602:  */
                   3603: 
1.55      daniel   3604: void
                   3605: xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   3606:     xmlChar *name = NULL;
                   3607:     xmlChar *value = NULL;
                   3608:     xmlChar *URI = NULL, *literal = NULL;
                   3609:     xmlChar *ndata = NULL;
1.39      daniel   3610:     int isParameter = 0;
1.123     daniel   3611:     xmlChar *orig = NULL;
1.22      daniel   3612:     
1.94      daniel   3613:     GROW;
1.40      daniel   3614:     if ((CUR == '<') && (NXT(1) == '!') &&
                   3615:         (NXT(2) == 'E') && (NXT(3) == 'N') &&
                   3616:         (NXT(4) == 'T') && (NXT(5) == 'I') &&
1.59      daniel   3617:         (NXT(6) == 'T') && (NXT(7) == 'Y')) {
1.96      daniel   3618:        ctxt->instate = XML_PARSER_ENTITY_DECL;
1.91      daniel   3619:        SHRINK;
1.40      daniel   3620:        SKIP(8);
1.59      daniel   3621:        if (!IS_BLANK(CUR)) {
                   3622:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3623:                ctxt->sax->error(ctxt->userData,
                   3624:                                 "Space required after '<!ENTITY'\n");
1.123     daniel   3625:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3626:            ctxt->wellFormed = 0;
                   3627:        }
                   3628:        SKIP_BLANKS;
1.40      daniel   3629: 
                   3630:        if (CUR == '%') {
                   3631:            NEXT;
1.59      daniel   3632:            if (!IS_BLANK(CUR)) {
                   3633:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3634:                    ctxt->sax->error(ctxt->userData,
                   3635:                                     "Space required after '%'\n");
1.123     daniel   3636:                ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3637:                ctxt->wellFormed = 0;
                   3638:            }
1.42      daniel   3639:            SKIP_BLANKS;
1.39      daniel   3640:            isParameter = 1;
1.22      daniel   3641:        }
                   3642: 
                   3643:         name = xmlParseName(ctxt);
1.24      daniel   3644:        if (name == NULL) {
1.55      daniel   3645:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3646:                ctxt->sax->error(ctxt->userData, "xmlParseEntityDecl: no name\n");
1.123     daniel   3647:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.59      daniel   3648:            ctxt->wellFormed = 0;
1.24      daniel   3649:             return;
                   3650:        }
1.59      daniel   3651:        if (!IS_BLANK(CUR)) {
                   3652:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3653:                ctxt->sax->error(ctxt->userData,
1.59      daniel   3654:                     "Space required after the entity name\n");
1.123     daniel   3655:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3656:            ctxt->wellFormed = 0;
                   3657:        }
1.42      daniel   3658:         SKIP_BLANKS;
1.24      daniel   3659: 
1.22      daniel   3660:        /*
1.68      daniel   3661:         * handle the various case of definitions...
1.22      daniel   3662:         */
1.39      daniel   3663:        if (isParameter) {
1.40      daniel   3664:            if ((CUR == '"') || (CUR == '\''))
1.78      daniel   3665:                value = xmlParseEntityValue(ctxt, &orig);
1.39      daniel   3666:                if (value) {
1.72      daniel   3667:                    if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
1.74      daniel   3668:                        ctxt->sax->entityDecl(ctxt->userData, name,
1.39      daniel   3669:                                    XML_INTERNAL_PARAMETER_ENTITY,
                   3670:                                    NULL, NULL, value);
                   3671:                }
1.24      daniel   3672:            else {
1.67      daniel   3673:                URI = xmlParseExternalID(ctxt, &literal, 1);
1.39      daniel   3674:                if (URI) {
1.72      daniel   3675:                    if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
1.74      daniel   3676:                        ctxt->sax->entityDecl(ctxt->userData, name,
1.39      daniel   3677:                                    XML_EXTERNAL_PARAMETER_ENTITY,
                   3678:                                    literal, URI, NULL);
                   3679:                }
1.24      daniel   3680:            }
                   3681:        } else {
1.40      daniel   3682:            if ((CUR == '"') || (CUR == '\'')) {
1.78      daniel   3683:                value = xmlParseEntityValue(ctxt, &orig);
1.72      daniel   3684:                if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
1.74      daniel   3685:                    ctxt->sax->entityDecl(ctxt->userData, name,
1.39      daniel   3686:                                XML_INTERNAL_GENERAL_ENTITY,
                   3687:                                NULL, NULL, value);
                   3688:            } else {
1.67      daniel   3689:                URI = xmlParseExternalID(ctxt, &literal, 1);
1.59      daniel   3690:                if ((CUR != '>') && (!IS_BLANK(CUR))) {
                   3691:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3692:                        ctxt->sax->error(ctxt->userData,
1.59      daniel   3693:                            "Space required before 'NDATA'\n");
1.123     daniel   3694:                    ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3695:                    ctxt->wellFormed = 0;
                   3696:                }
1.42      daniel   3697:                SKIP_BLANKS;
1.40      daniel   3698:                if ((CUR == 'N') && (NXT(1) == 'D') &&
                   3699:                    (NXT(2) == 'A') && (NXT(3) == 'T') &&
                   3700:                    (NXT(4) == 'A')) {
                   3701:                    SKIP(5);
1.59      daniel   3702:                    if (!IS_BLANK(CUR)) {
                   3703:                        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3704:                            ctxt->sax->error(ctxt->userData,
1.59      daniel   3705:                                "Space required after 'NDATA'\n");
1.123     daniel   3706:                        ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3707:                        ctxt->wellFormed = 0;
                   3708:                    }
1.42      daniel   3709:                    SKIP_BLANKS;
1.24      daniel   3710:                    ndata = xmlParseName(ctxt);
1.116     daniel   3711:                    if ((ctxt->sax != NULL) &&
                   3712:                        (ctxt->sax->unparsedEntityDecl != NULL))
                   3713:                        ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
1.39      daniel   3714:                                    literal, URI, ndata);
                   3715:                } else {
1.72      daniel   3716:                    if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
1.74      daniel   3717:                        ctxt->sax->entityDecl(ctxt->userData, name,
1.39      daniel   3718:                                    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
                   3719:                                    literal, URI, NULL);
1.24      daniel   3720:                }
                   3721:            }
                   3722:        }
1.42      daniel   3723:        SKIP_BLANKS;
1.40      daniel   3724:        if (CUR != '>') {
1.55      daniel   3725:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3726:                ctxt->sax->error(ctxt->userData, 
1.31      daniel   3727:                    "xmlParseEntityDecl: entity %s not terminated\n", name);
1.123     daniel   3728:            ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
1.59      daniel   3729:            ctxt->wellFormed = 0;
1.24      daniel   3730:        } else
1.40      daniel   3731:            NEXT;
1.78      daniel   3732:        if (orig != NULL) {
                   3733:            /*
1.98      daniel   3734:             * Ugly mechanism to save the raw entity value.
1.78      daniel   3735:             */
                   3736:            xmlEntityPtr cur = NULL;
                   3737: 
1.98      daniel   3738:            if (isParameter) {
                   3739:                if ((ctxt->sax != NULL) &&
                   3740:                    (ctxt->sax->getParameterEntity != NULL))
1.120     daniel   3741:                    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
1.98      daniel   3742:            } else {
                   3743:                if ((ctxt->sax != NULL) &&
                   3744:                    (ctxt->sax->getEntity != NULL))
1.120     daniel   3745:                    cur = ctxt->sax->getEntity(ctxt->userData, name);
1.98      daniel   3746:            }
                   3747:             if (cur != NULL) {
                   3748:                if (cur->orig != NULL)
1.119     daniel   3749:                    xmlFree(orig);
1.98      daniel   3750:                else
                   3751:                    cur->orig = orig;
                   3752:            } else
1.119     daniel   3753:                xmlFree(orig);
1.78      daniel   3754:        }
1.119     daniel   3755:        if (name != NULL) xmlFree(name);
                   3756:        if (value != NULL) xmlFree(value);
                   3757:        if (URI != NULL) xmlFree(URI);
                   3758:        if (literal != NULL) xmlFree(literal);
                   3759:        if (ndata != NULL) xmlFree(ndata);
1.22      daniel   3760:     }
                   3761: }
                   3762: 
1.50      daniel   3763: /**
1.59      daniel   3764:  * xmlParseDefaultDecl:
                   3765:  * @ctxt:  an XML parser context
                   3766:  * @value:  Receive a possible fixed default value for the attribute
                   3767:  *
                   3768:  * Parse an attribute default declaration
                   3769:  *
                   3770:  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
                   3771:  *
1.99      daniel   3772:  * [ VC: Required Attribute ]
1.117     daniel   3773:  * if the default declaration is the keyword #REQUIRED, then the
                   3774:  * attribute must be specified for all elements of the type in the
                   3775:  * attribute-list declaration.
1.99      daniel   3776:  *
                   3777:  * [ VC: Attribute Default Legal ]
1.102     daniel   3778:  * The declared default value must meet the lexical constraints of
                   3779:  * the declared attribute type c.f. xmlValidateAttributeDecl()
1.99      daniel   3780:  *
                   3781:  * [ VC: Fixed Attribute Default ]
1.117     daniel   3782:  * if an attribute has a default value declared with the #FIXED
                   3783:  * keyword, instances of that attribute must match the default value. 
1.99      daniel   3784:  *
                   3785:  * [ WFC: No < in Attribute Values ]
                   3786:  * handled in xmlParseAttValue()
                   3787:  *
1.59      daniel   3788:  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
                   3789:  *          or XML_ATTRIBUTE_FIXED. 
                   3790:  */
                   3791: 
                   3792: int
1.123     daniel   3793: xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
1.59      daniel   3794:     int val;
1.123     daniel   3795:     xmlChar *ret;
1.59      daniel   3796: 
                   3797:     *value = NULL;
                   3798:     if ((CUR == '#') && (NXT(1) == 'R') &&
                   3799:         (NXT(2) == 'E') && (NXT(3) == 'Q') &&
                   3800:         (NXT(4) == 'U') && (NXT(5) == 'I') &&
                   3801:         (NXT(6) == 'R') && (NXT(7) == 'E') &&
                   3802:         (NXT(8) == 'D')) {
                   3803:        SKIP(9);
                   3804:        return(XML_ATTRIBUTE_REQUIRED);
                   3805:     }
                   3806:     if ((CUR == '#') && (NXT(1) == 'I') &&
                   3807:         (NXT(2) == 'M') && (NXT(3) == 'P') &&
                   3808:         (NXT(4) == 'L') && (NXT(5) == 'I') &&
                   3809:         (NXT(6) == 'E') && (NXT(7) == 'D')) {
                   3810:        SKIP(8);
                   3811:        return(XML_ATTRIBUTE_IMPLIED);
                   3812:     }
                   3813:     val = XML_ATTRIBUTE_NONE;
                   3814:     if ((CUR == '#') && (NXT(1) == 'F') &&
                   3815:         (NXT(2) == 'I') && (NXT(3) == 'X') &&
                   3816:         (NXT(4) == 'E') && (NXT(5) == 'D')) {
                   3817:        SKIP(6);
                   3818:        val = XML_ATTRIBUTE_FIXED;
                   3819:        if (!IS_BLANK(CUR)) {
                   3820:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3821:                ctxt->sax->error(ctxt->userData,
                   3822:                                 "Space required after '#FIXED'\n");
1.123     daniel   3823:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   3824:            ctxt->wellFormed = 0;
                   3825:        }
                   3826:        SKIP_BLANKS;
                   3827:     }
                   3828:     ret = xmlParseAttValue(ctxt);
1.96      daniel   3829:     ctxt->instate = XML_PARSER_DTD;
1.59      daniel   3830:     if (ret == NULL) {
                   3831:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3832:            ctxt->sax->error(ctxt->userData,
1.59      daniel   3833:               "Attribute default value declaration error\n");
                   3834:        ctxt->wellFormed = 0;
                   3835:     } else
                   3836:         *value = ret;
                   3837:     return(val);
                   3838: }
                   3839: 
                   3840: /**
1.66      daniel   3841:  * xmlParseNotationType:
                   3842:  * @ctxt:  an XML parser context
                   3843:  *
                   3844:  * parse an Notation attribute type.
                   3845:  *
1.99      daniel   3846:  * Note: the leading 'NOTATION' S part has already being parsed...
                   3847:  *
1.66      daniel   3848:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
                   3849:  *
1.99      daniel   3850:  * [ VC: Notation Attributes ]
1.117     daniel   3851:  * Values of this type must match one of the notation names included
1.99      daniel   3852:  * in the declaration; all notation names in the declaration must be declared. 
1.66      daniel   3853:  *
                   3854:  * Returns: the notation attribute tree built while parsing
                   3855:  */
                   3856: 
                   3857: xmlEnumerationPtr
                   3858: xmlParseNotationType(xmlParserCtxtPtr ctxt) {
1.123     daniel   3859:     xmlChar *name;
1.66      daniel   3860:     xmlEnumerationPtr ret = NULL, last = NULL, cur;
                   3861: 
                   3862:     if (CUR != '(') {
                   3863:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3864:            ctxt->sax->error(ctxt->userData,
                   3865:                             "'(' required to start 'NOTATION'\n");
1.123     daniel   3866:        ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
1.66      daniel   3867:        ctxt->wellFormed = 0;
                   3868:        return(NULL);
                   3869:     }
1.91      daniel   3870:     SHRINK;
1.66      daniel   3871:     do {
                   3872:         NEXT;
                   3873:        SKIP_BLANKS;
                   3874:         name = xmlParseName(ctxt);
                   3875:        if (name == NULL) {
                   3876:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3877:                ctxt->sax->error(ctxt->userData, 
1.66      daniel   3878:                                 "Name expected in NOTATION declaration\n");
1.123     daniel   3879:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.66      daniel   3880:            ctxt->wellFormed = 0;
                   3881:            return(ret);
                   3882:        }
                   3883:        cur = xmlCreateEnumeration(name);
1.119     daniel   3884:        xmlFree(name);
1.66      daniel   3885:        if (cur == NULL) return(ret);
                   3886:        if (last == NULL) ret = last = cur;
                   3887:        else {
                   3888:            last->next = cur;
                   3889:            last = cur;
                   3890:        }
                   3891:        SKIP_BLANKS;
                   3892:     } while (CUR == '|');
                   3893:     if (CUR != ')') {
                   3894:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3895:            ctxt->sax->error(ctxt->userData,
1.66      daniel   3896:                             "')' required to finish NOTATION declaration\n");
1.123     daniel   3897:        ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
1.66      daniel   3898:        ctxt->wellFormed = 0;
                   3899:        return(ret);
                   3900:     }
                   3901:     NEXT;
                   3902:     return(ret);
                   3903: }
                   3904: 
                   3905: /**
                   3906:  * xmlParseEnumerationType:
                   3907:  * @ctxt:  an XML parser context
                   3908:  *
                   3909:  * parse an Enumeration attribute type.
                   3910:  *
                   3911:  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
                   3912:  *
1.99      daniel   3913:  * [ VC: Enumeration ]
1.117     daniel   3914:  * Values of this type must match one of the Nmtoken tokens in
1.99      daniel   3915:  * the declaration
                   3916:  *
1.66      daniel   3917:  * Returns: the enumeration attribute tree built while parsing
                   3918:  */
                   3919: 
                   3920: xmlEnumerationPtr
                   3921: xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
1.123     daniel   3922:     xmlChar *name;
1.66      daniel   3923:     xmlEnumerationPtr ret = NULL, last = NULL, cur;
                   3924: 
                   3925:     if (CUR != '(') {
                   3926:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3927:            ctxt->sax->error(ctxt->userData,
1.66      daniel   3928:                             "'(' required to start ATTLIST enumeration\n");
1.123     daniel   3929:        ctxt->errNo = XML_ERR_ATTLIST_NOT_STARTED;
1.66      daniel   3930:        ctxt->wellFormed = 0;
                   3931:        return(NULL);
                   3932:     }
1.91      daniel   3933:     SHRINK;
1.66      daniel   3934:     do {
                   3935:         NEXT;
                   3936:        SKIP_BLANKS;
                   3937:         name = xmlParseNmtoken(ctxt);
                   3938:        if (name == NULL) {
                   3939:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3940:                ctxt->sax->error(ctxt->userData, 
1.66      daniel   3941:                                 "NmToken expected in ATTLIST enumeration\n");
1.123     daniel   3942:            ctxt->errNo = XML_ERR_NMTOKEN_REQUIRED;
1.66      daniel   3943:            ctxt->wellFormed = 0;
                   3944:            return(ret);
                   3945:        }
                   3946:        cur = xmlCreateEnumeration(name);
1.119     daniel   3947:        xmlFree(name);
1.66      daniel   3948:        if (cur == NULL) return(ret);
                   3949:        if (last == NULL) ret = last = cur;
                   3950:        else {
                   3951:            last->next = cur;
                   3952:            last = cur;
                   3953:        }
                   3954:        SKIP_BLANKS;
                   3955:     } while (CUR == '|');
                   3956:     if (CUR != ')') {
                   3957:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   3958:            ctxt->sax->error(ctxt->userData,
1.66      daniel   3959:                             "')' required to finish ATTLIST enumeration\n");
1.123     daniel   3960:        ctxt->errNo = XML_ERR_ATTLIST_NOT_FINISHED;
1.66      daniel   3961:        ctxt->wellFormed = 0;
                   3962:        return(ret);
                   3963:     }
                   3964:     NEXT;
                   3965:     return(ret);
                   3966: }
                   3967: 
                   3968: /**
1.50      daniel   3969:  * xmlParseEnumeratedType:
                   3970:  * @ctxt:  an XML parser context
1.66      daniel   3971:  * @tree:  the enumeration tree built while parsing
1.50      daniel   3972:  *
1.66      daniel   3973:  * parse an Enumerated attribute type.
1.22      daniel   3974:  *
                   3975:  * [57] EnumeratedType ::= NotationType | Enumeration
                   3976:  *
                   3977:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
                   3978:  *
1.50      daniel   3979:  *
1.66      daniel   3980:  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
1.22      daniel   3981:  */
                   3982: 
1.66      daniel   3983: int
                   3984: xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
                   3985:     if ((CUR == 'N') && (NXT(1) == 'O') &&
                   3986:         (NXT(2) == 'T') && (NXT(3) == 'A') &&
                   3987:         (NXT(4) == 'T') && (NXT(5) == 'I') &&
                   3988:        (NXT(6) == 'O') && (NXT(7) == 'N')) {
                   3989:        SKIP(8);
                   3990:        if (!IS_BLANK(CUR)) {
                   3991:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   3992:                ctxt->sax->error(ctxt->userData,
                   3993:                                 "Space required after 'NOTATION'\n");
1.123     daniel   3994:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.66      daniel   3995:            ctxt->wellFormed = 0;
                   3996:            return(0);
                   3997:        }
                   3998:         SKIP_BLANKS;
                   3999:        *tree = xmlParseNotationType(ctxt);
                   4000:        if (*tree == NULL) return(0);
                   4001:        return(XML_ATTRIBUTE_NOTATION);
                   4002:     }
                   4003:     *tree = xmlParseEnumerationType(ctxt);
                   4004:     if (*tree == NULL) return(0);
                   4005:     return(XML_ATTRIBUTE_ENUMERATION);
1.22      daniel   4006: }
                   4007: 
1.50      daniel   4008: /**
                   4009:  * xmlParseAttributeType:
                   4010:  * @ctxt:  an XML parser context
1.66      daniel   4011:  * @tree:  the enumeration tree built while parsing
1.50      daniel   4012:  *
1.59      daniel   4013:  * parse the Attribute list def for an element
1.22      daniel   4014:  *
                   4015:  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
                   4016:  *
                   4017:  * [55] StringType ::= 'CDATA'
                   4018:  *
                   4019:  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
                   4020:  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
1.50      daniel   4021:  *
1.102     daniel   4022:  * Validity constraints for attribute values syntax are checked in
                   4023:  * xmlValidateAttributeValue()
                   4024:  *
1.99      daniel   4025:  * [ VC: ID ]
1.117     daniel   4026:  * Values of type ID must match the Name production. A name must not
1.99      daniel   4027:  * appear more than once in an XML document as a value of this type;
                   4028:  * i.e., ID values must uniquely identify the elements which bear them.
                   4029:  *
                   4030:  * [ VC: One ID per Element Type ]
1.117     daniel   4031:  * No element type may have more than one ID attribute specified.
1.99      daniel   4032:  *
                   4033:  * [ VC: ID Attribute Default ]
1.117     daniel   4034:  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
1.99      daniel   4035:  *
                   4036:  * [ VC: IDREF ]
1.102     daniel   4037:  * Values of type IDREF must match the Name production, and values
1.140     daniel   4038:  * of type IDREFS must match Names; each IDREF Name must match the value
1.117     daniel   4039:  * of an ID attribute on some element in the XML document; i.e. IDREF
1.99      daniel   4040:  * values must match the value of some ID attribute.
                   4041:  *
                   4042:  * [ VC: Entity Name ]
1.102     daniel   4043:  * Values of type ENTITY must match the Name production, values
1.140     daniel   4044:  * of type ENTITIES must match Names; each Entity Name must match the
1.117     daniel   4045:  * name of an unparsed entity declared in the DTD.  
1.99      daniel   4046:  *
                   4047:  * [ VC: Name Token ]
1.102     daniel   4048:  * Values of type NMTOKEN must match the Nmtoken production; values
1.99      daniel   4049:  * of type NMTOKENS must match Nmtokens. 
                   4050:  *
1.69      daniel   4051:  * Returns the attribute type
1.22      daniel   4052:  */
1.59      daniel   4053: int 
1.66      daniel   4054: xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
1.91      daniel   4055:     SHRINK;
1.40      daniel   4056:     if ((CUR == 'C') && (NXT(1) == 'D') &&
                   4057:         (NXT(2) == 'A') && (NXT(3) == 'T') &&
                   4058:         (NXT(4) == 'A')) {
                   4059:        SKIP(5);
1.66      daniel   4060:        return(XML_ATTRIBUTE_CDATA);
1.40      daniel   4061:      } else if ((CUR == 'I') && (NXT(1) == 'D') &&
                   4062:         (NXT(2) == 'R') && (NXT(3) == 'E') &&
1.97      daniel   4063:         (NXT(4) == 'F') && (NXT(5) == 'S')) {
                   4064:        SKIP(6);
                   4065:        return(XML_ATTRIBUTE_IDREFS);
                   4066:      } else if ((CUR == 'I') && (NXT(1) == 'D') &&
                   4067:         (NXT(2) == 'R') && (NXT(3) == 'E') &&
1.40      daniel   4068:         (NXT(4) == 'F')) {
                   4069:        SKIP(5);
1.59      daniel   4070:        return(XML_ATTRIBUTE_IDREF);
1.66      daniel   4071:      } else if ((CUR == 'I') && (NXT(1) == 'D')) {
                   4072:         SKIP(2);
                   4073:        return(XML_ATTRIBUTE_ID);
1.40      daniel   4074:      } else if ((CUR == 'E') && (NXT(1) == 'N') &&
                   4075:         (NXT(2) == 'T') && (NXT(3) == 'I') &&
                   4076:         (NXT(4) == 'T') && (NXT(5) == 'Y')) {
                   4077:        SKIP(6);
1.59      daniel   4078:        return(XML_ATTRIBUTE_ENTITY);
1.40      daniel   4079:      } else if ((CUR == 'E') && (NXT(1) == 'N') &&
                   4080:         (NXT(2) == 'T') && (NXT(3) == 'I') &&
                   4081:         (NXT(4) == 'T') && (NXT(5) == 'I') &&
                   4082:         (NXT(6) == 'E') && (NXT(7) == 'S')) {
                   4083:        SKIP(8);
1.59      daniel   4084:        return(XML_ATTRIBUTE_ENTITIES);
1.40      daniel   4085:      } else if ((CUR == 'N') && (NXT(1) == 'M') &&
                   4086:         (NXT(2) == 'T') && (NXT(3) == 'O') &&
                   4087:         (NXT(4) == 'K') && (NXT(5) == 'E') &&
1.66      daniel   4088:         (NXT(6) == 'N') && (NXT(7) == 'S')) {
                   4089:        SKIP(8);
                   4090:        return(XML_ATTRIBUTE_NMTOKENS);
                   4091:      } else if ((CUR == 'N') && (NXT(1) == 'M') &&
                   4092:         (NXT(2) == 'T') && (NXT(3) == 'O') &&
                   4093:         (NXT(4) == 'K') && (NXT(5) == 'E') &&
1.40      daniel   4094:         (NXT(6) == 'N')) {
                   4095:        SKIP(7);
1.59      daniel   4096:        return(XML_ATTRIBUTE_NMTOKEN);
1.22      daniel   4097:      }
1.66      daniel   4098:      return(xmlParseEnumeratedType(ctxt, tree));
1.22      daniel   4099: }
                   4100: 
1.50      daniel   4101: /**
                   4102:  * xmlParseAttributeListDecl:
                   4103:  * @ctxt:  an XML parser context
                   4104:  *
                   4105:  * : parse the Attribute list def for an element
1.22      daniel   4106:  *
                   4107:  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
                   4108:  *
                   4109:  * [53] AttDef ::= S Name S AttType S DefaultDecl
1.50      daniel   4110:  *
1.22      daniel   4111:  */
1.55      daniel   4112: void
                   4113: xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   4114:     xmlChar *elemName;
                   4115:     xmlChar *attrName;
1.103     daniel   4116:     xmlEnumerationPtr tree;
1.22      daniel   4117: 
1.40      daniel   4118:     if ((CUR == '<') && (NXT(1) == '!') &&
                   4119:         (NXT(2) == 'A') && (NXT(3) == 'T') &&
                   4120:         (NXT(4) == 'T') && (NXT(5) == 'L') &&
                   4121:         (NXT(6) == 'I') && (NXT(7) == 'S') &&
1.59      daniel   4122:         (NXT(8) == 'T')) {
1.40      daniel   4123:        SKIP(9);
1.59      daniel   4124:        if (!IS_BLANK(CUR)) {
                   4125:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   4126:                ctxt->sax->error(ctxt->userData,
                   4127:                                 "Space required after '<!ATTLIST'\n");
1.123     daniel   4128:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   4129:            ctxt->wellFormed = 0;
                   4130:        }
1.42      daniel   4131:         SKIP_BLANKS;
1.59      daniel   4132:         elemName = xmlParseName(ctxt);
                   4133:        if (elemName == NULL) {
1.55      daniel   4134:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   4135:                ctxt->sax->error(ctxt->userData,
                   4136:                                 "ATTLIST: no name for Element\n");
1.123     daniel   4137:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.59      daniel   4138:            ctxt->wellFormed = 0;
1.22      daniel   4139:            return;
                   4140:        }
1.42      daniel   4141:        SKIP_BLANKS;
1.40      daniel   4142:        while (CUR != '>') {
1.123     daniel   4143:            const xmlChar *check = CUR_PTR;
1.59      daniel   4144:            int type;
                   4145:            int def;
1.123     daniel   4146:            xmlChar *defaultValue = NULL;
1.59      daniel   4147: 
1.103     daniel   4148:             tree = NULL;
1.59      daniel   4149:            attrName = xmlParseName(ctxt);
                   4150:            if (attrName == NULL) {
                   4151:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   4152:                    ctxt->sax->error(ctxt->userData,
                   4153:                                     "ATTLIST: no name for Attribute\n");
1.123     daniel   4154:                ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.59      daniel   4155:                ctxt->wellFormed = 0;
                   4156:                break;
                   4157:            }
1.97      daniel   4158:            GROW;
1.59      daniel   4159:            if (!IS_BLANK(CUR)) {
                   4160:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4161:                    ctxt->sax->error(ctxt->userData, 
1.59      daniel   4162:                        "Space required after the attribute name\n");
1.123     daniel   4163:                ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   4164:                ctxt->wellFormed = 0;
                   4165:                break;
                   4166:            }
                   4167:            SKIP_BLANKS;
                   4168: 
1.66      daniel   4169:            type = xmlParseAttributeType(ctxt, &tree);
1.59      daniel   4170:            if (type <= 0) break;
1.22      daniel   4171: 
1.97      daniel   4172:            GROW;
1.59      daniel   4173:            if (!IS_BLANK(CUR)) {
                   4174:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4175:                    ctxt->sax->error(ctxt->userData, 
1.59      daniel   4176:                        "Space required after the attribute type\n");
1.123     daniel   4177:                ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   4178:                ctxt->wellFormed = 0;
                   4179:                break;
                   4180:            }
1.42      daniel   4181:            SKIP_BLANKS;
1.59      daniel   4182: 
                   4183:            def = xmlParseDefaultDecl(ctxt, &defaultValue);
                   4184:            if (def <= 0) break;
                   4185: 
1.97      daniel   4186:            GROW;
1.59      daniel   4187:             if (CUR != '>') {
                   4188:                if (!IS_BLANK(CUR)) {
                   4189:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4190:                        ctxt->sax->error(ctxt->userData, 
1.59      daniel   4191:                        "Space required after the attribute default value\n");
1.123     daniel   4192:                    ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   4193:                    ctxt->wellFormed = 0;
                   4194:                    break;
                   4195:                }
                   4196:                SKIP_BLANKS;
                   4197:            }
1.40      daniel   4198:            if (check == CUR_PTR) {
1.55      daniel   4199:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4200:                    ctxt->sax->error(ctxt->userData, 
1.59      daniel   4201:                    "xmlParseAttributeListDecl: detected internal error\n");
1.123     daniel   4202:                ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.22      daniel   4203:                break;
                   4204:            }
1.72      daniel   4205:            if ((ctxt->sax != NULL) && (ctxt->sax->attributeDecl != NULL))
1.74      daniel   4206:                ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
1.66      daniel   4207:                                type, def, defaultValue, tree);
1.59      daniel   4208:            if (attrName != NULL)
1.119     daniel   4209:                xmlFree(attrName);
1.59      daniel   4210:            if (defaultValue != NULL)
1.119     daniel   4211:                xmlFree(defaultValue);
1.97      daniel   4212:            GROW;
1.22      daniel   4213:        }
1.40      daniel   4214:        if (CUR == '>')
                   4215:            NEXT;
1.22      daniel   4216: 
1.119     daniel   4217:        xmlFree(elemName);
1.22      daniel   4218:     }
                   4219: }
                   4220: 
1.50      daniel   4221: /**
1.61      daniel   4222:  * xmlParseElementMixedContentDecl:
                   4223:  * @ctxt:  an XML parser context
                   4224:  *
                   4225:  * parse the declaration for a Mixed Element content
                   4226:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
                   4227:  * 
                   4228:  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
                   4229:  *                '(' S? '#PCDATA' S? ')'
                   4230:  *
1.99      daniel   4231:  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
                   4232:  *
                   4233:  * [ VC: No Duplicate Types ]
1.117     daniel   4234:  * The same name must not appear more than once in a single
                   4235:  * mixed-content declaration. 
1.99      daniel   4236:  *
1.61      daniel   4237:  * returns: the list of the xmlElementContentPtr describing the element choices
                   4238:  */
                   4239: xmlElementContentPtr
1.62      daniel   4240: xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt) {
1.64      daniel   4241:     xmlElementContentPtr ret = NULL, cur = NULL, n;
1.123     daniel   4242:     xmlChar *elem = NULL;
1.61      daniel   4243: 
1.97      daniel   4244:     GROW;
1.61      daniel   4245:     if ((CUR == '#') && (NXT(1) == 'P') &&
                   4246:         (NXT(2) == 'C') && (NXT(3) == 'D') &&
                   4247:         (NXT(4) == 'A') && (NXT(5) == 'T') &&
                   4248:         (NXT(6) == 'A')) {
                   4249:        SKIP(7);
                   4250:        SKIP_BLANKS;
1.91      daniel   4251:        SHRINK;
1.63      daniel   4252:        if (CUR == ')') {
                   4253:            NEXT;
                   4254:            ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
1.136     daniel   4255:            if (CUR == '*') {
                   4256:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   4257:                NEXT;
                   4258:            }
1.63      daniel   4259:            return(ret);
                   4260:        }
1.61      daniel   4261:        if ((CUR == '(') || (CUR == '|')) {
                   4262:            ret = cur = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
                   4263:            if (ret == NULL) return(NULL);
1.99      daniel   4264:        }
1.61      daniel   4265:        while (CUR == '|') {
1.64      daniel   4266:            NEXT;
1.61      daniel   4267:            if (elem == NULL) {
                   4268:                ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
                   4269:                if (ret == NULL) return(NULL);
                   4270:                ret->c1 = cur;
1.64      daniel   4271:                cur = ret;
1.61      daniel   4272:            } else {
1.64      daniel   4273:                n = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
                   4274:                if (n == NULL) return(NULL);
                   4275:                n->c1 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
                   4276:                cur->c2 = n;
                   4277:                cur = n;
1.119     daniel   4278:                xmlFree(elem);
1.61      daniel   4279:            }
                   4280:            SKIP_BLANKS;
                   4281:            elem = xmlParseName(ctxt);
                   4282:            if (elem == NULL) {
                   4283:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4284:                    ctxt->sax->error(ctxt->userData, 
1.61      daniel   4285:                        "xmlParseElementMixedContentDecl : Name expected\n");
1.123     daniel   4286:                ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.61      daniel   4287:                ctxt->wellFormed = 0;
                   4288:                xmlFreeElementContent(cur);
                   4289:                return(NULL);
                   4290:            }
                   4291:            SKIP_BLANKS;
1.97      daniel   4292:            GROW;
1.61      daniel   4293:        }
1.63      daniel   4294:        if ((CUR == ')') && (NXT(1) == '*')) {
1.66      daniel   4295:            if (elem != NULL) {
1.61      daniel   4296:                cur->c2 = xmlNewElementContent(elem,
                   4297:                                               XML_ELEMENT_CONTENT_ELEMENT);
1.119     daniel   4298:                xmlFree(elem);
1.66      daniel   4299:             }
1.65      daniel   4300:            ret->ocur = XML_ELEMENT_CONTENT_MULT;
1.64      daniel   4301:            SKIP(2);
1.61      daniel   4302:        } else {
1.119     daniel   4303:            if (elem != NULL) xmlFree(elem);
1.61      daniel   4304:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4305:                ctxt->sax->error(ctxt->userData, 
1.63      daniel   4306:                    "xmlParseElementMixedContentDecl : '|' or ')*' expected\n");
1.123     daniel   4307:            ctxt->errNo = XML_ERR_MIXED_NOT_STARTED;
1.61      daniel   4308:            ctxt->wellFormed = 0;
                   4309:            xmlFreeElementContent(ret);
                   4310:            return(NULL);
                   4311:        }
                   4312: 
                   4313:     } else {
                   4314:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4315:            ctxt->sax->error(ctxt->userData, 
1.61      daniel   4316:                "xmlParseElementMixedContentDecl : '#PCDATA' expected\n");
1.123     daniel   4317:        ctxt->errNo = XML_ERR_PCDATA_REQUIRED;
1.61      daniel   4318:        ctxt->wellFormed = 0;
                   4319:     }
                   4320:     return(ret);
                   4321: }
                   4322: 
                   4323: /**
                   4324:  * xmlParseElementChildrenContentDecl:
1.50      daniel   4325:  * @ctxt:  an XML parser context
                   4326:  *
1.61      daniel   4327:  * parse the declaration for a Mixed Element content
                   4328:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
1.22      daniel   4329:  * 
1.61      daniel   4330:  *
1.22      daniel   4331:  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
                   4332:  *
                   4333:  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
                   4334:  *
                   4335:  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
                   4336:  *
                   4337:  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
                   4338:  *
1.99      daniel   4339:  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
                   4340:  * TODO Parameter-entity replacement text must be properly nested
                   4341:  *     with parenthetized groups. That is to say, if either of the
                   4342:  *     opening or closing parentheses in a choice, seq, or Mixed
                   4343:  *     construct is contained in the replacement text for a parameter
                   4344:  *     entity, both must be contained in the same replacement text. For
                   4345:  *     interoperability, if a parameter-entity reference appears in a
                   4346:  *     choice, seq, or Mixed construct, its replacement text should not
                   4347:  *     be empty, and neither the first nor last non-blank character of
                   4348:  *     the replacement text should be a connector (| or ,).
                   4349:  *
1.62      daniel   4350:  * returns: the tree of xmlElementContentPtr describing the element 
1.61      daniel   4351:  *          hierarchy.
                   4352:  */
                   4353: xmlElementContentPtr
1.62      daniel   4354: xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) {
1.63      daniel   4355:     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
1.123     daniel   4356:     xmlChar *elem;
                   4357:     xmlChar type = 0;
1.62      daniel   4358: 
                   4359:     SKIP_BLANKS;
1.94      daniel   4360:     GROW;
1.62      daniel   4361:     if (CUR == '(') {
1.63      daniel   4362:         /* Recurse on first child */
1.62      daniel   4363:        NEXT;
                   4364:        SKIP_BLANKS;
                   4365:         cur = ret = xmlParseElementChildrenContentDecl(ctxt);
                   4366:        SKIP_BLANKS;
1.101     daniel   4367:        GROW;
1.62      daniel   4368:     } else {
                   4369:        elem = xmlParseName(ctxt);
                   4370:        if (elem == NULL) {
                   4371:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4372:                ctxt->sax->error(ctxt->userData, 
1.62      daniel   4373:                "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
1.123     daniel   4374:            ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
1.62      daniel   4375:            ctxt->wellFormed = 0;
                   4376:            return(NULL);
                   4377:        }
                   4378:         cur = ret = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
1.101     daniel   4379:        GROW;
1.62      daniel   4380:        if (CUR == '?') {
1.104     daniel   4381:            cur->ocur = XML_ELEMENT_CONTENT_OPT;
1.62      daniel   4382:            NEXT;
                   4383:        } else if (CUR == '*') {
1.104     daniel   4384:            cur->ocur = XML_ELEMENT_CONTENT_MULT;
1.62      daniel   4385:            NEXT;
                   4386:        } else if (CUR == '+') {
1.104     daniel   4387:            cur->ocur = XML_ELEMENT_CONTENT_PLUS;
1.62      daniel   4388:            NEXT;
                   4389:        } else {
1.104     daniel   4390:            cur->ocur = XML_ELEMENT_CONTENT_ONCE;
1.62      daniel   4391:        }
1.119     daniel   4392:        xmlFree(elem);
1.101     daniel   4393:        GROW;
1.62      daniel   4394:     }
                   4395:     SKIP_BLANKS;
1.91      daniel   4396:     SHRINK;
1.62      daniel   4397:     while (CUR != ')') {
1.63      daniel   4398:         /*
                   4399:         * Each loop we parse one separator and one element.
                   4400:         */
1.62      daniel   4401:         if (CUR == ',') {
                   4402:            if (type == 0) type = CUR;
                   4403: 
                   4404:            /*
                   4405:             * Detect "Name | Name , Name" error
                   4406:             */
                   4407:            else if (type != CUR) {
                   4408:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4409:                    ctxt->sax->error(ctxt->userData, 
1.62      daniel   4410:                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
                   4411:                    type);
1.123     daniel   4412:                ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
1.62      daniel   4413:                ctxt->wellFormed = 0;
                   4414:                xmlFreeElementContent(ret);
                   4415:                return(NULL);
                   4416:            }
1.64      daniel   4417:            NEXT;
1.62      daniel   4418: 
1.63      daniel   4419:            op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_SEQ);
                   4420:            if (op == NULL) {
                   4421:                xmlFreeElementContent(ret);
                   4422:                return(NULL);
                   4423:            }
                   4424:            if (last == NULL) {
                   4425:                op->c1 = ret;
1.65      daniel   4426:                ret = cur = op;
1.63      daniel   4427:            } else {
                   4428:                cur->c2 = op;
                   4429:                op->c1 = last;
                   4430:                cur =op;
1.65      daniel   4431:                last = NULL;
1.63      daniel   4432:            }
1.62      daniel   4433:        } else if (CUR == '|') {
                   4434:            if (type == 0) type = CUR;
                   4435: 
                   4436:            /*
1.63      daniel   4437:             * Detect "Name , Name | Name" error
1.62      daniel   4438:             */
                   4439:            else if (type != CUR) {
                   4440:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4441:                    ctxt->sax->error(ctxt->userData, 
1.62      daniel   4442:                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
                   4443:                    type);
1.123     daniel   4444:                ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
1.62      daniel   4445:                ctxt->wellFormed = 0;
                   4446:                xmlFreeElementContent(ret);
                   4447:                return(NULL);
                   4448:            }
1.64      daniel   4449:            NEXT;
1.62      daniel   4450: 
1.63      daniel   4451:            op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
                   4452:            if (op == NULL) {
                   4453:                xmlFreeElementContent(ret);
                   4454:                return(NULL);
                   4455:            }
                   4456:            if (last == NULL) {
                   4457:                op->c1 = ret;
1.65      daniel   4458:                ret = cur = op;
1.63      daniel   4459:            } else {
                   4460:                cur->c2 = op;
                   4461:                op->c1 = last;
                   4462:                cur =op;
1.65      daniel   4463:                last = NULL;
1.63      daniel   4464:            }
1.62      daniel   4465:        } else {
                   4466:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4467:                ctxt->sax->error(ctxt->userData, 
1.62      daniel   4468:            "xmlParseElementChildrenContentDecl : ',' '|' or ')' expected\n");
                   4469:            ctxt->wellFormed = 0;
1.123     daniel   4470:            ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_FINISHED;
1.62      daniel   4471:            xmlFreeElementContent(ret);
                   4472:            return(NULL);
                   4473:        }
1.101     daniel   4474:        GROW;
1.62      daniel   4475:        SKIP_BLANKS;
1.101     daniel   4476:        GROW;
1.62      daniel   4477:        if (CUR == '(') {
1.63      daniel   4478:            /* Recurse on second child */
1.62      daniel   4479:            NEXT;
                   4480:            SKIP_BLANKS;
1.65      daniel   4481:            last = xmlParseElementChildrenContentDecl(ctxt);
1.62      daniel   4482:            SKIP_BLANKS;
                   4483:        } else {
                   4484:            elem = xmlParseName(ctxt);
                   4485:            if (elem == NULL) {
                   4486:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4487:                    ctxt->sax->error(ctxt->userData, 
1.122     daniel   4488:                "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
1.123     daniel   4489:                ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
1.62      daniel   4490:                ctxt->wellFormed = 0;
                   4491:                return(NULL);
                   4492:            }
1.65      daniel   4493:            last = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
1.119     daniel   4494:            xmlFree(elem);
1.105     daniel   4495:            if (CUR == '?') {
                   4496:                last->ocur = XML_ELEMENT_CONTENT_OPT;
                   4497:                NEXT;
                   4498:            } else if (CUR == '*') {
                   4499:                last->ocur = XML_ELEMENT_CONTENT_MULT;
                   4500:                NEXT;
                   4501:            } else if (CUR == '+') {
                   4502:                last->ocur = XML_ELEMENT_CONTENT_PLUS;
                   4503:                NEXT;
                   4504:            } else {
                   4505:                last->ocur = XML_ELEMENT_CONTENT_ONCE;
                   4506:            }
1.63      daniel   4507:        }
                   4508:        SKIP_BLANKS;
1.97      daniel   4509:        GROW;
1.64      daniel   4510:     }
1.65      daniel   4511:     if ((cur != NULL) && (last != NULL)) {
                   4512:         cur->c2 = last;
1.62      daniel   4513:     }
                   4514:     NEXT;
                   4515:     if (CUR == '?') {
                   4516:         ret->ocur = XML_ELEMENT_CONTENT_OPT;
                   4517:        NEXT;
                   4518:     } else if (CUR == '*') {
                   4519:         ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   4520:        NEXT;
                   4521:     } else if (CUR == '+') {
                   4522:         ret->ocur = XML_ELEMENT_CONTENT_PLUS;
                   4523:        NEXT;
                   4524:     }
                   4525:     return(ret);
1.61      daniel   4526: }
                   4527: 
                   4528: /**
                   4529:  * xmlParseElementContentDecl:
                   4530:  * @ctxt:  an XML parser context
                   4531:  * @name:  the name of the element being defined.
                   4532:  * @result:  the Element Content pointer will be stored here if any
1.22      daniel   4533:  *
1.61      daniel   4534:  * parse the declaration for an Element content either Mixed or Children,
                   4535:  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
                   4536:  * 
                   4537:  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
1.50      daniel   4538:  *
1.61      daniel   4539:  * returns: the type of element content XML_ELEMENT_TYPE_xxx
1.22      daniel   4540:  */
                   4541: 
1.61      daniel   4542: int
1.123     daniel   4543: xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, xmlChar *name,
1.61      daniel   4544:                            xmlElementContentPtr *result) {
                   4545: 
                   4546:     xmlElementContentPtr tree = NULL;
                   4547:     int res;
                   4548: 
                   4549:     *result = NULL;
                   4550: 
                   4551:     if (CUR != '(') {
                   4552:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4553:            ctxt->sax->error(ctxt->userData, 
1.61      daniel   4554:                "xmlParseElementContentDecl : '(' expected\n");
1.123     daniel   4555:        ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
1.61      daniel   4556:        ctxt->wellFormed = 0;
                   4557:        return(-1);
                   4558:     }
                   4559:     NEXT;
1.97      daniel   4560:     GROW;
1.61      daniel   4561:     SKIP_BLANKS;
                   4562:     if ((CUR == '#') && (NXT(1) == 'P') &&
                   4563:         (NXT(2) == 'C') && (NXT(3) == 'D') &&
                   4564:         (NXT(4) == 'A') && (NXT(5) == 'T') &&
                   4565:         (NXT(6) == 'A')) {
1.62      daniel   4566:         tree = xmlParseElementMixedContentDecl(ctxt);
1.61      daniel   4567:        res = XML_ELEMENT_TYPE_MIXED;
                   4568:     } else {
1.62      daniel   4569:         tree = xmlParseElementChildrenContentDecl(ctxt);
1.61      daniel   4570:        res = XML_ELEMENT_TYPE_ELEMENT;
                   4571:     }
                   4572:     SKIP_BLANKS;
1.63      daniel   4573:     /****************************
1.61      daniel   4574:     if (CUR != ')') {
                   4575:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4576:            ctxt->sax->error(ctxt->userData, 
1.61      daniel   4577:                "xmlParseElementContentDecl : ')' expected\n");
                   4578:        ctxt->wellFormed = 0;
                   4579:        return(-1);
                   4580:     }
1.63      daniel   4581:      ****************************/
                   4582:     *result = tree;
1.61      daniel   4583:     return(res);
1.22      daniel   4584: }
                   4585: 
1.50      daniel   4586: /**
                   4587:  * xmlParseElementDecl:
                   4588:  * @ctxt:  an XML parser context
                   4589:  *
                   4590:  * parse an Element declaration.
1.22      daniel   4591:  *
                   4592:  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
                   4593:  *
1.99      daniel   4594:  * [ VC: Unique Element Type Declaration ]
1.117     daniel   4595:  * No element type may be declared more than once
1.69      daniel   4596:  *
                   4597:  * Returns the type of the element, or -1 in case of error
1.22      daniel   4598:  */
1.59      daniel   4599: int
1.55      daniel   4600: xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   4601:     xmlChar *name;
1.59      daniel   4602:     int ret = -1;
1.61      daniel   4603:     xmlElementContentPtr content  = NULL;
1.22      daniel   4604: 
1.97      daniel   4605:     GROW;
1.40      daniel   4606:     if ((CUR == '<') && (NXT(1) == '!') &&
                   4607:         (NXT(2) == 'E') && (NXT(3) == 'L') &&
                   4608:         (NXT(4) == 'E') && (NXT(5) == 'M') &&
                   4609:         (NXT(6) == 'E') && (NXT(7) == 'N') &&
1.59      daniel   4610:         (NXT(8) == 'T')) {
1.40      daniel   4611:        SKIP(9);
1.59      daniel   4612:        if (!IS_BLANK(CUR)) {
                   4613:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4614:                ctxt->sax->error(ctxt->userData, 
1.59      daniel   4615:                    "Space required after 'ELEMENT'\n");
1.123     daniel   4616:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   4617:            ctxt->wellFormed = 0;
                   4618:        }
1.42      daniel   4619:         SKIP_BLANKS;
1.22      daniel   4620:         name = xmlParseName(ctxt);
                   4621:        if (name == NULL) {
1.55      daniel   4622:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4623:                ctxt->sax->error(ctxt->userData,
1.59      daniel   4624:                   "xmlParseElementDecl: no name for Element\n");
1.123     daniel   4625:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.59      daniel   4626:            ctxt->wellFormed = 0;
                   4627:            return(-1);
                   4628:        }
                   4629:        if (!IS_BLANK(CUR)) {
                   4630:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4631:                ctxt->sax->error(ctxt->userData, 
1.59      daniel   4632:                    "Space required after the element name\n");
1.123     daniel   4633:            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   4634:            ctxt->wellFormed = 0;
1.22      daniel   4635:        }
1.42      daniel   4636:         SKIP_BLANKS;
1.40      daniel   4637:        if ((CUR == 'E') && (NXT(1) == 'M') &&
                   4638:            (NXT(2) == 'P') && (NXT(3) == 'T') &&
                   4639:            (NXT(4) == 'Y')) {
                   4640:            SKIP(5);
1.22      daniel   4641:            /*
                   4642:             * Element must always be empty.
                   4643:             */
1.59      daniel   4644:            ret = XML_ELEMENT_TYPE_EMPTY;
1.40      daniel   4645:        } else if ((CUR == 'A') && (NXT(1) == 'N') &&
                   4646:                   (NXT(2) == 'Y')) {
                   4647:            SKIP(3);
1.22      daniel   4648:            /*
                   4649:             * Element is a generic container.
                   4650:             */
1.59      daniel   4651:            ret = XML_ELEMENT_TYPE_ANY;
1.61      daniel   4652:        } else if (CUR == '(') {
                   4653:            ret = xmlParseElementContentDecl(ctxt, name, &content);
1.22      daniel   4654:        } else {
1.98      daniel   4655:            /*
                   4656:             * [ WFC: PEs in Internal Subset ] error handling.
                   4657:             */
                   4658:            if ((CUR == '%') && (ctxt->external == 0) &&
                   4659:                (ctxt->inputNr == 1)) {
                   4660:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   4661:                    ctxt->sax->error(ctxt->userData, 
                   4662:          "PEReference: forbidden within markup decl in internal subset\n");
1.123     daniel   4663:                ctxt->errNo = XML_ERR_PEREF_IN_INT_SUBSET;
1.98      daniel   4664:            } else {
                   4665:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   4666:                    ctxt->sax->error(ctxt->userData, 
                   4667:                      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
1.123     daniel   4668:                ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
1.98      daniel   4669:             }
1.61      daniel   4670:            ctxt->wellFormed = 0;
1.119     daniel   4671:            if (name != NULL) xmlFree(name);
1.61      daniel   4672:            return(-1);
1.22      daniel   4673:        }
1.142     daniel   4674: 
                   4675:        SKIP_BLANKS;
                   4676:        /*
                   4677:         * Pop-up of finished entities.
                   4678:         */
                   4679:        while ((CUR == 0) && (ctxt->inputNr > 1))
                   4680:            xmlPopInput(ctxt);
1.42      daniel   4681:        SKIP_BLANKS;
1.142     daniel   4682: 
1.40      daniel   4683:        if (CUR != '>') {
1.55      daniel   4684:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   4685:                ctxt->sax->error(ctxt->userData, 
1.31      daniel   4686:                  "xmlParseElementDecl: expected '>' at the end\n");
1.123     daniel   4687:            ctxt->errNo = XML_ERR_GT_REQUIRED;
1.59      daniel   4688:            ctxt->wellFormed = 0;
1.61      daniel   4689:        } else {
1.40      daniel   4690:            NEXT;
1.72      daniel   4691:            if ((ctxt->sax != NULL) && (ctxt->sax->elementDecl != NULL))
1.76      daniel   4692:                ctxt->sax->elementDecl(ctxt->userData, name, ret,
                   4693:                                       content);
1.61      daniel   4694:        }
1.84      daniel   4695:        if (content != NULL) {
                   4696:            xmlFreeElementContent(content);
                   4697:        }
1.61      daniel   4698:        if (name != NULL) {
1.119     daniel   4699:            xmlFree(name);
1.61      daniel   4700:        }
1.22      daniel   4701:     }
1.59      daniel   4702:     return(ret);
1.22      daniel   4703: }
                   4704: 
1.50      daniel   4705: /**
                   4706:  * xmlParseMarkupDecl:
                   4707:  * @ctxt:  an XML parser context
                   4708:  * 
                   4709:  * parse Markup declarations
1.22      daniel   4710:  *
                   4711:  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
                   4712:  *                     NotationDecl | PI | Comment
                   4713:  *
1.98      daniel   4714:  * [ VC: Proper Declaration/PE Nesting ]
                   4715:  * TODO Parameter-entity replacement text must be properly nested with
                   4716:  * markup declarations. That is to say, if either the first character
                   4717:  * or the last character of a markup declaration (markupdecl above) is
                   4718:  * contained in the replacement text for a parameter-entity reference,
                   4719:  * both must be contained in the same replacement text.
                   4720:  *
                   4721:  * [ WFC: PEs in Internal Subset ]
                   4722:  * In the internal DTD subset, parameter-entity references can occur
                   4723:  * only where markup declarations can occur, not within markup declarations.
                   4724:  * (This does not apply to references that occur in external parameter
                   4725:  * entities or to the external subset.) 
1.22      daniel   4726:  */
1.55      daniel   4727: void
                   4728: xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
1.94      daniel   4729:     GROW;
1.22      daniel   4730:     xmlParseElementDecl(ctxt);
                   4731:     xmlParseAttributeListDecl(ctxt);
                   4732:     xmlParseEntityDecl(ctxt);
                   4733:     xmlParseNotationDecl(ctxt);
                   4734:     xmlParsePI(ctxt);
1.114     daniel   4735:     xmlParseComment(ctxt);
1.98      daniel   4736:     /*
                   4737:      * This is only for internal subset. On external entities,
                   4738:      * the replacement is done before parsing stage
                   4739:      */
                   4740:     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
                   4741:        xmlParsePEReference(ctxt);
1.97      daniel   4742:     ctxt->instate = XML_PARSER_DTD;
1.22      daniel   4743: }
                   4744: 
1.50      daniel   4745: /**
1.76      daniel   4746:  * xmlParseTextDecl:
                   4747:  * @ctxt:  an XML parser context
                   4748:  * 
                   4749:  * parse an XML declaration header for external entities
                   4750:  *
                   4751:  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
                   4752:  *
                   4753:  * Returns the only valuable info for an external parsed entity, the encoding
                   4754:  */
                   4755: 
1.123     daniel   4756: xmlChar *
1.76      daniel   4757: xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   4758:     xmlChar *version;
                   4759:     xmlChar *encoding = NULL;
1.76      daniel   4760: 
                   4761:     /*
                   4762:      * We know that '<?xml' is here.
                   4763:      */
                   4764:     SKIP(5);
                   4765: 
                   4766:     if (!IS_BLANK(CUR)) {
                   4767:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   4768:            ctxt->sax->error(ctxt->userData,
                   4769:                             "Space needed after '<?xml'\n");
1.123     daniel   4770:        ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.76      daniel   4771:        ctxt->wellFormed = 0;
                   4772:     }
                   4773:     SKIP_BLANKS;
                   4774: 
                   4775:     /*
                   4776:      * We may have the VersionInfo here.
                   4777:      */
                   4778:     version = xmlParseVersionInfo(ctxt);
                   4779:     if (version == NULL)
                   4780:        version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   4781:     ctxt->version = xmlStrdup(version);
1.119     daniel   4782:     xmlFree(version);
1.76      daniel   4783: 
                   4784:     /*
                   4785:      * We must have the encoding declaration
                   4786:      */
                   4787:     if (!IS_BLANK(CUR)) {
                   4788:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   4789:            ctxt->sax->error(ctxt->userData, "Space needed here\n");
1.123     daniel   4790:        ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.76      daniel   4791:        ctxt->wellFormed = 0;
                   4792:     }
                   4793:     encoding = xmlParseEncodingDecl(ctxt);
                   4794: 
                   4795:     SKIP_BLANKS;
                   4796:     if ((CUR == '?') && (NXT(1) == '>')) {
                   4797:         SKIP(2);
                   4798:     } else if (CUR == '>') {
                   4799:         /* Deprecated old WD ... */
                   4800:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   4801:            ctxt->sax->error(ctxt->userData,
                   4802:                             "XML declaration must end-up with '?>'\n");
1.123     daniel   4803:        ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
1.76      daniel   4804:        ctxt->wellFormed = 0;
                   4805:        NEXT;
                   4806:     } else {
                   4807:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   4808:            ctxt->sax->error(ctxt->userData,
                   4809:                             "parsing XML declaration: '?>' expected\n");
1.123     daniel   4810:        ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
1.76      daniel   4811:        ctxt->wellFormed = 0;
                   4812:        MOVETO_ENDTAG(CUR_PTR);
                   4813:        NEXT;
                   4814:     }
                   4815:     return(encoding);
                   4816: }
                   4817: 
                   4818: /*
                   4819:  * xmlParseConditionalSections
                   4820:  * @ctxt:  an XML parser context
                   4821:  *
                   4822:  * TODO : Conditionnal section are not yet supported !
                   4823:  *
                   4824:  * [61] conditionalSect ::= includeSect | ignoreSect 
                   4825:  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 
                   4826:  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
                   4827:  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
                   4828:  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
                   4829:  */
                   4830: 
                   4831: void
                   4832: xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
                   4833:     if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   4834:        ctxt->sax->warning(ctxt->userData,
                   4835:                            "XML conditional section not supported\n");
                   4836:     /*
                   4837:      * Skip up to the end of the conditionnal section.
                   4838:      */
1.143     daniel   4839:     while ((CUR != 0) && ((CUR != ']') || (NXT(1) != ']') || (NXT(2) != '>'))) {
1.76      daniel   4840:        NEXT;
1.143     daniel   4841:        /*
                   4842:         * Pop-up of finished entities.
                   4843:         */
                   4844:        while ((CUR == 0) && (ctxt->inputNr > 1))
                   4845:            xmlPopInput(ctxt);
                   4846: 
                   4847:        if (CUR == 0)
                   4848:            GROW;
                   4849:     }
                   4850: 
                   4851:     if (CUR == 0)
                   4852:         SHRINK;
                   4853: 
1.76      daniel   4854:     if (CUR == 0) {
                   4855:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   4856:            ctxt->sax->error(ctxt->userData,
                   4857:                "XML conditional section not closed\n");
1.123     daniel   4858:        ctxt->errNo = XML_ERR_CONDSEC_NOT_FINISHED;
1.76      daniel   4859:        ctxt->wellFormed = 0;
1.143     daniel   4860:     } else {
                   4861:         SKIP(3);
1.76      daniel   4862:     }
                   4863: }
                   4864: 
                   4865: /**
1.124     daniel   4866:  * xmlParseExternalSubset:
1.76      daniel   4867:  * @ctxt:  an XML parser context
1.124     daniel   4868:  * @ExternalID: the external identifier
                   4869:  * @SystemID: the system identifier (or URL)
1.76      daniel   4870:  * 
                   4871:  * parse Markup declarations from an external subset
                   4872:  *
                   4873:  * [30] extSubset ::= textDecl? extSubsetDecl
                   4874:  *
                   4875:  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
                   4876:  */
                   4877: void
1.123     daniel   4878: xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
                   4879:                        const xmlChar *SystemID) {
1.132     daniel   4880:     GROW;
1.76      daniel   4881:     if ((CUR == '<') && (NXT(1) == '?') &&
                   4882:         (NXT(2) == 'x') && (NXT(3) == 'm') &&
                   4883:        (NXT(4) == 'l')) {
1.134     daniel   4884:        xmlChar *decl;
                   4885: 
                   4886:        decl = xmlParseTextDecl(ctxt);
                   4887:        if (decl != NULL)
                   4888:            xmlFree(decl);
1.76      daniel   4889:     }
1.79      daniel   4890:     if (ctxt->myDoc == NULL) {
1.116     daniel   4891:         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
1.79      daniel   4892:     }
                   4893:     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
                   4894:         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
                   4895: 
1.96      daniel   4896:     ctxt->instate = XML_PARSER_DTD;
1.101     daniel   4897:     ctxt->external = 1;
1.76      daniel   4898:     while (((CUR == '<') && (NXT(1) == '?')) ||
                   4899:            ((CUR == '<') && (NXT(1) == '!')) ||
                   4900:            IS_BLANK(CUR)) {
1.123     daniel   4901:        const xmlChar *check = CUR_PTR;
1.115     daniel   4902:        int cons = ctxt->input->consumed;
                   4903: 
1.76      daniel   4904:         if ((CUR == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   4905:            xmlParseConditionalSections(ctxt);
                   4906:        } else if (IS_BLANK(CUR)) {
                   4907:            NEXT;
                   4908:        } else if (CUR == '%') {
                   4909:             xmlParsePEReference(ctxt);
                   4910:        } else
                   4911:            xmlParseMarkupDecl(ctxt);
1.77      daniel   4912: 
                   4913:        /*
                   4914:         * Pop-up of finished entities.
                   4915:         */
                   4916:        while ((CUR == 0) && (ctxt->inputNr > 1))
                   4917:            xmlPopInput(ctxt);
                   4918: 
1.115     daniel   4919:        if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                   4920:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   4921:                ctxt->sax->error(ctxt->userData,
                   4922:                    "Content error in the external subset\n");
                   4923:            ctxt->wellFormed = 0;
1.123     daniel   4924:            ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
1.115     daniel   4925:            break;
                   4926:        }
1.76      daniel   4927:     }
                   4928:     
                   4929:     if (CUR != 0) {
                   4930:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   4931:            ctxt->sax->error(ctxt->userData,
                   4932:                "Extra content at the end of the document\n");
1.123     daniel   4933:        ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
1.76      daniel   4934:        ctxt->wellFormed = 0;
                   4935:     }
                   4936: 
                   4937: }
                   4938: 
                   4939: /**
1.77      daniel   4940:  * xmlParseReference:
                   4941:  * @ctxt:  an XML parser context
                   4942:  * 
                   4943:  * parse and handle entity references in content, depending on the SAX
                   4944:  * interface, this may end-up in a call to character() if this is a
1.79      daniel   4945:  * CharRef, a predefined entity, if there is no reference() callback.
                   4946:  * or if the parser was asked to switch to that mode.
1.77      daniel   4947:  *
                   4948:  * [67] Reference ::= EntityRef | CharRef
                   4949:  */
                   4950: void
                   4951: xmlParseReference(xmlParserCtxtPtr ctxt) {
                   4952:     xmlEntityPtr ent;
1.123     daniel   4953:     xmlChar *val;
1.77      daniel   4954:     if (CUR != '&') return;
                   4955: 
1.113     daniel   4956:     if (ctxt->inputNr > 1) {
1.123     daniel   4957:         xmlChar cur[2] = { '&' , 0 } ;
1.113     daniel   4958: 
                   4959:        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
                   4960:            ctxt->sax->characters(ctxt->userData, cur, 1);
                   4961:        if (ctxt->token == '&')
                   4962:            ctxt->token = 0;
                   4963:         else {
                   4964:            SKIP(1);
                   4965:        }
                   4966:        return;
                   4967:     }
1.77      daniel   4968:     if (NXT(1) == '#') {
1.123     daniel   4969:        xmlChar out[2];
1.77      daniel   4970:        int val = xmlParseCharRef(ctxt);
1.117     daniel   4971:        /* invalid for UTF-8 variable encoding !!!!! */
1.77      daniel   4972:        out[0] = val;
                   4973:        out[1] = 0;
                   4974:        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
                   4975:            ctxt->sax->characters(ctxt->userData, out, 1);
                   4976:     } else {
                   4977:        ent = xmlParseEntityRef(ctxt);
                   4978:        if (ent == NULL) return;
                   4979:        if ((ent->name != NULL) && 
1.113     daniel   4980:            (ent->type != XML_INTERNAL_PREDEFINED_ENTITY)) {
                   4981:            if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
                   4982:                (ctxt->replaceEntities == 0)) {
                   4983:                /*
                   4984:                 * Create a node.
                   4985:                 */
                   4986:                ctxt->sax->reference(ctxt->userData, ent->name);
                   4987:                return;
                   4988:            } else if (ctxt->replaceEntities) {
                   4989:                xmlParserInputPtr input;
1.79      daniel   4990: 
1.113     daniel   4991:                input = xmlNewEntityInputStream(ctxt, ent);
                   4992:                xmlPushInput(ctxt, input);
                   4993:                return;
                   4994:            }
1.77      daniel   4995:        }
                   4996:        val = ent->content;
                   4997:        if (val == NULL) return;
                   4998:        /*
                   4999:         * inline the entity.
                   5000:         */
                   5001:        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
                   5002:            ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
                   5003:     }
1.24      daniel   5004: }
                   5005: 
1.50      daniel   5006: /**
                   5007:  * xmlParseEntityRef:
                   5008:  * @ctxt:  an XML parser context
                   5009:  *
                   5010:  * parse ENTITY references declarations
1.24      daniel   5011:  *
                   5012:  * [68] EntityRef ::= '&' Name ';'
1.68      daniel   5013:  *
1.98      daniel   5014:  * [ WFC: Entity Declared ]
                   5015:  * In a document without any DTD, a document with only an internal DTD
                   5016:  * subset which contains no parameter entity references, or a document
                   5017:  * with "standalone='yes'", the Name given in the entity reference
                   5018:  * must match that in an entity declaration, except that well-formed
                   5019:  * documents need not declare any of the following entities: amp, lt,
                   5020:  * gt, apos, quot.  The declaration of a parameter entity must precede
                   5021:  * any reference to it.  Similarly, the declaration of a general entity
                   5022:  * must precede any reference to it which appears in a default value in an
                   5023:  * attribute-list declaration. Note that if entities are declared in the
                   5024:  * external subset or in external parameter entities, a non-validating
                   5025:  * processor is not obligated to read and process their declarations;
                   5026:  * for such documents, the rule that an entity must be declared is a
                   5027:  * well-formedness constraint only if standalone='yes'.
                   5028:  *
                   5029:  * [ WFC: Parsed Entity ]
                   5030:  * An entity reference must not contain the name of an unparsed entity
                   5031:  *
1.77      daniel   5032:  * Returns the xmlEntityPtr if found, or NULL otherwise.
1.24      daniel   5033:  */
1.77      daniel   5034: xmlEntityPtr
1.55      daniel   5035: xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
1.123     daniel   5036:     xmlChar *name;
1.72      daniel   5037:     xmlEntityPtr ent = NULL;
1.24      daniel   5038: 
1.91      daniel   5039:     GROW;
1.111     daniel   5040:     
1.40      daniel   5041:     if (CUR == '&') {
                   5042:         NEXT;
1.24      daniel   5043:         name = xmlParseName(ctxt);
                   5044:        if (name == NULL) {
1.55      daniel   5045:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.98      daniel   5046:                ctxt->sax->error(ctxt->userData,
                   5047:                                 "xmlParseEntityRef: no name\n");
1.123     daniel   5048:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.59      daniel   5049:            ctxt->wellFormed = 0;
1.24      daniel   5050:        } else {
1.40      daniel   5051:            if (CUR == ';') {
                   5052:                NEXT;
1.24      daniel   5053:                /*
1.77      daniel   5054:                 * Ask first SAX for entity resolution, otherwise try the
                   5055:                 * predefined set.
                   5056:                 */
                   5057:                if (ctxt->sax != NULL) {
                   5058:                    if (ctxt->sax->getEntity != NULL)
                   5059:                        ent = ctxt->sax->getEntity(ctxt->userData, name);
                   5060:                    if (ent == NULL)
                   5061:                        ent = xmlGetPredefinedEntity(name);
                   5062:                }
                   5063:                /*
1.98      daniel   5064:                 * [ WFC: Entity Declared ]
                   5065:                 * In a document without any DTD, a document with only an
                   5066:                 * internal DTD subset which contains no parameter entity
                   5067:                 * references, or a document with "standalone='yes'", the
                   5068:                 * Name given in the entity reference must match that in an
                   5069:                 * entity declaration, except that well-formed documents
                   5070:                 * need not declare any of the following entities: amp, lt,
                   5071:                 * gt, apos, quot.
                   5072:                 * The declaration of a parameter entity must precede any
                   5073:                 * reference to it.
                   5074:                 * Similarly, the declaration of a general entity must
                   5075:                 * precede any reference to it which appears in a default
                   5076:                 * value in an attribute-list declaration. Note that if
                   5077:                 * entities are declared in the external subset or in
                   5078:                 * external parameter entities, a non-validating processor
                   5079:                 * is not obligated to read and process their declarations;
                   5080:                 * for such documents, the rule that an entity must be
                   5081:                 * declared is a well-formedness constraint only if
                   5082:                 * standalone='yes'. 
1.59      daniel   5083:                 */
1.77      daniel   5084:                if (ent == NULL) {
1.98      daniel   5085:                    if ((ctxt->standalone == 1) ||
                   5086:                        ((ctxt->hasExternalSubset == 0) &&
                   5087:                         (ctxt->hasPErefs == 0))) {
                   5088:                        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.77      daniel   5089:                            ctxt->sax->error(ctxt->userData, 
                   5090:                                 "Entity '%s' not defined\n", name);
1.123     daniel   5091:                        ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
1.77      daniel   5092:                        ctxt->wellFormed = 0;
                   5093:                    } else {
1.98      daniel   5094:                        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   5095:                            ctxt->sax->warning(ctxt->userData, 
                   5096:                                 "Entity '%s' not defined\n", name);
1.123     daniel   5097:                        ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
1.59      daniel   5098:                    }
1.77      daniel   5099:                }
1.59      daniel   5100: 
                   5101:                /*
1.98      daniel   5102:                 * [ WFC: Parsed Entity ]
                   5103:                 * An entity reference must not contain the name of an
                   5104:                 * unparsed entity
                   5105:                 */
                   5106:                else if (ent->type == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
                   5107:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5108:                        ctxt->sax->error(ctxt->userData, 
                   5109:                             "Entity reference to unparsed entity %s\n", name);
1.123     daniel   5110:                    ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
1.98      daniel   5111:                    ctxt->wellFormed = 0;
                   5112:                }
                   5113: 
                   5114:                /*
                   5115:                 * [ WFC: No External Entity References ]
                   5116:                 * Attribute values cannot contain direct or indirect
                   5117:                 * entity references to external entities.
                   5118:                 */
                   5119:                else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   5120:                         (ent->type == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
                   5121:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5122:                        ctxt->sax->error(ctxt->userData, 
                   5123:                     "Attribute references external entity '%s'\n", name);
1.123     daniel   5124:                    ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
1.98      daniel   5125:                    ctxt->wellFormed = 0;
                   5126:                }
                   5127:                /*
                   5128:                 * [ WFC: No < in Attribute Values ]
                   5129:                 * The replacement text of any entity referred to directly or
                   5130:                 * indirectly in an attribute value (other than "&lt;") must
                   5131:                 * not contain a <. 
1.59      daniel   5132:                 */
1.98      daniel   5133:                else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
1.116     daniel   5134:                         (ent != NULL) &&
                   5135:                         (xmlStrcmp(ent->name, BAD_CAST "lt")) &&
1.98      daniel   5136:                         (ent->content != NULL) &&
                   5137:                         (xmlStrchr(ent->content, '<'))) {
                   5138:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5139:                        ctxt->sax->error(ctxt->userData, 
                   5140:         "'<' in entity '%s' is not allowed in attributes values\n", name);
1.123     daniel   5141:                    ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
1.98      daniel   5142:                    ctxt->wellFormed = 0;
                   5143:                }
                   5144: 
                   5145:                /*
                   5146:                 * Internal check, no parameter entities here ...
                   5147:                 */
                   5148:                else {
1.59      daniel   5149:                    switch (ent->type) {
                   5150:                        case XML_INTERNAL_PARAMETER_ENTITY:
                   5151:                        case XML_EXTERNAL_PARAMETER_ENTITY:
                   5152:                        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5153:                            ctxt->sax->error(ctxt->userData, 
1.59      daniel   5154:                     "Attempt to reference the parameter entity '%s'\n", name);
1.123     daniel   5155:                        ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
1.59      daniel   5156:                        ctxt->wellFormed = 0;
                   5157:                        break;
                   5158:                    }
                   5159:                }
                   5160: 
                   5161:                /*
1.98      daniel   5162:                 * [ WFC: No Recursion ]
1.117     daniel   5163:                 * TODO A parsed entity must not contain a recursive reference
                   5164:                 * to itself, either directly or indirectly. 
1.59      daniel   5165:                 */
1.77      daniel   5166: 
1.24      daniel   5167:            } else {
1.55      daniel   5168:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5169:                    ctxt->sax->error(ctxt->userData,
1.59      daniel   5170:                                     "xmlParseEntityRef: expecting ';'\n");
1.123     daniel   5171:                ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
1.59      daniel   5172:                ctxt->wellFormed = 0;
1.24      daniel   5173:            }
1.119     daniel   5174:            xmlFree(name);
1.24      daniel   5175:        }
                   5176:     }
1.77      daniel   5177:     return(ent);
1.24      daniel   5178: }
1.135     daniel   5179: /**
                   5180:  * xmlParseStringEntityRef:
                   5181:  * @ctxt:  an XML parser context
                   5182:  * @str:  a pointer to an index in the string
                   5183:  *
                   5184:  * parse ENTITY references declarations, but this version parses it from
                   5185:  * a string value.
                   5186:  *
                   5187:  * [68] EntityRef ::= '&' Name ';'
                   5188:  *
                   5189:  * [ WFC: Entity Declared ]
                   5190:  * In a document without any DTD, a document with only an internal DTD
                   5191:  * subset which contains no parameter entity references, or a document
                   5192:  * with "standalone='yes'", the Name given in the entity reference
                   5193:  * must match that in an entity declaration, except that well-formed
                   5194:  * documents need not declare any of the following entities: amp, lt,
                   5195:  * gt, apos, quot.  The declaration of a parameter entity must precede
                   5196:  * any reference to it.  Similarly, the declaration of a general entity
                   5197:  * must precede any reference to it which appears in a default value in an
                   5198:  * attribute-list declaration. Note that if entities are declared in the
                   5199:  * external subset or in external parameter entities, a non-validating
                   5200:  * processor is not obligated to read and process their declarations;
                   5201:  * for such documents, the rule that an entity must be declared is a
                   5202:  * well-formedness constraint only if standalone='yes'.
                   5203:  *
                   5204:  * [ WFC: Parsed Entity ]
                   5205:  * An entity reference must not contain the name of an unparsed entity
                   5206:  *
                   5207:  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
                   5208:  * is updated to the current location in the string.
                   5209:  */
                   5210: xmlEntityPtr
                   5211: xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
                   5212:     xmlChar *name;
                   5213:     const xmlChar *ptr;
                   5214:     xmlChar cur;
                   5215:     xmlEntityPtr ent = NULL;
                   5216: 
                   5217:     GROW;
                   5218:     
                   5219:     if ((str == NULL) || (*str == NULL)) return(NULL); /* !!! */
                   5220:     ptr = *str;
                   5221:     cur = *ptr;
                   5222:     if (cur == '&') {
                   5223:         ptr++;
                   5224:        cur = *ptr;
                   5225:         name = xmlParseStringName(ctxt, &ptr);
                   5226:        if (name == NULL) {
                   5227:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5228:                ctxt->sax->error(ctxt->userData,
                   5229:                                 "xmlParseEntityRef: no name\n");
                   5230:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
                   5231:            ctxt->wellFormed = 0;
                   5232:        } else {
                   5233:            if (CUR == ';') {
                   5234:                NEXT;
                   5235:                /*
                   5236:                 * Ask first SAX for entity resolution, otherwise try the
                   5237:                 * predefined set.
                   5238:                 */
                   5239:                if (ctxt->sax != NULL) {
                   5240:                    if (ctxt->sax->getEntity != NULL)
                   5241:                        ent = ctxt->sax->getEntity(ctxt->userData, name);
                   5242:                    if (ent == NULL)
                   5243:                        ent = xmlGetPredefinedEntity(name);
                   5244:                }
                   5245:                /*
                   5246:                 * [ WFC: Entity Declared ]
                   5247:                 * In a document without any DTD, a document with only an
                   5248:                 * internal DTD subset which contains no parameter entity
                   5249:                 * references, or a document with "standalone='yes'", the
                   5250:                 * Name given in the entity reference must match that in an
                   5251:                 * entity declaration, except that well-formed documents
                   5252:                 * need not declare any of the following entities: amp, lt,
                   5253:                 * gt, apos, quot.
                   5254:                 * The declaration of a parameter entity must precede any
                   5255:                 * reference to it.
                   5256:                 * Similarly, the declaration of a general entity must
                   5257:                 * precede any reference to it which appears in a default
                   5258:                 * value in an attribute-list declaration. Note that if
                   5259:                 * entities are declared in the external subset or in
                   5260:                 * external parameter entities, a non-validating processor
                   5261:                 * is not obligated to read and process their declarations;
                   5262:                 * for such documents, the rule that an entity must be
                   5263:                 * declared is a well-formedness constraint only if
                   5264:                 * standalone='yes'. 
                   5265:                 */
                   5266:                if (ent == NULL) {
                   5267:                    if ((ctxt->standalone == 1) ||
                   5268:                        ((ctxt->hasExternalSubset == 0) &&
                   5269:                         (ctxt->hasPErefs == 0))) {
                   5270:                        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5271:                            ctxt->sax->error(ctxt->userData, 
                   5272:                                 "Entity '%s' not defined\n", name);
                   5273:                        ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
                   5274:                        ctxt->wellFormed = 0;
                   5275:                    } else {
                   5276:                        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   5277:                            ctxt->sax->warning(ctxt->userData, 
                   5278:                                 "Entity '%s' not defined\n", name);
                   5279:                        ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
                   5280:                    }
                   5281:                }
                   5282: 
                   5283:                /*
                   5284:                 * [ WFC: Parsed Entity ]
                   5285:                 * An entity reference must not contain the name of an
                   5286:                 * unparsed entity
                   5287:                 */
                   5288:                else if (ent->type == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
                   5289:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5290:                        ctxt->sax->error(ctxt->userData, 
                   5291:                             "Entity reference to unparsed entity %s\n", name);
                   5292:                    ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
                   5293:                    ctxt->wellFormed = 0;
                   5294:                }
                   5295: 
                   5296:                /*
                   5297:                 * [ WFC: No External Entity References ]
                   5298:                 * Attribute values cannot contain direct or indirect
                   5299:                 * entity references to external entities.
                   5300:                 */
                   5301:                else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   5302:                         (ent->type == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
                   5303:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5304:                        ctxt->sax->error(ctxt->userData, 
                   5305:                     "Attribute references external entity '%s'\n", name);
                   5306:                    ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
                   5307:                    ctxt->wellFormed = 0;
                   5308:                }
                   5309:                /*
                   5310:                 * [ WFC: No < in Attribute Values ]
                   5311:                 * The replacement text of any entity referred to directly or
                   5312:                 * indirectly in an attribute value (other than "&lt;") must
                   5313:                 * not contain a <. 
                   5314:                 */
                   5315:                else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   5316:                         (ent != NULL) &&
                   5317:                         (xmlStrcmp(ent->name, BAD_CAST "lt")) &&
                   5318:                         (ent->content != NULL) &&
                   5319:                         (xmlStrchr(ent->content, '<'))) {
                   5320:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5321:                        ctxt->sax->error(ctxt->userData, 
                   5322:         "'<' in entity '%s' is not allowed in attributes values\n", name);
                   5323:                    ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
                   5324:                    ctxt->wellFormed = 0;
                   5325:                }
                   5326: 
                   5327:                /*
                   5328:                 * Internal check, no parameter entities here ...
                   5329:                 */
                   5330:                else {
                   5331:                    switch (ent->type) {
                   5332:                        case XML_INTERNAL_PARAMETER_ENTITY:
                   5333:                        case XML_EXTERNAL_PARAMETER_ENTITY:
                   5334:                        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5335:                            ctxt->sax->error(ctxt->userData, 
                   5336:                     "Attempt to reference the parameter entity '%s'\n", name);
                   5337:                        ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
                   5338:                        ctxt->wellFormed = 0;
                   5339:                        break;
                   5340:                    }
                   5341:                }
                   5342: 
                   5343:                /*
                   5344:                 * [ WFC: No Recursion ]
                   5345:                 * TODO A parsed entity must not contain a recursive reference
                   5346:                 * to itself, either directly or indirectly. 
                   5347:                 */
                   5348: 
                   5349:            } else {
                   5350:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5351:                    ctxt->sax->error(ctxt->userData,
                   5352:                                     "xmlParseEntityRef: expecting ';'\n");
                   5353:                ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
                   5354:                ctxt->wellFormed = 0;
                   5355:            }
                   5356:            xmlFree(name);
                   5357:        }
                   5358:     }
                   5359:     return(ent);
                   5360: }
1.24      daniel   5361: 
1.50      daniel   5362: /**
                   5363:  * xmlParsePEReference:
                   5364:  * @ctxt:  an XML parser context
                   5365:  *
                   5366:  * parse PEReference declarations
1.77      daniel   5367:  * The entity content is handled directly by pushing it's content as
                   5368:  * a new input stream.
1.22      daniel   5369:  *
                   5370:  * [69] PEReference ::= '%' Name ';'
1.68      daniel   5371:  *
1.98      daniel   5372:  * [ WFC: No Recursion ]
                   5373:  * TODO A parsed entity must not contain a recursive
                   5374:  * reference to itself, either directly or indirectly. 
                   5375:  *
                   5376:  * [ WFC: Entity Declared ]
                   5377:  * In a document without any DTD, a document with only an internal DTD
                   5378:  * subset which contains no parameter entity references, or a document
                   5379:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   5380:  * entity must precede any reference to it...
                   5381:  *
                   5382:  * [ VC: Entity Declared ]
                   5383:  * In a document with an external subset or external parameter entities
                   5384:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   5385:  * must precede any reference to it...
                   5386:  *
                   5387:  * [ WFC: In DTD ]
                   5388:  * Parameter-entity references may only appear in the DTD.
                   5389:  * NOTE: misleading but this is handled.
1.22      daniel   5390:  */
1.77      daniel   5391: void
1.55      daniel   5392: xmlParsePEReference(xmlParserCtxtPtr ctxt) {
1.123     daniel   5393:     xmlChar *name;
1.72      daniel   5394:     xmlEntityPtr entity = NULL;
1.50      daniel   5395:     xmlParserInputPtr input;
1.22      daniel   5396: 
1.40      daniel   5397:     if (CUR == '%') {
                   5398:         NEXT;
1.22      daniel   5399:         name = xmlParseName(ctxt);
                   5400:        if (name == NULL) {
1.55      daniel   5401:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   5402:                ctxt->sax->error(ctxt->userData,
                   5403:                                 "xmlParsePEReference: no name\n");
1.123     daniel   5404:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.59      daniel   5405:            ctxt->wellFormed = 0;
1.22      daniel   5406:        } else {
1.40      daniel   5407:            if (CUR == ';') {
                   5408:                NEXT;
1.98      daniel   5409:                if ((ctxt->sax != NULL) &&
                   5410:                    (ctxt->sax->getParameterEntity != NULL))
                   5411:                    entity = ctxt->sax->getParameterEntity(ctxt->userData,
                   5412:                                                           name);
1.45      daniel   5413:                if (entity == NULL) {
1.98      daniel   5414:                    /*
                   5415:                     * [ WFC: Entity Declared ]
                   5416:                     * In a document without any DTD, a document with only an
                   5417:                     * internal DTD subset which contains no parameter entity
                   5418:                     * references, or a document with "standalone='yes'", ...
                   5419:                     * ... The declaration of a parameter entity must precede
                   5420:                     * any reference to it...
                   5421:                     */
                   5422:                    if ((ctxt->standalone == 1) ||
                   5423:                        ((ctxt->hasExternalSubset == 0) &&
                   5424:                         (ctxt->hasPErefs == 0))) {
                   5425:                        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5426:                            ctxt->sax->error(ctxt->userData,
                   5427:                             "PEReference: %%%s; not found\n", name);
1.123     daniel   5428:                        ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
1.98      daniel   5429:                        ctxt->wellFormed = 0;
                   5430:                    } else {
                   5431:                        /*
                   5432:                         * [ VC: Entity Declared ]
                   5433:                         * In a document with an external subset or external
                   5434:                         * parameter entities with "standalone='no'", ...
                   5435:                         * ... The declaration of a parameter entity must precede
                   5436:                         * any reference to it...
                   5437:                         */
                   5438:                        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   5439:                            ctxt->sax->warning(ctxt->userData,
                   5440:                             "PEReference: %%%s; not found\n", name);
                   5441:                        ctxt->valid = 0;
                   5442:                    }
1.50      daniel   5443:                } else {
1.98      daniel   5444:                    /*
                   5445:                     * Internal checking in case the entity quest barfed
                   5446:                     */
                   5447:                    if ((entity->type != XML_INTERNAL_PARAMETER_ENTITY) &&
                   5448:                        (entity->type != XML_EXTERNAL_PARAMETER_ENTITY)) {
                   5449:                        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   5450:                            ctxt->sax->warning(ctxt->userData,
                   5451:                         "Internal: %%%s; is not a parameter entity\n", name);
                   5452:                    } else {
                   5453:                        input = xmlNewEntityInputStream(ctxt, entity);
                   5454:                        xmlPushInput(ctxt, input);
                   5455:                    }
1.45      daniel   5456:                }
1.98      daniel   5457:                ctxt->hasPErefs = 1;
1.22      daniel   5458:            } else {
1.55      daniel   5459:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5460:                    ctxt->sax->error(ctxt->userData,
1.59      daniel   5461:                                     "xmlParsePEReference: expecting ';'\n");
1.123     daniel   5462:                ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
1.59      daniel   5463:                ctxt->wellFormed = 0;
1.22      daniel   5464:            }
1.119     daniel   5465:            xmlFree(name);
1.3       veillard 5466:        }
                   5467:     }
                   5468: }
                   5469: 
1.50      daniel   5470: /**
1.135     daniel   5471:  * xmlParseStringPEReference:
                   5472:  * @ctxt:  an XML parser context
                   5473:  * @str:  a pointer to an index in the string
                   5474:  *
                   5475:  * parse PEReference declarations
                   5476:  *
                   5477:  * [69] PEReference ::= '%' Name ';'
                   5478:  *
                   5479:  * [ WFC: No Recursion ]
                   5480:  * TODO A parsed entity must not contain a recursive
                   5481:  * reference to itself, either directly or indirectly. 
                   5482:  *
                   5483:  * [ WFC: Entity Declared ]
                   5484:  * In a document without any DTD, a document with only an internal DTD
                   5485:  * subset which contains no parameter entity references, or a document
                   5486:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   5487:  * entity must precede any reference to it...
                   5488:  *
                   5489:  * [ VC: Entity Declared ]
                   5490:  * In a document with an external subset or external parameter entities
                   5491:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   5492:  * must precede any reference to it...
                   5493:  *
                   5494:  * [ WFC: In DTD ]
                   5495:  * Parameter-entity references may only appear in the DTD.
                   5496:  * NOTE: misleading but this is handled.
                   5497:  *
                   5498:  * Returns the string of the entity content.
                   5499:  *         str is updated to the current value of the index
                   5500:  */
                   5501: xmlEntityPtr
                   5502: xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
                   5503:     const xmlChar *ptr;
                   5504:     xmlChar cur;
                   5505:     xmlChar *name;
                   5506:     xmlEntityPtr entity = NULL;
                   5507: 
                   5508:     if ((str == NULL) || (*str == NULL)) return(NULL);
                   5509:     ptr = *str;
                   5510:     cur = *ptr;
                   5511:     if (cur == '%') {
                   5512:         ptr++;
                   5513:        cur = *ptr;
                   5514:         name = xmlParseStringName(ctxt, &ptr);
                   5515:        if (name == NULL) {
                   5516:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5517:                ctxt->sax->error(ctxt->userData,
                   5518:                                 "xmlParseStringPEReference: no name\n");
                   5519:            ctxt->errNo = XML_ERR_NAME_REQUIRED;
                   5520:            ctxt->wellFormed = 0;
                   5521:        } else {
                   5522:            cur = *ptr;
                   5523:            if (cur == ';') {
                   5524:                ptr++;
                   5525:                cur = *ptr;
                   5526:                if ((ctxt->sax != NULL) &&
                   5527:                    (ctxt->sax->getParameterEntity != NULL))
                   5528:                    entity = ctxt->sax->getParameterEntity(ctxt->userData,
                   5529:                                                           name);
                   5530:                if (entity == NULL) {
                   5531:                    /*
                   5532:                     * [ WFC: Entity Declared ]
                   5533:                     * In a document without any DTD, a document with only an
                   5534:                     * internal DTD subset which contains no parameter entity
                   5535:                     * references, or a document with "standalone='yes'", ...
                   5536:                     * ... The declaration of a parameter entity must precede
                   5537:                     * any reference to it...
                   5538:                     */
                   5539:                    if ((ctxt->standalone == 1) ||
                   5540:                        ((ctxt->hasExternalSubset == 0) &&
                   5541:                         (ctxt->hasPErefs == 0))) {
                   5542:                        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5543:                            ctxt->sax->error(ctxt->userData,
                   5544:                             "PEReference: %%%s; not found\n", name);
                   5545:                        ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
                   5546:                        ctxt->wellFormed = 0;
                   5547:                    } else {
                   5548:                        /*
                   5549:                         * [ VC: Entity Declared ]
                   5550:                         * In a document with an external subset or external
                   5551:                         * parameter entities with "standalone='no'", ...
                   5552:                         * ... The declaration of a parameter entity must
                   5553:                         * precede any reference to it...
                   5554:                         */
                   5555:                        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   5556:                            ctxt->sax->warning(ctxt->userData,
                   5557:                             "PEReference: %%%s; not found\n", name);
                   5558:                        ctxt->valid = 0;
                   5559:                    }
                   5560:                } else {
                   5561:                    /*
                   5562:                     * Internal checking in case the entity quest barfed
                   5563:                     */
                   5564:                    if ((entity->type != XML_INTERNAL_PARAMETER_ENTITY) &&
                   5565:                        (entity->type != XML_EXTERNAL_PARAMETER_ENTITY)) {
                   5566:                        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                   5567:                            ctxt->sax->warning(ctxt->userData,
                   5568:                         "Internal: %%%s; is not a parameter entity\n", name);
                   5569:                    }
                   5570:                }
                   5571:                ctxt->hasPErefs = 1;
                   5572:            } else {
                   5573:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5574:                    ctxt->sax->error(ctxt->userData,
                   5575:                                     "xmlParseStringPEReference: expecting ';'\n");
                   5576:                ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
                   5577:                ctxt->wellFormed = 0;
                   5578:            }
                   5579:            xmlFree(name);
                   5580:        }
                   5581:     }
                   5582:     *str = ptr;
                   5583:     return(entity);
                   5584: }
                   5585: 
                   5586: /**
1.50      daniel   5587:  * xmlParseDocTypeDecl :
                   5588:  * @ctxt:  an XML parser context
                   5589:  *
                   5590:  * parse a DOCTYPE declaration
1.21      daniel   5591:  *
1.22      daniel   5592:  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
                   5593:  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
1.98      daniel   5594:  *
                   5595:  * [ VC: Root Element Type ]
1.99      daniel   5596:  * The Name in the document type declaration must match the element
1.98      daniel   5597:  * type of the root element. 
1.21      daniel   5598:  */
                   5599: 
1.55      daniel   5600: void
                   5601: xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   5602:     xmlChar *name;
                   5603:     xmlChar *ExternalID = NULL;
                   5604:     xmlChar *URI = NULL;
1.21      daniel   5605: 
                   5606:     /*
                   5607:      * We know that '<!DOCTYPE' has been detected.
                   5608:      */
1.40      daniel   5609:     SKIP(9);
1.21      daniel   5610: 
1.42      daniel   5611:     SKIP_BLANKS;
1.21      daniel   5612: 
                   5613:     /*
                   5614:      * Parse the DOCTYPE name.
                   5615:      */
                   5616:     name = xmlParseName(ctxt);
                   5617:     if (name == NULL) {
1.55      daniel   5618:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   5619:            ctxt->sax->error(ctxt->userData, 
                   5620:                "xmlParseDocTypeDecl : no DOCTYPE name !\n");
1.59      daniel   5621:        ctxt->wellFormed = 0;
1.123     daniel   5622:        ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.21      daniel   5623:     }
                   5624: 
1.42      daniel   5625:     SKIP_BLANKS;
1.21      daniel   5626: 
                   5627:     /*
1.22      daniel   5628:      * Check for SystemID and ExternalID
                   5629:      */
1.67      daniel   5630:     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
1.98      daniel   5631: 
                   5632:     if ((URI != NULL) || (ExternalID != NULL)) {
                   5633:         ctxt->hasExternalSubset = 1;
                   5634:     }
                   5635: 
1.42      daniel   5636:     SKIP_BLANKS;
1.36      daniel   5637: 
1.76      daniel   5638:     /*
                   5639:      * NOTE: the SAX callback may try to fetch the external subset
                   5640:      *       entity and fill it up !
                   5641:      */
1.72      daniel   5642:     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL))
1.74      daniel   5643:        ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
1.22      daniel   5644: 
                   5645:     /*
1.140     daniel   5646:      * Cleanup
                   5647:      */
                   5648:     if (URI != NULL) xmlFree(URI);
                   5649:     if (ExternalID != NULL) xmlFree(ExternalID);
                   5650:     if (name != NULL) xmlFree(name);
                   5651: 
                   5652:     /*
                   5653:      * Is there any internal subset declarations ?
                   5654:      * they are handled separately in xmlParseInternalSubset()
                   5655:      */
                   5656:     if (CUR == '[')
                   5657:        return;
                   5658: 
                   5659:     /*
                   5660:      * We should be at the end of the DOCTYPE declaration.
                   5661:      */
                   5662:     if (CUR != '>') {
                   5663:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   5664:            ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
                   5665:        ctxt->wellFormed = 0;
                   5666:        ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
                   5667:     }
                   5668:     NEXT;
                   5669: }
                   5670: 
                   5671: /**
                   5672:  * xmlParseInternalsubset :
                   5673:  * @ctxt:  an XML parser context
                   5674:  *
                   5675:  * parse the internal subset declaration
                   5676:  *
                   5677:  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
                   5678:  */
                   5679: 
                   5680: void
                   5681: xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
                   5682:     /*
1.22      daniel   5683:      * Is there any DTD definition ?
                   5684:      */
1.40      daniel   5685:     if (CUR == '[') {
1.96      daniel   5686:         ctxt->instate = XML_PARSER_DTD;
1.40      daniel   5687:         NEXT;
1.22      daniel   5688:        /*
                   5689:         * Parse the succession of Markup declarations and 
                   5690:         * PEReferences.
                   5691:         * Subsequence (markupdecl | PEReference | S)*
                   5692:         */
1.40      daniel   5693:        while (CUR != ']') {
1.123     daniel   5694:            const xmlChar *check = CUR_PTR;
1.115     daniel   5695:            int cons = ctxt->input->consumed;
1.22      daniel   5696: 
1.42      daniel   5697:            SKIP_BLANKS;
1.22      daniel   5698:            xmlParseMarkupDecl(ctxt);
1.50      daniel   5699:            xmlParsePEReference(ctxt);
1.22      daniel   5700: 
1.115     daniel   5701:            /*
                   5702:             * Pop-up of finished entities.
                   5703:             */
                   5704:            while ((CUR == 0) && (ctxt->inputNr > 1))
                   5705:                xmlPopInput(ctxt);
                   5706: 
1.118     daniel   5707:            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
1.55      daniel   5708:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5709:                    ctxt->sax->error(ctxt->userData, 
1.140     daniel   5710:             "xmlParseInternalSubset: error detected in Markup declaration\n");
1.59      daniel   5711:                ctxt->wellFormed = 0;
1.123     daniel   5712:                ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.22      daniel   5713:                break;
                   5714:            }
                   5715:        }
1.40      daniel   5716:        if (CUR == ']') NEXT;
1.22      daniel   5717:     }
                   5718: 
                   5719:     /*
                   5720:      * We should be at the end of the DOCTYPE declaration.
1.21      daniel   5721:      */
1.40      daniel   5722:     if (CUR != '>') {
1.55      daniel   5723:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5724:            ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n");
1.59      daniel   5725:        ctxt->wellFormed = 0;
1.123     daniel   5726:        ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
1.21      daniel   5727:     }
1.40      daniel   5728:     NEXT;
1.21      daniel   5729: }
                   5730: 
1.50      daniel   5731: /**
                   5732:  * xmlParseAttribute:
                   5733:  * @ctxt:  an XML parser context
1.123     daniel   5734:  * @value:  a xmlChar ** used to store the value of the attribute
1.50      daniel   5735:  *
                   5736:  * parse an attribute
1.3       veillard 5737:  *
1.22      daniel   5738:  * [41] Attribute ::= Name Eq AttValue
                   5739:  *
1.98      daniel   5740:  * [ WFC: No External Entity References ]
                   5741:  * Attribute values cannot contain direct or indirect entity references
                   5742:  * to external entities.
                   5743:  *
                   5744:  * [ WFC: No < in Attribute Values ]
                   5745:  * The replacement text of any entity referred to directly or indirectly in
                   5746:  * an attribute value (other than "&lt;") must not contain a <. 
                   5747:  * 
                   5748:  * [ VC: Attribute Value Type ]
1.117     daniel   5749:  * The attribute must have been declared; the value must be of the type
1.99      daniel   5750:  * declared for it.
1.98      daniel   5751:  *
1.22      daniel   5752:  * [25] Eq ::= S? '=' S?
                   5753:  *
1.29      daniel   5754:  * With namespace:
                   5755:  *
                   5756:  * [NS 11] Attribute ::= QName Eq AttValue
1.43      daniel   5757:  *
                   5758:  * Also the case QName == xmlns:??? is handled independently as a namespace
                   5759:  * definition.
1.69      daniel   5760:  *
1.72      daniel   5761:  * Returns the attribute name, and the value in *value.
1.3       veillard 5762:  */
                   5763: 
1.123     daniel   5764: xmlChar *
                   5765: xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
                   5766:     xmlChar *name, *val;
1.3       veillard 5767: 
1.72      daniel   5768:     *value = NULL;
                   5769:     name = xmlParseName(ctxt);
1.22      daniel   5770:     if (name == NULL) {
1.55      daniel   5771:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5772:            ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
1.59      daniel   5773:        ctxt->wellFormed = 0;
1.123     daniel   5774:        ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.52      daniel   5775:         return(NULL);
1.3       veillard 5776:     }
                   5777: 
                   5778:     /*
1.29      daniel   5779:      * read the value
1.3       veillard 5780:      */
1.42      daniel   5781:     SKIP_BLANKS;
1.40      daniel   5782:     if (CUR == '=') {
                   5783:         NEXT;
1.42      daniel   5784:        SKIP_BLANKS;
1.72      daniel   5785:        val = xmlParseAttValue(ctxt);
1.96      daniel   5786:        ctxt->instate = XML_PARSER_CONTENT;
1.29      daniel   5787:     } else {
1.55      daniel   5788:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5789:            ctxt->sax->error(ctxt->userData,
1.59      daniel   5790:               "Specification mandate value for attribute %s\n", name);
1.123     daniel   5791:        ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
1.59      daniel   5792:        ctxt->wellFormed = 0;
1.52      daniel   5793:        return(NULL);
1.43      daniel   5794:     }
                   5795: 
1.72      daniel   5796:     *value = val;
                   5797:     return(name);
1.3       veillard 5798: }
                   5799: 
1.50      daniel   5800: /**
                   5801:  * xmlParseStartTag:
                   5802:  * @ctxt:  an XML parser context
                   5803:  * 
                   5804:  * parse a start of tag either for rule element or
                   5805:  * EmptyElement. In both case we don't parse the tag closing chars.
1.27      daniel   5806:  *
                   5807:  * [40] STag ::= '<' Name (S Attribute)* S? '>'
                   5808:  *
1.98      daniel   5809:  * [ WFC: Unique Att Spec ]
                   5810:  * No attribute name may appear more than once in the same start-tag or
                   5811:  * empty-element tag. 
                   5812:  *
1.29      daniel   5813:  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
                   5814:  *
1.98      daniel   5815:  * [ WFC: Unique Att Spec ]
                   5816:  * No attribute name may appear more than once in the same start-tag or
                   5817:  * empty-element tag. 
                   5818:  *
1.29      daniel   5819:  * With namespace:
                   5820:  *
                   5821:  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
                   5822:  *
                   5823:  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
1.83      daniel   5824:  *
1.129     daniel   5825:  * Returne the element name parsed
1.2       veillard 5826:  */
                   5827: 
1.123     daniel   5828: xmlChar *
1.69      daniel   5829: xmlParseStartTag(xmlParserCtxtPtr ctxt) {
1.123     daniel   5830:     xmlChar *name;
                   5831:     xmlChar *attname;
                   5832:     xmlChar *attvalue;
                   5833:     const xmlChar **atts = NULL;
1.72      daniel   5834:     int nbatts = 0;
                   5835:     int maxatts = 0;
                   5836:     int i;
1.2       veillard 5837: 
1.83      daniel   5838:     if (CUR != '<') return(NULL);
1.40      daniel   5839:     NEXT;
1.3       veillard 5840: 
1.72      daniel   5841:     name = xmlParseName(ctxt);
1.59      daniel   5842:     if (name == NULL) {
                   5843:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5844:            ctxt->sax->error(ctxt->userData, 
1.59      daniel   5845:             "xmlParseStartTag: invalid element name\n");
1.123     daniel   5846:        ctxt->errNo = XML_ERR_NAME_REQUIRED;
1.59      daniel   5847:        ctxt->wellFormed = 0;
1.83      daniel   5848:         return(NULL);
1.50      daniel   5849:     }
                   5850: 
                   5851:     /*
1.3       veillard 5852:      * Now parse the attributes, it ends up with the ending
                   5853:      *
                   5854:      * (S Attribute)* S?
                   5855:      */
1.42      daniel   5856:     SKIP_BLANKS;
1.91      daniel   5857:     GROW;
1.40      daniel   5858:     while ((IS_CHAR(CUR)) &&
                   5859:            (CUR != '>') && 
                   5860:           ((CUR != '/') || (NXT(1) != '>'))) {
1.123     daniel   5861:        const xmlChar *q = CUR_PTR;
1.91      daniel   5862:        int cons = ctxt->input->consumed;
1.29      daniel   5863: 
1.72      daniel   5864:        attname = xmlParseAttribute(ctxt, &attvalue);
                   5865:         if ((attname != NULL) && (attvalue != NULL)) {
                   5866:            /*
1.98      daniel   5867:             * [ WFC: Unique Att Spec ]
                   5868:             * No attribute name may appear more than once in the same
                   5869:             * start-tag or empty-element tag. 
1.72      daniel   5870:             */
                   5871:            for (i = 0; i < nbatts;i += 2) {
                   5872:                if (!xmlStrcmp(atts[i], attname)) {
                   5873:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.98      daniel   5874:                        ctxt->sax->error(ctxt->userData,
                   5875:                                "Attribute %s redefined\n",
                   5876:                                         attname);
1.72      daniel   5877:                    ctxt->wellFormed = 0;
1.123     daniel   5878:                    ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
1.119     daniel   5879:                    xmlFree(attname);
                   5880:                    xmlFree(attvalue);
1.98      daniel   5881:                    goto failed;
1.72      daniel   5882:                }
                   5883:            }
                   5884: 
                   5885:            /*
                   5886:             * Add the pair to atts
                   5887:             */
                   5888:            if (atts == NULL) {
                   5889:                maxatts = 10;
1.123     daniel   5890:                atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
1.72      daniel   5891:                if (atts == NULL) {
1.86      daniel   5892:                    fprintf(stderr, "malloc of %ld byte failed\n",
1.123     daniel   5893:                            maxatts * (long)sizeof(xmlChar *));
1.83      daniel   5894:                    return(NULL);
1.72      daniel   5895:                }
1.127     daniel   5896:            } else if (nbatts + 4 > maxatts) {
1.72      daniel   5897:                maxatts *= 2;
1.123     daniel   5898:                atts = (const xmlChar **) xmlRealloc(atts,
                   5899:                                                  maxatts * sizeof(xmlChar *));
1.72      daniel   5900:                if (atts == NULL) {
1.86      daniel   5901:                    fprintf(stderr, "realloc of %ld byte failed\n",
1.123     daniel   5902:                            maxatts * (long)sizeof(xmlChar *));
1.83      daniel   5903:                    return(NULL);
1.72      daniel   5904:                }
                   5905:            }
                   5906:            atts[nbatts++] = attname;
                   5907:            atts[nbatts++] = attvalue;
                   5908:            atts[nbatts] = NULL;
                   5909:            atts[nbatts + 1] = NULL;
                   5910:        }
                   5911: 
1.116     daniel   5912: failed:     
1.42      daniel   5913:        SKIP_BLANKS;
1.91      daniel   5914:         if ((cons == ctxt->input->consumed) && (q == CUR_PTR)) {
1.55      daniel   5915:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5916:                ctxt->sax->error(ctxt->userData, 
1.31      daniel   5917:                 "xmlParseStartTag: problem parsing attributes\n");
1.123     daniel   5918:            ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.59      daniel   5919:            ctxt->wellFormed = 0;
1.29      daniel   5920:            break;
1.3       veillard 5921:        }
1.91      daniel   5922:         GROW;
1.3       veillard 5923:     }
                   5924: 
1.43      daniel   5925:     /*
1.72      daniel   5926:      * SAX: Start of Element !
1.43      daniel   5927:      */
1.72      daniel   5928:     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
1.74      daniel   5929:         ctxt->sax->startElement(ctxt->userData, name, atts);
1.43      daniel   5930: 
1.72      daniel   5931:     if (atts != NULL) {
1.123     daniel   5932:         for (i = 0;i < nbatts;i++) xmlFree((xmlChar *) atts[i]);
1.119     daniel   5933:        xmlFree(atts);
1.72      daniel   5934:     }
1.83      daniel   5935:     return(name);
1.3       veillard 5936: }
                   5937: 
1.50      daniel   5938: /**
                   5939:  * xmlParseEndTag:
                   5940:  * @ctxt:  an XML parser context
                   5941:  *
                   5942:  * parse an end of tag
1.27      daniel   5943:  *
                   5944:  * [42] ETag ::= '</' Name S? '>'
1.29      daniel   5945:  *
                   5946:  * With namespace
                   5947:  *
1.72      daniel   5948:  * [NS 9] ETag ::= '</' QName S? '>'
1.7       veillard 5949:  */
                   5950: 
1.55      daniel   5951: void
1.140     daniel   5952: xmlParseEndTag(xmlParserCtxtPtr ctxt) {
1.123     daniel   5953:     xmlChar *name;
1.140     daniel   5954:     xmlChar *oldname;
1.7       veillard 5955: 
1.91      daniel   5956:     GROW;
1.40      daniel   5957:     if ((CUR != '<') || (NXT(1) != '/')) {
1.55      daniel   5958:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5959:            ctxt->sax->error(ctxt->userData, "xmlParseEndTag: '</' not found\n");
1.59      daniel   5960:        ctxt->wellFormed = 0;
1.123     daniel   5961:        ctxt->errNo = XML_ERR_LTSLASH_REQUIRED;
1.27      daniel   5962:        return;
                   5963:     }
1.40      daniel   5964:     SKIP(2);
1.7       veillard 5965: 
1.72      daniel   5966:     name = xmlParseName(ctxt);
1.7       veillard 5967: 
                   5968:     /*
                   5969:      * We should definitely be at the ending "S? '>'" part
                   5970:      */
1.91      daniel   5971:     GROW;
1.42      daniel   5972:     SKIP_BLANKS;
1.40      daniel   5973:     if ((!IS_CHAR(CUR)) || (CUR != '>')) {
1.55      daniel   5974:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   5975:            ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
1.123     daniel   5976:        ctxt->errNo = XML_ERR_GT_REQUIRED;
1.59      daniel   5977:        ctxt->wellFormed = 0;
1.7       veillard 5978:     } else
1.40      daniel   5979:        NEXT;
1.7       veillard 5980: 
1.72      daniel   5981:     /*
1.98      daniel   5982:      * [ WFC: Element Type Match ]
                   5983:      * The Name in an element's end-tag must match the element type in the
                   5984:      * start-tag. 
                   5985:      *
1.83      daniel   5986:      */
1.147     daniel   5987:     if ((name == NULL) || (ctxt->name == NULL) ||
                   5988:         (xmlStrcmp(name, ctxt->name))) {
                   5989:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
                   5990:            if ((name != NULL) && (ctxt->name != NULL)) {
                   5991:                ctxt->sax->error(ctxt->userData,
                   5992:                     "Opening and ending tag mismatch: %s and %s\n",
                   5993:                                 ctxt->name, name);
                   5994:             } else if (ctxt->name != NULL) {
                   5995:                ctxt->sax->error(ctxt->userData,
                   5996:                     "Ending tag eror for: %s\n", ctxt->name);
                   5997:            } else {
                   5998:                ctxt->sax->error(ctxt->userData,
                   5999:                     "Ending tag error: internal error ???\n");
                   6000:            }
1.122     daniel   6001: 
1.147     daniel   6002:        }     
1.123     daniel   6003:        ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH;
1.83      daniel   6004:        ctxt->wellFormed = 0;
                   6005:     }
                   6006: 
                   6007:     /*
1.72      daniel   6008:      * SAX: End of Tag
                   6009:      */
                   6010:     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
1.74      daniel   6011:         ctxt->sax->endElement(ctxt->userData, name);
1.72      daniel   6012: 
                   6013:     if (name != NULL)
1.119     daniel   6014:        xmlFree(name);
1.140     daniel   6015:     oldname = namePop(ctxt);
                   6016:     if (oldname != NULL) {
                   6017: #ifdef DEBUG_STACK
                   6018:        fprintf(stderr,"Close: popped %s\n", oldname);
                   6019: #endif
                   6020:        xmlFree(oldname);
                   6021:     }
1.7       veillard 6022:     return;
                   6023: }
                   6024: 
1.50      daniel   6025: /**
                   6026:  * xmlParseCDSect:
                   6027:  * @ctxt:  an XML parser context
                   6028:  * 
                   6029:  * Parse escaped pure raw content.
1.29      daniel   6030:  *
                   6031:  * [18] CDSect ::= CDStart CData CDEnd
                   6032:  *
                   6033:  * [19] CDStart ::= '<![CDATA['
                   6034:  *
                   6035:  * [20] Data ::= (Char* - (Char* ']]>' Char*))
                   6036:  *
                   6037:  * [21] CDEnd ::= ']]>'
1.3       veillard 6038:  */
1.55      daniel   6039: void
                   6040: xmlParseCDSect(xmlParserCtxtPtr ctxt) {
1.135     daniel   6041:     xmlChar *buf = NULL;
                   6042:     int len = 0;
1.140     daniel   6043:     int size = XML_PARSER_BUFFER_SIZE;
1.123     daniel   6044:     xmlChar r, s;
                   6045:     xmlChar cur;
1.3       veillard 6046: 
1.106     daniel   6047:     if ((NXT(0) == '<') && (NXT(1) == '!') &&
1.40      daniel   6048:        (NXT(2) == '[') && (NXT(3) == 'C') &&
                   6049:        (NXT(4) == 'D') && (NXT(5) == 'A') &&
                   6050:        (NXT(6) == 'T') && (NXT(7) == 'A') &&
                   6051:        (NXT(8) == '[')) {
                   6052:        SKIP(9);
1.29      daniel   6053:     } else
1.45      daniel   6054:         return;
1.109     daniel   6055: 
                   6056:     ctxt->instate = XML_PARSER_CDATA_SECTION;
1.40      daniel   6057:     if (!IS_CHAR(CUR)) {
1.55      daniel   6058:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6059:            ctxt->sax->error(ctxt->userData,
1.135     daniel   6060:                             "CData section not finished\n");
1.59      daniel   6061:        ctxt->wellFormed = 0;
1.123     daniel   6062:        ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
1.109     daniel   6063:        ctxt->instate = XML_PARSER_CONTENT;
1.45      daniel   6064:         return;
1.3       veillard 6065:     }
1.110     daniel   6066:     r = CUR;
1.91      daniel   6067:     NEXT;
1.40      daniel   6068:     if (!IS_CHAR(CUR)) {
1.55      daniel   6069:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6070:            ctxt->sax->error(ctxt->userData,
1.135     daniel   6071:                             "CData section not finished\n");
1.123     daniel   6072:        ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
1.59      daniel   6073:        ctxt->wellFormed = 0;
1.109     daniel   6074:        ctxt->instate = XML_PARSER_CONTENT;
1.45      daniel   6075:         return;
1.3       veillard 6076:     }
1.110     daniel   6077:     s = CUR;
1.91      daniel   6078:     NEXT;
1.108     veillard 6079:     cur = CUR;
1.135     daniel   6080:     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   6081:     if (buf == NULL) {
                   6082:        fprintf(stderr, "malloc of %d byte failed\n", size);
                   6083:        return;
                   6084:     }
1.108     veillard 6085:     while (IS_CHAR(cur) &&
1.110     daniel   6086:            ((r != ']') || (s != ']') || (cur != '>'))) {
1.135     daniel   6087:        if (len + 1 >= size) {
                   6088:            size *= 2;
                   6089:            buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   6090:            if (buf == NULL) {
                   6091:                fprintf(stderr, "realloc of %d byte failed\n", size);
                   6092:                return;
                   6093:            }
                   6094:        }
                   6095:        buf[len++] = r;
1.110     daniel   6096:        r = s;
                   6097:        s = cur;
                   6098:         NEXT;
1.108     veillard 6099:        cur = CUR;
1.3       veillard 6100:     }
1.135     daniel   6101:     buf[len] = 0;
1.109     daniel   6102:     ctxt->instate = XML_PARSER_CONTENT;
1.40      daniel   6103:     if (!IS_CHAR(CUR)) {
1.55      daniel   6104:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6105:            ctxt->sax->error(ctxt->userData,
1.135     daniel   6106:                             "CData section not finished\n%.50s\n", buf);
1.123     daniel   6107:        ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
1.59      daniel   6108:        ctxt->wellFormed = 0;
1.135     daniel   6109:        xmlFree(buf);
1.45      daniel   6110:         return;
1.3       veillard 6111:     }
1.107     daniel   6112:     NEXT;
1.16      daniel   6113: 
1.45      daniel   6114:     /*
1.135     daniel   6115:      * Ok the buffer is to be consumed as cdata.
1.45      daniel   6116:      */
                   6117:     if (ctxt->sax != NULL) {
1.107     daniel   6118:        if (ctxt->sax->cdataBlock != NULL)
1.135     daniel   6119:            ctxt->sax->cdataBlock(ctxt->userData, buf, len);
1.45      daniel   6120:     }
1.135     daniel   6121:     xmlFree(buf);
1.2       veillard 6122: }
                   6123: 
1.50      daniel   6124: /**
                   6125:  * xmlParseContent:
                   6126:  * @ctxt:  an XML parser context
                   6127:  *
                   6128:  * Parse a content:
1.2       veillard 6129:  *
1.27      daniel   6130:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
1.2       veillard 6131:  */
                   6132: 
1.55      daniel   6133: void
                   6134: xmlParseContent(xmlParserCtxtPtr ctxt) {
1.97      daniel   6135:     GROW;
1.40      daniel   6136:     while ((CUR != '<') || (NXT(1) != '/')) {
1.123     daniel   6137:        const xmlChar *test = CUR_PTR;
1.91      daniel   6138:        int cons = ctxt->input->consumed;
1.123     daniel   6139:        xmlChar tok = ctxt->token;
1.27      daniel   6140: 
                   6141:        /*
                   6142:         * First case : a Processing Instruction.
                   6143:         */
1.40      daniel   6144:        if ((CUR == '<') && (NXT(1) == '?')) {
1.27      daniel   6145:            xmlParsePI(ctxt);
                   6146:        }
1.72      daniel   6147: 
1.27      daniel   6148:        /*
                   6149:         * Second case : a CDSection
                   6150:         */
1.40      daniel   6151:        else if ((CUR == '<') && (NXT(1) == '!') &&
                   6152:            (NXT(2) == '[') && (NXT(3) == 'C') &&
                   6153:            (NXT(4) == 'D') && (NXT(5) == 'A') &&
                   6154:            (NXT(6) == 'T') && (NXT(7) == 'A') &&
                   6155:            (NXT(8) == '[')) {
1.45      daniel   6156:            xmlParseCDSect(ctxt);
1.27      daniel   6157:        }
1.72      daniel   6158: 
1.27      daniel   6159:        /*
                   6160:         * Third case :  a comment
                   6161:         */
1.40      daniel   6162:        else if ((CUR == '<') && (NXT(1) == '!') &&
                   6163:                 (NXT(2) == '-') && (NXT(3) == '-')) {
1.114     daniel   6164:            xmlParseComment(ctxt);
1.97      daniel   6165:            ctxt->instate = XML_PARSER_CONTENT;
1.27      daniel   6166:        }
1.72      daniel   6167: 
1.27      daniel   6168:        /*
                   6169:         * Fourth case :  a sub-element.
                   6170:         */
1.40      daniel   6171:        else if (CUR == '<') {
1.72      daniel   6172:            xmlParseElement(ctxt);
1.45      daniel   6173:        }
1.72      daniel   6174: 
1.45      daniel   6175:        /*
1.50      daniel   6176:         * Fifth case : a reference. If if has not been resolved,
                   6177:         *    parsing returns it's Name, create the node 
1.45      daniel   6178:         */
1.97      daniel   6179: 
1.45      daniel   6180:        else if (CUR == '&') {
1.77      daniel   6181:            xmlParseReference(ctxt);
1.27      daniel   6182:        }
1.72      daniel   6183: 
1.27      daniel   6184:        /*
                   6185:         * Last case, text. Note that References are handled directly.
                   6186:         */
                   6187:        else {
1.45      daniel   6188:            xmlParseCharData(ctxt, 0);
1.3       veillard 6189:        }
1.14      veillard 6190: 
1.91      daniel   6191:        GROW;
1.14      veillard 6192:        /*
1.45      daniel   6193:         * Pop-up of finished entities.
1.14      veillard 6194:         */
1.69      daniel   6195:        while ((CUR == 0) && (ctxt->inputNr > 1))
                   6196:            xmlPopInput(ctxt);
1.135     daniel   6197:        SHRINK;
1.45      daniel   6198: 
1.113     daniel   6199:        if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
                   6200:            (tok == ctxt->token)) {
1.55      daniel   6201:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6202:                ctxt->sax->error(ctxt->userData,
1.59      daniel   6203:                     "detected an error in element content\n");
1.123     daniel   6204:            ctxt->errNo = XML_ERR_INTERNAL_ERROR;
1.59      daniel   6205:            ctxt->wellFormed = 0;
1.29      daniel   6206:             break;
                   6207:        }
1.3       veillard 6208:     }
1.2       veillard 6209: }
                   6210: 
1.50      daniel   6211: /**
                   6212:  * xmlParseElement:
                   6213:  * @ctxt:  an XML parser context
                   6214:  *
                   6215:  * parse an XML element, this is highly recursive
1.26      daniel   6216:  *
                   6217:  * [39] element ::= EmptyElemTag | STag content ETag
                   6218:  *
1.98      daniel   6219:  * [ WFC: Element Type Match ]
                   6220:  * The Name in an element's end-tag must match the element type in the
                   6221:  * start-tag. 
                   6222:  *
                   6223:  * [ VC: Element Valid ]
1.117     daniel   6224:  * An element is valid if there is a declaration matching elementdecl
1.99      daniel   6225:  * where the Name matches the element type and one of the following holds:
                   6226:  *  - The declaration matches EMPTY and the element has no content.
                   6227:  *  - The declaration matches children and the sequence of child elements
                   6228:  *    belongs to the language generated by the regular expression in the
                   6229:  *    content model, with optional white space (characters matching the
                   6230:  *    nonterminal S) between each pair of child elements. 
                   6231:  *  - The declaration matches Mixed and the content consists of character
                   6232:  *    data and child elements whose types match names in the content model. 
                   6233:  *  - The declaration matches ANY, and the types of any child elements have
                   6234:  *    been declared.
1.2       veillard 6235:  */
1.26      daniel   6236: 
1.72      daniel   6237: void
1.69      daniel   6238: xmlParseElement(xmlParserCtxtPtr ctxt) {
1.123     daniel   6239:     const xmlChar *openTag = CUR_PTR;
                   6240:     xmlChar *name;
1.140     daniel   6241:     xmlChar *oldname;
1.32      daniel   6242:     xmlParserNodeInfo node_info;
1.118     daniel   6243:     xmlNodePtr ret;
1.2       veillard 6244: 
1.32      daniel   6245:     /* Capture start position */
1.118     daniel   6246:     if (ctxt->record_info) {
                   6247:         node_info.begin_pos = ctxt->input->consumed +
                   6248:                           (CUR_PTR - ctxt->input->base);
                   6249:        node_info.begin_line = ctxt->input->line;
                   6250:     }
1.32      daniel   6251: 
1.83      daniel   6252:     name = xmlParseStartTag(ctxt);
                   6253:     if (name == NULL) {
                   6254:         return;
                   6255:     }
1.140     daniel   6256:     namePush(ctxt, name);
1.118     daniel   6257:     ret = ctxt->node;
1.2       veillard 6258: 
                   6259:     /*
1.99      daniel   6260:      * [ VC: Root Element Type ]
                   6261:      * The Name in the document type declaration must match the element
                   6262:      * type of the root element. 
                   6263:      */
1.105     daniel   6264:     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
                   6265:         ctxt->node && (ctxt->node == ctxt->myDoc->root))
1.102     daniel   6266:         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1.99      daniel   6267: 
                   6268:     /*
1.2       veillard 6269:      * Check for an Empty Element.
                   6270:      */
1.40      daniel   6271:     if ((CUR == '/') && (NXT(1) == '>')) {
                   6272:         SKIP(2);
1.72      daniel   6273:        if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
1.83      daniel   6274:            ctxt->sax->endElement(ctxt->userData, name);
1.140     daniel   6275:        oldname = namePop(ctxt);
                   6276:        if (oldname != NULL) {
                   6277: #ifdef DEBUG_STACK
                   6278:            fprintf(stderr,"Close: popped %s\n", oldname);
                   6279: #endif
                   6280:            xmlFree(oldname);
                   6281:        }
1.72      daniel   6282:        return;
1.2       veillard 6283:     }
1.91      daniel   6284:     if (CUR == '>') {
                   6285:         NEXT;
                   6286:     } else {
1.55      daniel   6287:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6288:            ctxt->sax->error(ctxt->userData,
                   6289:                             "Couldn't find end of Start Tag\n%.30s\n",
1.57      daniel   6290:                             openTag);
1.59      daniel   6291:        ctxt->wellFormed = 0;
1.123     daniel   6292:        ctxt->errNo = XML_ERR_GT_REQUIRED;
1.45      daniel   6293: 
                   6294:        /*
                   6295:         * end of parsing of this node.
                   6296:         */
                   6297:        nodePop(ctxt);
1.140     daniel   6298:        oldname = namePop(ctxt);
                   6299:        if (oldname != NULL) {
                   6300: #ifdef DEBUG_STACK
                   6301:            fprintf(stderr,"Close: popped %s\n", oldname);
                   6302: #endif
                   6303:            xmlFree(oldname);
                   6304:        }
1.118     daniel   6305: 
                   6306:        /*
                   6307:         * Capture end position and add node
                   6308:         */
                   6309:        if ( ret != NULL && ctxt->record_info ) {
                   6310:           node_info.end_pos = ctxt->input->consumed +
                   6311:                              (CUR_PTR - ctxt->input->base);
                   6312:           node_info.end_line = ctxt->input->line;
                   6313:           node_info.node = ret;
                   6314:           xmlParserAddNodeInfo(ctxt, &node_info);
                   6315:        }
1.72      daniel   6316:        return;
1.2       veillard 6317:     }
                   6318: 
                   6319:     /*
                   6320:      * Parse the content of the element:
                   6321:      */
1.45      daniel   6322:     xmlParseContent(ctxt);
1.40      daniel   6323:     if (!IS_CHAR(CUR)) {
1.55      daniel   6324:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6325:            ctxt->sax->error(ctxt->userData,
1.57      daniel   6326:                 "Premature end of data in tag %.30s\n", openTag);
1.59      daniel   6327:        ctxt->wellFormed = 0;
1.123     daniel   6328:        ctxt->errNo = XML_ERR_TAG_NOT_FINISED;
1.45      daniel   6329: 
                   6330:        /*
                   6331:         * end of parsing of this node.
                   6332:         */
                   6333:        nodePop(ctxt);
1.140     daniel   6334:        oldname = namePop(ctxt);
                   6335:        if (oldname != NULL) {
                   6336: #ifdef DEBUG_STACK
                   6337:            fprintf(stderr,"Close: popped %s\n", oldname);
                   6338: #endif
                   6339:            xmlFree(oldname);
                   6340:        }
1.72      daniel   6341:        return;
1.2       veillard 6342:     }
                   6343: 
                   6344:     /*
1.27      daniel   6345:      * parse the end of tag: '</' should be here.
1.2       veillard 6346:      */
1.140     daniel   6347:     xmlParseEndTag(ctxt);
1.118     daniel   6348: 
                   6349:     /*
                   6350:      * Capture end position and add node
                   6351:      */
                   6352:     if ( ret != NULL && ctxt->record_info ) {
                   6353:        node_info.end_pos = ctxt->input->consumed +
                   6354:                           (CUR_PTR - ctxt->input->base);
                   6355:        node_info.end_line = ctxt->input->line;
                   6356:        node_info.node = ret;
                   6357:        xmlParserAddNodeInfo(ctxt, &node_info);
                   6358:     }
1.2       veillard 6359: }
                   6360: 
1.50      daniel   6361: /**
                   6362:  * xmlParseVersionNum:
                   6363:  * @ctxt:  an XML parser context
                   6364:  *
                   6365:  * parse the XML version value.
1.29      daniel   6366:  *
                   6367:  * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
1.68      daniel   6368:  *
                   6369:  * Returns the string giving the XML version number, or NULL
1.29      daniel   6370:  */
1.123     daniel   6371: xmlChar *
1.55      daniel   6372: xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
1.135     daniel   6373:     xmlChar *buf = NULL;
                   6374:     int len = 0;
                   6375:     int size = 10;
                   6376:     xmlChar cur;
1.29      daniel   6377: 
1.135     daniel   6378:     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   6379:     if (buf == NULL) {
                   6380:        fprintf(stderr, "malloc of %d byte failed\n", size);
                   6381:        return(NULL);
                   6382:     }
                   6383:     cur = CUR;
                   6384:     while (IS_CHAR(cur) &&
                   6385:            (((cur >= 'a') && (cur <= 'z')) ||
                   6386:             ((cur >= 'A') && (cur <= 'Z')) ||
                   6387:             ((cur >= '0') && (cur <= '9')) ||
                   6388:             (cur == '_') || (cur == '.') ||
                   6389:            (cur == ':') || (cur == '-'))) {
                   6390:        if (len + 1 >= size) {
                   6391:            size *= 2;
                   6392:            buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   6393:            if (buf == NULL) {
                   6394:                fprintf(stderr, "realloc of %d byte failed\n", size);
                   6395:                return(NULL);
                   6396:            }
                   6397:        }
                   6398:        buf[len++] = cur;
                   6399:        NEXT;
                   6400:        cur=CUR;
                   6401:     }
                   6402:     buf[len] = 0;
                   6403:     return(buf);
1.29      daniel   6404: }
                   6405: 
1.50      daniel   6406: /**
                   6407:  * xmlParseVersionInfo:
                   6408:  * @ctxt:  an XML parser context
                   6409:  * 
                   6410:  * parse the XML version.
1.29      daniel   6411:  *
                   6412:  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
                   6413:  * 
                   6414:  * [25] Eq ::= S? '=' S?
1.50      daniel   6415:  *
1.68      daniel   6416:  * Returns the version string, e.g. "1.0"
1.29      daniel   6417:  */
                   6418: 
1.123     daniel   6419: xmlChar *
1.55      daniel   6420: xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
1.123     daniel   6421:     xmlChar *version = NULL;
                   6422:     const xmlChar *q;
1.29      daniel   6423: 
1.40      daniel   6424:     if ((CUR == 'v') && (NXT(1) == 'e') &&
                   6425:         (NXT(2) == 'r') && (NXT(3) == 's') &&
                   6426:        (NXT(4) == 'i') && (NXT(5) == 'o') &&
                   6427:        (NXT(6) == 'n')) {
                   6428:        SKIP(7);
1.42      daniel   6429:        SKIP_BLANKS;
1.40      daniel   6430:        if (CUR != '=') {
1.55      daniel   6431:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6432:                ctxt->sax->error(ctxt->userData,
                   6433:                                 "xmlParseVersionInfo : expected '='\n");
1.59      daniel   6434:            ctxt->wellFormed = 0;
1.123     daniel   6435:            ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
1.31      daniel   6436:            return(NULL);
                   6437:         }
1.40      daniel   6438:        NEXT;
1.42      daniel   6439:        SKIP_BLANKS;
1.40      daniel   6440:        if (CUR == '"') {
                   6441:            NEXT;
                   6442:            q = CUR_PTR;
1.29      daniel   6443:            version = xmlParseVersionNum(ctxt);
1.55      daniel   6444:            if (CUR != '"') {
                   6445:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6446:                    ctxt->sax->error(ctxt->userData, 
                   6447:                                     "String not closed\n%.50s\n", q);
1.59      daniel   6448:                ctxt->wellFormed = 0;
1.123     daniel   6449:                ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.55      daniel   6450:            } else
1.40      daniel   6451:                NEXT;
                   6452:        } else if (CUR == '\''){
                   6453:            NEXT;
                   6454:            q = CUR_PTR;
1.29      daniel   6455:            version = xmlParseVersionNum(ctxt);
1.55      daniel   6456:            if (CUR != '\'') {
                   6457:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6458:                    ctxt->sax->error(ctxt->userData,
                   6459:                                     "String not closed\n%.50s\n", q);
1.123     daniel   6460:                ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.59      daniel   6461:                ctxt->wellFormed = 0;
1.55      daniel   6462:            } else
1.40      daniel   6463:                NEXT;
1.31      daniel   6464:        } else {
1.55      daniel   6465:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6466:                ctxt->sax->error(ctxt->userData,
1.59      daniel   6467:                      "xmlParseVersionInfo : expected ' or \"\n");
1.122     daniel   6468:            ctxt->wellFormed = 0;
1.123     daniel   6469:            ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
1.29      daniel   6470:        }
                   6471:     }
                   6472:     return(version);
                   6473: }
                   6474: 
1.50      daniel   6475: /**
                   6476:  * xmlParseEncName:
                   6477:  * @ctxt:  an XML parser context
                   6478:  *
                   6479:  * parse the XML encoding name
1.29      daniel   6480:  *
                   6481:  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
1.50      daniel   6482:  *
1.68      daniel   6483:  * Returns the encoding name value or NULL
1.29      daniel   6484:  */
1.123     daniel   6485: xmlChar *
1.55      daniel   6486: xmlParseEncName(xmlParserCtxtPtr ctxt) {
1.135     daniel   6487:     xmlChar *buf = NULL;
                   6488:     int len = 0;
                   6489:     int size = 10;
                   6490:     xmlChar cur;
1.29      daniel   6491: 
1.135     daniel   6492:     cur = CUR;
                   6493:     if (((cur >= 'a') && (cur <= 'z')) ||
                   6494:         ((cur >= 'A') && (cur <= 'Z'))) {
                   6495:        buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
                   6496:        if (buf == NULL) {
                   6497:            fprintf(stderr, "malloc of %d byte failed\n", size);
                   6498:            return(NULL);
                   6499:        }
                   6500:        
                   6501:        buf[len++] = cur;
1.40      daniel   6502:        NEXT;
1.135     daniel   6503:        cur = CUR;
                   6504:        while (IS_CHAR(cur) &&
                   6505:               (((cur >= 'a') && (cur <= 'z')) ||
                   6506:                ((cur >= 'A') && (cur <= 'Z')) ||
                   6507:                ((cur >= '0') && (cur <= '9')) ||
                   6508:                (cur == '.') || (cur == '_') ||
                   6509:                (cur == '-'))) {
                   6510:            if (len + 1 >= size) {
                   6511:                size *= 2;
                   6512:                buf = xmlRealloc(buf, size * sizeof(xmlChar));
                   6513:                if (buf == NULL) {
                   6514:                    fprintf(stderr, "realloc of %d byte failed\n", size);
                   6515:                    return(NULL);
                   6516:                }
                   6517:            }
                   6518:            buf[len++] = cur;
                   6519:            NEXT;
                   6520:            cur = CUR;
                   6521:            if (cur == 0) {
                   6522:                SHRINK;
                   6523:                GROW;
                   6524:                cur = CUR;
                   6525:            }
                   6526:         }
                   6527:        buf[len] = 0;
1.29      daniel   6528:     } else {
1.55      daniel   6529:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6530:            ctxt->sax->error(ctxt->userData, "Invalid XML encoding name\n");
1.59      daniel   6531:        ctxt->wellFormed = 0;
1.123     daniel   6532:        ctxt->errNo = XML_ERR_ENCODING_NAME;
1.29      daniel   6533:     }
1.135     daniel   6534:     return(buf);
1.29      daniel   6535: }
                   6536: 
1.50      daniel   6537: /**
                   6538:  * xmlParseEncodingDecl:
                   6539:  * @ctxt:  an XML parser context
                   6540:  * 
                   6541:  * parse the XML encoding declaration
1.29      daniel   6542:  *
                   6543:  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
1.50      daniel   6544:  *
                   6545:  * TODO: this should setup the conversion filters.
                   6546:  *
1.68      daniel   6547:  * Returns the encoding value or NULL
1.29      daniel   6548:  */
                   6549: 
1.123     daniel   6550: xmlChar *
1.55      daniel   6551: xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   6552:     xmlChar *encoding = NULL;
                   6553:     const xmlChar *q;
1.29      daniel   6554: 
1.42      daniel   6555:     SKIP_BLANKS;
1.40      daniel   6556:     if ((CUR == 'e') && (NXT(1) == 'n') &&
                   6557:         (NXT(2) == 'c') && (NXT(3) == 'o') &&
                   6558:        (NXT(4) == 'd') && (NXT(5) == 'i') &&
                   6559:        (NXT(6) == 'n') && (NXT(7) == 'g')) {
                   6560:        SKIP(8);
1.42      daniel   6561:        SKIP_BLANKS;
1.40      daniel   6562:        if (CUR != '=') {
1.55      daniel   6563:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6564:                ctxt->sax->error(ctxt->userData,
                   6565:                                 "xmlParseEncodingDecl : expected '='\n");
1.59      daniel   6566:            ctxt->wellFormed = 0;
1.123     daniel   6567:            ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
1.31      daniel   6568:            return(NULL);
                   6569:         }
1.40      daniel   6570:        NEXT;
1.42      daniel   6571:        SKIP_BLANKS;
1.40      daniel   6572:        if (CUR == '"') {
                   6573:            NEXT;
                   6574:            q = CUR_PTR;
1.29      daniel   6575:            encoding = xmlParseEncName(ctxt);
1.55      daniel   6576:            if (CUR != '"') {
                   6577:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6578:                    ctxt->sax->error(ctxt->userData, 
                   6579:                                     "String not closed\n%.50s\n", q);
1.59      daniel   6580:                ctxt->wellFormed = 0;
1.123     daniel   6581:                ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.55      daniel   6582:            } else
1.40      daniel   6583:                NEXT;
                   6584:        } else if (CUR == '\''){
                   6585:            NEXT;
                   6586:            q = CUR_PTR;
1.29      daniel   6587:            encoding = xmlParseEncName(ctxt);
1.55      daniel   6588:            if (CUR != '\'') {
                   6589:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6590:                    ctxt->sax->error(ctxt->userData,
                   6591:                                     "String not closed\n%.50s\n", q);
1.59      daniel   6592:                ctxt->wellFormed = 0;
1.123     daniel   6593:                ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.55      daniel   6594:            } else
1.40      daniel   6595:                NEXT;
                   6596:        } else if (CUR == '"'){
1.55      daniel   6597:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6598:                ctxt->sax->error(ctxt->userData,
1.59      daniel   6599:                     "xmlParseEncodingDecl : expected ' or \"\n");
                   6600:            ctxt->wellFormed = 0;
1.123     daniel   6601:            ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
1.29      daniel   6602:        }
                   6603:     }
                   6604:     return(encoding);
                   6605: }
                   6606: 
1.50      daniel   6607: /**
                   6608:  * xmlParseSDDecl:
                   6609:  * @ctxt:  an XML parser context
                   6610:  *
                   6611:  * parse the XML standalone declaration
1.29      daniel   6612:  *
                   6613:  * [32] SDDecl ::= S 'standalone' Eq
                   6614:  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
1.99      daniel   6615:  *
                   6616:  * [ VC: Standalone Document Declaration ]
                   6617:  * TODO The standalone document declaration must have the value "no"
                   6618:  * if any external markup declarations contain declarations of:
                   6619:  *  - attributes with default values, if elements to which these
                   6620:  *    attributes apply appear in the document without specifications
                   6621:  *    of values for these attributes, or
                   6622:  *  - entities (other than amp, lt, gt, apos, quot), if references
                   6623:  *    to those entities appear in the document, or
                   6624:  *  - attributes with values subject to normalization, where the
                   6625:  *    attribute appears in the document with a value which will change
                   6626:  *    as a result of normalization, or
                   6627:  *  - element types with element content, if white space occurs directly
                   6628:  *    within any instance of those types.
1.68      daniel   6629:  *
                   6630:  * Returns 1 if standalone, 0 otherwise
1.29      daniel   6631:  */
                   6632: 
1.55      daniel   6633: int
                   6634: xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
1.29      daniel   6635:     int standalone = -1;
                   6636: 
1.42      daniel   6637:     SKIP_BLANKS;
1.40      daniel   6638:     if ((CUR == 's') && (NXT(1) == 't') &&
                   6639:         (NXT(2) == 'a') && (NXT(3) == 'n') &&
                   6640:        (NXT(4) == 'd') && (NXT(5) == 'a') &&
                   6641:        (NXT(6) == 'l') && (NXT(7) == 'o') &&
                   6642:        (NXT(8) == 'n') && (NXT(9) == 'e')) {
                   6643:        SKIP(10);
1.81      daniel   6644:         SKIP_BLANKS;
1.40      daniel   6645:        if (CUR != '=') {
1.55      daniel   6646:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6647:                ctxt->sax->error(ctxt->userData,
1.59      daniel   6648:                    "XML standalone declaration : expected '='\n");
1.123     daniel   6649:            ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
1.59      daniel   6650:            ctxt->wellFormed = 0;
1.32      daniel   6651:            return(standalone);
                   6652:         }
1.40      daniel   6653:        NEXT;
1.42      daniel   6654:        SKIP_BLANKS;
1.40      daniel   6655:         if (CUR == '\''){
                   6656:            NEXT;
                   6657:            if ((CUR == 'n') && (NXT(1) == 'o')) {
1.29      daniel   6658:                standalone = 0;
1.40      daniel   6659:                 SKIP(2);
                   6660:            } else if ((CUR == 'y') && (NXT(1) == 'e') &&
                   6661:                       (NXT(2) == 's')) {
1.29      daniel   6662:                standalone = 1;
1.40      daniel   6663:                SKIP(3);
1.29      daniel   6664:             } else {
1.55      daniel   6665:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6666:                    ctxt->sax->error(ctxt->userData,
                   6667:                                     "standalone accepts only 'yes' or 'no'\n");
1.123     daniel   6668:                ctxt->errNo = XML_ERR_STANDALONE_VALUE;
1.59      daniel   6669:                ctxt->wellFormed = 0;
1.29      daniel   6670:            }
1.55      daniel   6671:            if (CUR != '\'') {
                   6672:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6673:                    ctxt->sax->error(ctxt->userData, "String not closed\n");
1.123     daniel   6674:                ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.59      daniel   6675:                ctxt->wellFormed = 0;
1.55      daniel   6676:            } else
1.40      daniel   6677:                NEXT;
                   6678:        } else if (CUR == '"'){
                   6679:            NEXT;
                   6680:            if ((CUR == 'n') && (NXT(1) == 'o')) {
1.29      daniel   6681:                standalone = 0;
1.40      daniel   6682:                SKIP(2);
                   6683:            } else if ((CUR == 'y') && (NXT(1) == 'e') &&
                   6684:                       (NXT(2) == 's')) {
1.29      daniel   6685:                standalone = 1;
1.40      daniel   6686:                 SKIP(3);
1.29      daniel   6687:             } else {
1.55      daniel   6688:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6689:                    ctxt->sax->error(ctxt->userData,
1.59      daniel   6690:                        "standalone accepts only 'yes' or 'no'\n");
1.123     daniel   6691:                ctxt->errNo = XML_ERR_STANDALONE_VALUE;
1.59      daniel   6692:                ctxt->wellFormed = 0;
1.29      daniel   6693:            }
1.55      daniel   6694:            if (CUR != '"') {
                   6695:                if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6696:                    ctxt->sax->error(ctxt->userData, "String not closed\n");
1.59      daniel   6697:                ctxt->wellFormed = 0;
1.123     daniel   6698:                ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
1.55      daniel   6699:            } else
1.40      daniel   6700:                NEXT;
1.37      daniel   6701:        } else {
1.55      daniel   6702:             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6703:                ctxt->sax->error(ctxt->userData,
                   6704:                                 "Standalone value not found\n");
1.59      daniel   6705:            ctxt->wellFormed = 0;
1.123     daniel   6706:            ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
1.37      daniel   6707:         }
1.29      daniel   6708:     }
                   6709:     return(standalone);
                   6710: }
                   6711: 
1.50      daniel   6712: /**
                   6713:  * xmlParseXMLDecl:
                   6714:  * @ctxt:  an XML parser context
                   6715:  * 
                   6716:  * parse an XML declaration header
1.29      daniel   6717:  *
                   6718:  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
1.1       veillard 6719:  */
                   6720: 
1.55      daniel   6721: void
                   6722: xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
1.123     daniel   6723:     xmlChar *version;
1.1       veillard 6724: 
                   6725:     /*
1.19      daniel   6726:      * We know that '<?xml' is here.
1.1       veillard 6727:      */
1.40      daniel   6728:     SKIP(5);
1.1       veillard 6729: 
1.59      daniel   6730:     if (!IS_BLANK(CUR)) {
                   6731:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6732:            ctxt->sax->error(ctxt->userData, "Blank needed after '<?xml'\n");
1.123     daniel   6733:        ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   6734:        ctxt->wellFormed = 0;
                   6735:     }
1.42      daniel   6736:     SKIP_BLANKS;
1.1       veillard 6737: 
                   6738:     /*
1.29      daniel   6739:      * We should have the VersionInfo here.
1.1       veillard 6740:      */
1.29      daniel   6741:     version = xmlParseVersionInfo(ctxt);
                   6742:     if (version == NULL)
1.45      daniel   6743:        version = xmlCharStrdup(XML_DEFAULT_VERSION);
1.72      daniel   6744:     ctxt->version = xmlStrdup(version);
1.119     daniel   6745:     xmlFree(version);
1.29      daniel   6746: 
                   6747:     /*
                   6748:      * We may have the encoding declaration
                   6749:      */
1.59      daniel   6750:     if (!IS_BLANK(CUR)) {
                   6751:         if ((CUR == '?') && (NXT(1) == '>')) {
                   6752:            SKIP(2);
                   6753:            return;
                   6754:        }
                   6755:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6756:            ctxt->sax->error(ctxt->userData, "Blank needed here\n");
1.123     daniel   6757:        ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   6758:        ctxt->wellFormed = 0;
                   6759:     }
1.72      daniel   6760:     ctxt->encoding = xmlParseEncodingDecl(ctxt);
1.1       veillard 6761: 
                   6762:     /*
1.29      daniel   6763:      * We may have the standalone status.
1.1       veillard 6764:      */
1.72      daniel   6765:     if ((ctxt->encoding != NULL) && (!IS_BLANK(CUR))) {
1.59      daniel   6766:         if ((CUR == '?') && (NXT(1) == '>')) {
                   6767:            SKIP(2);
                   6768:            return;
                   6769:        }
                   6770:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6771:            ctxt->sax->error(ctxt->userData, "Blank needed here\n");
1.59      daniel   6772:        ctxt->wellFormed = 0;
1.123     daniel   6773:        ctxt->errNo = XML_ERR_SPACE_REQUIRED;
1.59      daniel   6774:     }
                   6775:     SKIP_BLANKS;
1.72      daniel   6776:     ctxt->standalone = xmlParseSDDecl(ctxt);
1.1       veillard 6777: 
1.42      daniel   6778:     SKIP_BLANKS;
1.40      daniel   6779:     if ((CUR == '?') && (NXT(1) == '>')) {
                   6780:         SKIP(2);
                   6781:     } else if (CUR == '>') {
1.31      daniel   6782:         /* Deprecated old WD ... */
1.55      daniel   6783:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6784:            ctxt->sax->error(ctxt->userData, 
                   6785:                             "XML declaration must end-up with '?>'\n");
1.59      daniel   6786:        ctxt->wellFormed = 0;
1.123     daniel   6787:        ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
1.40      daniel   6788:        NEXT;
1.29      daniel   6789:     } else {
1.55      daniel   6790:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.122     daniel   6791:            ctxt->sax->error(ctxt->userData,
                   6792:                             "parsing XML declaration: '?>' expected\n");
1.59      daniel   6793:        ctxt->wellFormed = 0;
1.123     daniel   6794:        ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
1.40      daniel   6795:        MOVETO_ENDTAG(CUR_PTR);
                   6796:        NEXT;
1.29      daniel   6797:     }
1.1       veillard 6798: }
                   6799: 
1.50      daniel   6800: /**
                   6801:  * xmlParseMisc:
                   6802:  * @ctxt:  an XML parser context
                   6803:  * 
                   6804:  * parse an XML Misc* optionnal field.
1.21      daniel   6805:  *
1.22      daniel   6806:  * [27] Misc ::= Comment | PI |  S
1.1       veillard 6807:  */
                   6808: 
1.55      daniel   6809: void
                   6810: xmlParseMisc(xmlParserCtxtPtr ctxt) {
1.40      daniel   6811:     while (((CUR == '<') && (NXT(1) == '?')) ||
                   6812:            ((CUR == '<') && (NXT(1) == '!') &&
                   6813:            (NXT(2) == '-') && (NXT(3) == '-')) ||
                   6814:            IS_BLANK(CUR)) {
                   6815:         if ((CUR == '<') && (NXT(1) == '?')) {
1.16      daniel   6816:            xmlParsePI(ctxt);
1.40      daniel   6817:        } else if (IS_BLANK(CUR)) {
                   6818:            NEXT;
1.1       veillard 6819:        } else
1.114     daniel   6820:            xmlParseComment(ctxt);
1.1       veillard 6821:     }
                   6822: }
                   6823: 
1.50      daniel   6824: /**
                   6825:  * xmlParseDocument :
                   6826:  * @ctxt:  an XML parser context
                   6827:  * 
                   6828:  * parse an XML document (and build a tree if using the standard SAX
                   6829:  * interface).
1.21      daniel   6830:  *
1.22      daniel   6831:  * [1] document ::= prolog element Misc*
1.29      daniel   6832:  *
                   6833:  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
1.50      daniel   6834:  *
1.68      daniel   6835:  * Returns 0, -1 in case of error. the parser context is augmented
1.50      daniel   6836:  *                as a result of the parsing.
1.1       veillard 6837:  */
                   6838: 
1.55      daniel   6839: int
                   6840: xmlParseDocument(xmlParserCtxtPtr ctxt) {
1.45      daniel   6841:     xmlDefaultSAXHandlerInit();
                   6842: 
1.91      daniel   6843:     GROW;
                   6844: 
1.14      veillard 6845:     /*
1.44      daniel   6846:      * SAX: beginning of the document processing.
                   6847:      */
1.72      daniel   6848:     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
1.74      daniel   6849:         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
1.44      daniel   6850: 
                   6851:     /*
1.117     daniel   6852:      * TODO We should check for encoding here and plug-in some
                   6853:      * conversion code !!!!
1.14      veillard 6854:      */
1.1       veillard 6855: 
                   6856:     /*
                   6857:      * Wipe out everything which is before the first '<'
                   6858:      */
1.59      daniel   6859:     if (IS_BLANK(CUR)) {
                   6860:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6861:            ctxt->sax->error(ctxt->userData,
1.59      daniel   6862:            "Extra spaces at the beginning of the document are not allowed\n");
1.123     daniel   6863:        ctxt->errNo = XML_ERR_DOCUMENT_START;
1.59      daniel   6864:        ctxt->wellFormed = 0;
                   6865:        SKIP_BLANKS;
                   6866:     }
                   6867: 
                   6868:     if (CUR == 0) {
                   6869:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6870:            ctxt->sax->error(ctxt->userData, "Document is empty\n");
1.123     daniel   6871:        ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
1.59      daniel   6872:        ctxt->wellFormed = 0;
                   6873:     }
1.1       veillard 6874: 
                   6875:     /*
                   6876:      * Check for the XMLDecl in the Prolog.
                   6877:      */
1.91      daniel   6878:     GROW;
1.40      daniel   6879:     if ((CUR == '<') && (NXT(1) == '?') &&
                   6880:         (NXT(2) == 'x') && (NXT(3) == 'm') &&
1.142     daniel   6881:        (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
1.19      daniel   6882:        xmlParseXMLDecl(ctxt);
1.42      daniel   6883:        SKIP_BLANKS;
1.40      daniel   6884:     } else if ((CUR == '<') && (NXT(1) == '?') &&
                   6885:         (NXT(2) == 'X') && (NXT(3) == 'M') &&
1.142     daniel   6886:        (NXT(4) == 'L') && (IS_BLANK(NXT(5)))) {
1.19      daniel   6887:        /*
                   6888:         * The first drafts were using <?XML and the final W3C REC
                   6889:         * now use <?xml ...
                   6890:         */
1.16      daniel   6891:        xmlParseXMLDecl(ctxt);
1.42      daniel   6892:        SKIP_BLANKS;
1.1       veillard 6893:     } else {
1.72      daniel   6894:        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
1.1       veillard 6895:     }
1.72      daniel   6896:     if ((ctxt->sax) && (ctxt->sax->startDocument))
1.74      daniel   6897:         ctxt->sax->startDocument(ctxt->userData);
1.1       veillard 6898: 
                   6899:     /*
                   6900:      * The Misc part of the Prolog
                   6901:      */
1.91      daniel   6902:     GROW;
1.16      daniel   6903:     xmlParseMisc(ctxt);
1.1       veillard 6904: 
                   6905:     /*
1.29      daniel   6906:      * Then possibly doc type declaration(s) and more Misc
1.21      daniel   6907:      * (doctypedecl Misc*)?
                   6908:      */
1.91      daniel   6909:     GROW;
1.40      daniel   6910:     if ((CUR == '<') && (NXT(1) == '!') &&
                   6911:        (NXT(2) == 'D') && (NXT(3) == 'O') &&
                   6912:        (NXT(4) == 'C') && (NXT(5) == 'T') &&
                   6913:        (NXT(6) == 'Y') && (NXT(7) == 'P') &&
                   6914:        (NXT(8) == 'E')) {
1.22      daniel   6915:        xmlParseDocTypeDecl(ctxt);
1.140     daniel   6916:        if (CUR == '[') {
                   6917:            ctxt->instate = XML_PARSER_DTD;
                   6918:            xmlParseInternalSubset(ctxt);
                   6919:        }
1.96      daniel   6920:        ctxt->instate = XML_PARSER_PROLOG;
1.22      daniel   6921:        xmlParseMisc(ctxt);
1.21      daniel   6922:     }
                   6923: 
                   6924:     /*
                   6925:      * Time to start parsing the tree itself
1.1       veillard 6926:      */
1.91      daniel   6927:     GROW;
1.140     daniel   6928:     if (CUR != '<') {
1.59      daniel   6929:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   6930:            ctxt->sax->error(ctxt->userData,
1.140     daniel   6931:                    "Start tag expect, '<' not found\n");
                   6932:        ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
1.59      daniel   6933:        ctxt->wellFormed = 0;
1.140     daniel   6934:        ctxt->instate = XML_PARSER_EOF;
                   6935:     } else {
                   6936:        ctxt->instate = XML_PARSER_CONTENT;
                   6937:        xmlParseElement(ctxt);
                   6938:        ctxt->instate = XML_PARSER_EPILOG;
                   6939: 
                   6940: 
                   6941:        /*
                   6942:         * The Misc part at the end
                   6943:         */
                   6944:        xmlParseMisc(ctxt);
                   6945: 
                   6946:        if (CUR != 0) {
                   6947:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   6948:                ctxt->sax->error(ctxt->userData,
                   6949:                    "Extra content at the end of the document\n");
                   6950:            ctxt->wellFormed = 0;
                   6951:            ctxt->errNo = XML_ERR_DOCUMENT_END;
                   6952:        }
                   6953:        ctxt->instate = XML_PARSER_EOF;
1.59      daniel   6954:     }
                   6955: 
1.44      daniel   6956:     /*
                   6957:      * SAX: end of the document processing.
                   6958:      */
1.72      daniel   6959:     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
1.74      daniel   6960:         ctxt->sax->endDocument(ctxt->userData);
1.59      daniel   6961:     if (! ctxt->wellFormed) return(-1);
1.16      daniel   6962:     return(0);
                   6963: }
                   6964: 
1.98      daniel   6965: /************************************************************************
                   6966:  *                                                                     *
1.128     daniel   6967:  *             Progressive parsing interfaces                          *
                   6968:  *                                                                     *
                   6969:  ************************************************************************/
                   6970: 
                   6971: /**
                   6972:  * xmlParseLookupSequence:
                   6973:  * @ctxt:  an XML parser context
                   6974:  * @first:  the first char to lookup
1.140     daniel   6975:  * @next:  the next char to lookup or zero
                   6976:  * @third:  the next char to lookup or zero
1.128     daniel   6977:  *
1.140     daniel   6978:  * Try to find if a sequence (first, next, third) or  just (first next) or
                   6979:  * (first) is available in the input stream.
                   6980:  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
                   6981:  * to avoid rescanning sequences of bytes, it DOES change the state of the
                   6982:  * parser, do not use liberally.
1.128     daniel   6983:  *
1.140     daniel   6984:  * Returns the index to the current parsing point if the full sequence
                   6985:  *      is available, -1 otherwise.
1.128     daniel   6986:  */
                   6987: int
1.140     daniel   6988: xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
                   6989:                        xmlChar next, xmlChar third) {
                   6990:     int base, len;
                   6991:     xmlParserInputPtr in;
                   6992:     const xmlChar *buf;
                   6993: 
                   6994:     in = ctxt->input;
                   6995:     if (in == NULL) return(-1);
                   6996:     base = in->cur - in->base;
                   6997:     if (base < 0) return(-1);
                   6998:     if (ctxt->checkIndex > base)
                   6999:         base = ctxt->checkIndex;
                   7000:     if (in->buf == NULL) {
                   7001:        buf = in->base;
                   7002:        len = in->length;
                   7003:     } else {
                   7004:        buf = in->buf->buffer->content;
                   7005:        len = in->buf->buffer->use;
                   7006:     }
                   7007:     /* take into account the sequence length */
                   7008:     if (third) len -= 2;
                   7009:     else if (next) len --;
                   7010:     for (;base < len;base++) {
                   7011:         if (buf[base] == first) {
                   7012:            if (third != 0) {
                   7013:                if ((buf[base + 1] != next) ||
                   7014:                    (buf[base + 2] != third)) continue;
                   7015:            } else if (next != 0) {
                   7016:                if (buf[base + 1] != next) continue;
                   7017:            }
                   7018:            ctxt->checkIndex = 0;
                   7019: #ifdef DEBUG_PUSH
                   7020:            if (next == 0)
                   7021:                fprintf(stderr, "PP: lookup '%c' found at %d\n",
                   7022:                        first, base);
                   7023:            else if (third == 0)
                   7024:                fprintf(stderr, "PP: lookup '%c%c' found at %d\n",
                   7025:                        first, next, base);
                   7026:            else 
                   7027:                fprintf(stderr, "PP: lookup '%c%c%c' found at %d\n",
                   7028:                        first, next, third, base);
                   7029: #endif
                   7030:            return(base - (in->cur - in->base));
                   7031:        }
                   7032:     }
                   7033:     ctxt->checkIndex = base;
                   7034: #ifdef DEBUG_PUSH
                   7035:     if (next == 0)
                   7036:        fprintf(stderr, "PP: lookup '%c' failed\n", first);
                   7037:     else if (third == 0)
                   7038:        fprintf(stderr, "PP: lookup '%c%c' failed\n", first, next);
                   7039:     else       
                   7040:        fprintf(stderr, "PP: lookup '%c%c%c' failed\n", first, next, third);
                   7041: #endif
                   7042:     return(-1);
1.128     daniel   7043: }
                   7044: 
                   7045: /**
1.143     daniel   7046:  * xmlParseTryOrFinish:
1.128     daniel   7047:  * @ctxt:  an XML parser context
1.143     daniel   7048:  * @terminate:  last chunk indicator
1.128     daniel   7049:  *
                   7050:  * Try to progress on parsing
                   7051:  *
                   7052:  * Returns zero if no parsing was possible
                   7053:  */
                   7054: int
1.143     daniel   7055: xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
1.128     daniel   7056:     int ret = 0;
1.140     daniel   7057:     xmlParserInputPtr in;
                   7058:     int avail;
                   7059:     xmlChar cur, next;
                   7060: 
                   7061: #ifdef DEBUG_PUSH
                   7062:     switch (ctxt->instate) {
                   7063:        case XML_PARSER_EOF:
                   7064:            fprintf(stderr, "PP: try EOF\n"); break;
                   7065:        case XML_PARSER_START:
                   7066:            fprintf(stderr, "PP: try START\n"); break;
                   7067:        case XML_PARSER_MISC:
                   7068:            fprintf(stderr, "PP: try MISC\n");break;
                   7069:        case XML_PARSER_COMMENT:
                   7070:            fprintf(stderr, "PP: try COMMENT\n");break;
                   7071:        case XML_PARSER_PROLOG:
                   7072:            fprintf(stderr, "PP: try PROLOG\n");break;
                   7073:        case XML_PARSER_START_TAG:
                   7074:            fprintf(stderr, "PP: try START_TAG\n");break;
                   7075:        case XML_PARSER_CONTENT:
                   7076:            fprintf(stderr, "PP: try CONTENT\n");break;
                   7077:        case XML_PARSER_CDATA_SECTION:
                   7078:            fprintf(stderr, "PP: try CDATA_SECTION\n");break;
                   7079:        case XML_PARSER_END_TAG:
                   7080:            fprintf(stderr, "PP: try END_TAG\n");break;
                   7081:        case XML_PARSER_ENTITY_DECL:
                   7082:            fprintf(stderr, "PP: try ENTITY_DECL\n");break;
                   7083:        case XML_PARSER_ENTITY_VALUE:
                   7084:            fprintf(stderr, "PP: try ENTITY_VALUE\n");break;
                   7085:        case XML_PARSER_ATTRIBUTE_VALUE:
                   7086:            fprintf(stderr, "PP: try ATTRIBUTE_VALUE\n");break;
                   7087:        case XML_PARSER_DTD:
                   7088:            fprintf(stderr, "PP: try DTD\n");break;
                   7089:        case XML_PARSER_EPILOG:
                   7090:            fprintf(stderr, "PP: try EPILOG\n");break;
                   7091:        case XML_PARSER_PI:
                   7092:            fprintf(stderr, "PP: try PI\n");break;
                   7093:     }
                   7094: #endif
1.128     daniel   7095: 
                   7096:     while (1) {
1.140     daniel   7097:        /*
                   7098:         * Pop-up of finished entities.
                   7099:         */
                   7100:        while ((CUR == 0) && (ctxt->inputNr > 1))
                   7101:            xmlPopInput(ctxt);
                   7102: 
                   7103:        in = ctxt->input;
                   7104:        if (in == NULL) break;
                   7105:        if (in->buf == NULL)
                   7106:            avail = in->length - (in->cur - in->base);
                   7107:        else
                   7108:            avail = in->buf->buffer->use - (in->cur - in->base);
                   7109:         if (avail < 1)
                   7110:            goto done;
1.128     daniel   7111:         switch (ctxt->instate) {
                   7112:             case XML_PARSER_EOF:
1.140     daniel   7113:                /*
                   7114:                 * Document parsing is done !
                   7115:                 */
                   7116:                goto done;
                   7117:             case XML_PARSER_START:
                   7118:                /*
                   7119:                 * Very first chars read from the document flow.
                   7120:                 */
                   7121:                cur = in->cur[0];
                   7122:                if (IS_BLANK(cur)) {
                   7123:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   7124:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   7125:                                                      &xmlDefaultSAXLocator);
                   7126:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   7127:                        ctxt->sax->error(ctxt->userData,
                   7128:            "Extra spaces at the beginning of the document are not allowed\n");
                   7129:                    ctxt->errNo = XML_ERR_DOCUMENT_START;
                   7130:                    ctxt->wellFormed = 0;
                   7131:                    SKIP_BLANKS;
                   7132:                    ret++;
                   7133:                    if (in->buf == NULL)
                   7134:                        avail = in->length - (in->cur - in->base);
                   7135:                    else
                   7136:                        avail = in->buf->buffer->use - (in->cur - in->base);
                   7137:                }
                   7138:                if (avail < 2)
                   7139:                    goto done;
                   7140: 
                   7141:                cur = in->cur[0];
                   7142:                next = in->cur[1];
                   7143:                if (cur == 0) {
                   7144:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   7145:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   7146:                                                      &xmlDefaultSAXLocator);
                   7147:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   7148:                        ctxt->sax->error(ctxt->userData, "Document is empty\n");
                   7149:                    ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
                   7150:                    ctxt->wellFormed = 0;
                   7151:                    ctxt->instate = XML_PARSER_EOF;
                   7152: #ifdef DEBUG_PUSH
                   7153:                    fprintf(stderr, "PP: entering EOF\n");
                   7154: #endif
                   7155:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   7156:                        ctxt->sax->endDocument(ctxt->userData);
                   7157:                    goto done;
                   7158:                }
                   7159:                if ((cur == '<') && (next == '?')) {
                   7160:                    /* PI or XML decl */
                   7161:                    if (avail < 5) return(ret);
1.143     daniel   7162:                    if ((!terminate) &&
                   7163:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
1.140     daniel   7164:                        return(ret);
                   7165:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   7166:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   7167:                                                      &xmlDefaultSAXLocator);
                   7168:                    if ((in->cur[2] == 'x') &&
                   7169:                        (in->cur[3] == 'm') &&
1.142     daniel   7170:                        (in->cur[4] == 'l') &&
                   7171:                        (IS_BLANK(in->cur[5]))) {
1.140     daniel   7172:                        ret += 5;
                   7173: #ifdef DEBUG_PUSH
                   7174:                        fprintf(stderr, "PP: Parsing XML Decl\n");
                   7175: #endif
                   7176:                        xmlParseXMLDecl(ctxt);
                   7177:                        if ((ctxt->sax) && (ctxt->sax->startDocument))
                   7178:                            ctxt->sax->startDocument(ctxt->userData);
                   7179:                        ctxt->instate = XML_PARSER_MISC;
                   7180: #ifdef DEBUG_PUSH
                   7181:                        fprintf(stderr, "PP: entering MISC\n");
                   7182: #endif
                   7183:                    } else {
                   7184:                        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   7185:                        if ((ctxt->sax) && (ctxt->sax->startDocument))
                   7186:                            ctxt->sax->startDocument(ctxt->userData);
                   7187:                        ctxt->instate = XML_PARSER_MISC;
                   7188: #ifdef DEBUG_PUSH
                   7189:                        fprintf(stderr, "PP: entering MISC\n");
                   7190: #endif
                   7191:                    }
                   7192:                } else {
                   7193:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   7194:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   7195:                                                      &xmlDefaultSAXLocator);
                   7196:                    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   7197:                    if ((ctxt->sax) && (ctxt->sax->startDocument))
                   7198:                        ctxt->sax->startDocument(ctxt->userData);
                   7199:                    ctxt->instate = XML_PARSER_MISC;
                   7200: #ifdef DEBUG_PUSH
                   7201:                    fprintf(stderr, "PP: entering MISC\n");
                   7202: #endif
                   7203:                }
                   7204:                break;
                   7205:             case XML_PARSER_MISC:
                   7206:                SKIP_BLANKS;
                   7207:                if (in->buf == NULL)
                   7208:                    avail = in->length - (in->cur - in->base);
                   7209:                else
                   7210:                    avail = in->buf->buffer->use - (in->cur - in->base);
                   7211:                if (avail < 2)
                   7212:                    goto done;
                   7213:                cur = in->cur[0];
                   7214:                next = in->cur[1];
                   7215:                if ((cur == '<') && (next == '?')) {
1.143     daniel   7216:                    if ((!terminate) &&
                   7217:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
1.140     daniel   7218:                        goto done;
                   7219: #ifdef DEBUG_PUSH
                   7220:                    fprintf(stderr, "PP: Parsing PI\n");
                   7221: #endif
                   7222:                    xmlParsePI(ctxt);
                   7223:                } else if ((cur == '<') && (next == '!') &&
                   7224:                    (in->cur[2] == '-') && (in->cur[3] == '-')) {
1.143     daniel   7225:                    if ((!terminate) &&
                   7226:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
1.140     daniel   7227:                        goto done;
                   7228: #ifdef DEBUG_PUSH
                   7229:                    fprintf(stderr, "PP: Parsing Comment\n");
                   7230: #endif
                   7231:                    xmlParseComment(ctxt);
                   7232:                    ctxt->instate = XML_PARSER_MISC;
                   7233:                } else if ((cur == '<') && (next == '!') &&
                   7234:                    (in->cur[2] == 'D') && (in->cur[3] == 'O') &&
                   7235:                    (in->cur[4] == 'C') && (in->cur[5] == 'T') &&
                   7236:                    (in->cur[6] == 'Y') && (in->cur[7] == 'P') &&
                   7237:                    (in->cur[8] == 'E')) {
1.143     daniel   7238:                    if ((!terminate) &&
                   7239:                        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
1.140     daniel   7240:                        goto done;
                   7241: #ifdef DEBUG_PUSH
                   7242:                    fprintf(stderr, "PP: Parsing internal subset\n");
                   7243: #endif
                   7244:                    xmlParseDocTypeDecl(ctxt);
                   7245:                    if (CUR == '[') {
                   7246:                        ctxt->instate = XML_PARSER_DTD;
                   7247: #ifdef DEBUG_PUSH
                   7248:                        fprintf(stderr, "PP: entering DTD\n");
                   7249: #endif
                   7250:                    } else {
                   7251:                        ctxt->instate = XML_PARSER_PROLOG;
                   7252: #ifdef DEBUG_PUSH
                   7253:                        fprintf(stderr, "PP: entering PROLOG\n");
                   7254: #endif
                   7255:                    }
                   7256:                } else if ((cur == '<') && (next == '!') &&
                   7257:                           (avail < 9)) {
                   7258:                    goto done;
                   7259:                } else {
                   7260:                    ctxt->instate = XML_PARSER_START_TAG;
                   7261: #ifdef DEBUG_PUSH
                   7262:                    fprintf(stderr, "PP: entering START_TAG\n");
                   7263: #endif
                   7264:                }
                   7265:                break;
1.128     daniel   7266:             case XML_PARSER_PROLOG:
1.140     daniel   7267:                SKIP_BLANKS;
                   7268:                if (in->buf == NULL)
                   7269:                    avail = in->length - (in->cur - in->base);
                   7270:                else
                   7271:                    avail = in->buf->buffer->use - (in->cur - in->base);
                   7272:                if (avail < 2) 
                   7273:                    goto done;
                   7274:                cur = in->cur[0];
                   7275:                next = in->cur[1];
                   7276:                if ((cur == '<') && (next == '?')) {
1.143     daniel   7277:                    if ((!terminate) &&
                   7278:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
1.140     daniel   7279:                        goto done;
                   7280: #ifdef DEBUG_PUSH
                   7281:                    fprintf(stderr, "PP: Parsing PI\n");
                   7282: #endif
                   7283:                    xmlParsePI(ctxt);
                   7284:                } else if ((cur == '<') && (next == '!') &&
                   7285:                    (in->cur[2] == '-') && (in->cur[3] == '-')) {
1.143     daniel   7286:                    if ((!terminate) &&
                   7287:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
1.140     daniel   7288:                        goto done;
                   7289: #ifdef DEBUG_PUSH
                   7290:                    fprintf(stderr, "PP: Parsing Comment\n");
                   7291: #endif
                   7292:                    xmlParseComment(ctxt);
                   7293:                    ctxt->instate = XML_PARSER_PROLOG;
                   7294:                } else if ((cur == '<') && (next == '!') &&
                   7295:                           (avail < 4)) {
                   7296:                    goto done;
                   7297:                } else {
                   7298:                    ctxt->instate = XML_PARSER_START_TAG;
                   7299: #ifdef DEBUG_PUSH
                   7300:                    fprintf(stderr, "PP: entering START_TAG\n");
                   7301: #endif
                   7302:                }
                   7303:                break;
                   7304:             case XML_PARSER_EPILOG:
                   7305:                SKIP_BLANKS;
                   7306:                if (in->buf == NULL)
                   7307:                    avail = in->length - (in->cur - in->base);
                   7308:                else
                   7309:                    avail = in->buf->buffer->use - (in->cur - in->base);
                   7310:                if (avail < 2)
                   7311:                    goto done;
                   7312:                cur = in->cur[0];
                   7313:                next = in->cur[1];
                   7314:                if ((cur == '<') && (next == '?')) {
1.143     daniel   7315:                    if ((!terminate) &&
                   7316:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
1.140     daniel   7317:                        goto done;
                   7318: #ifdef DEBUG_PUSH
                   7319:                    fprintf(stderr, "PP: Parsing PI\n");
                   7320: #endif
                   7321:                    xmlParsePI(ctxt);
                   7322:                    ctxt->instate = XML_PARSER_EPILOG;
                   7323:                } else if ((cur == '<') && (next == '!') &&
                   7324:                    (in->cur[2] == '-') && (in->cur[3] == '-')) {
1.143     daniel   7325:                    if ((!terminate) &&
                   7326:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
1.140     daniel   7327:                        goto done;
                   7328: #ifdef DEBUG_PUSH
                   7329:                    fprintf(stderr, "PP: Parsing Comment\n");
                   7330: #endif
                   7331:                    xmlParseComment(ctxt);
                   7332:                    ctxt->instate = XML_PARSER_EPILOG;
                   7333:                } else if ((cur == '<') && (next == '!') &&
                   7334:                           (avail < 4)) {
                   7335:                    goto done;
                   7336:                } else {
                   7337:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   7338:                        ctxt->sax->error(ctxt->userData,
                   7339:                            "Extra content at the end of the document\n");
                   7340:                    ctxt->wellFormed = 0;
                   7341:                    ctxt->errNo = XML_ERR_DOCUMENT_END;
                   7342:                    ctxt->instate = XML_PARSER_EOF;
                   7343: #ifdef DEBUG_PUSH
                   7344:                    fprintf(stderr, "PP: entering EOF\n");
                   7345: #endif
                   7346:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   7347:                        ctxt->sax->endDocument(ctxt->userData);
                   7348:                    goto done;
                   7349:                }
                   7350:                break;
                   7351:             case XML_PARSER_START_TAG: {
                   7352:                xmlChar *name, *oldname;
                   7353: 
                   7354:                if (avail < 2)
                   7355:                    goto done;
                   7356:                cur = in->cur[0];
                   7357:                if (cur != '<') {
                   7358:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   7359:                        ctxt->sax->error(ctxt->userData,
                   7360:                                "Start tag expect, '<' not found\n");
                   7361:                    ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
                   7362:                    ctxt->wellFormed = 0;
                   7363:                    ctxt->instate = XML_PARSER_EOF;
                   7364: #ifdef DEBUG_PUSH
                   7365:                    fprintf(stderr, "PP: entering EOF\n");
                   7366: #endif
                   7367:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   7368:                        ctxt->sax->endDocument(ctxt->userData);
                   7369:                    goto done;
                   7370:                }
1.143     daniel   7371:                if ((!terminate) &&
                   7372:                    (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
1.140     daniel   7373:                    goto done;
                   7374:                name = xmlParseStartTag(ctxt);
                   7375:                if (name == NULL) {
                   7376:                    ctxt->instate = XML_PARSER_EOF;
                   7377: #ifdef DEBUG_PUSH
                   7378:                    fprintf(stderr, "PP: entering EOF\n");
                   7379: #endif
                   7380:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   7381:                        ctxt->sax->endDocument(ctxt->userData);
                   7382:                    goto done;
                   7383:                }
                   7384:                namePush(ctxt, xmlStrdup(name));
                   7385: 
                   7386:                /*
                   7387:                 * [ VC: Root Element Type ]
                   7388:                 * The Name in the document type declaration must match
                   7389:                 * the element type of the root element. 
                   7390:                 */
                   7391:                if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
                   7392:                    ctxt->node && (ctxt->node == ctxt->myDoc->root))
                   7393:                    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
                   7394: 
                   7395:                /*
                   7396:                 * Check for an Empty Element.
                   7397:                 */
                   7398:                if ((CUR == '/') && (NXT(1) == '>')) {
                   7399:                    SKIP(2);
                   7400:                    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
                   7401:                        ctxt->sax->endElement(ctxt->userData, name);
                   7402:                    xmlFree(name);
                   7403:                    oldname = namePop(ctxt);
                   7404:                    if (oldname != NULL) {
                   7405: #ifdef DEBUG_STACK
                   7406:                        fprintf(stderr,"Close: popped %s\n", oldname);
                   7407: #endif
                   7408:                        xmlFree(oldname);
                   7409:                    }
                   7410:                    if (ctxt->name == NULL) {
                   7411:                        ctxt->instate = XML_PARSER_EPILOG;
                   7412: #ifdef DEBUG_PUSH
                   7413:                        fprintf(stderr, "PP: entering EPILOG\n");
                   7414: #endif
                   7415:                    } else {
                   7416:                        ctxt->instate = XML_PARSER_CONTENT;
                   7417: #ifdef DEBUG_PUSH
                   7418:                        fprintf(stderr, "PP: entering CONTENT\n");
                   7419: #endif
                   7420:                    }
                   7421:                    break;
                   7422:                }
                   7423:                if (CUR == '>') {
                   7424:                    NEXT;
                   7425:                } else {
                   7426:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   7427:                        ctxt->sax->error(ctxt->userData,
                   7428:                                         "Couldn't find end of Start Tag %s\n",
                   7429:                                         name);
                   7430:                    ctxt->wellFormed = 0;
                   7431:                    ctxt->errNo = XML_ERR_GT_REQUIRED;
                   7432: 
                   7433:                    /*
                   7434:                     * end of parsing of this node.
                   7435:                     */
                   7436:                    nodePop(ctxt);
                   7437:                    oldname = namePop(ctxt);
                   7438:                    if (oldname != NULL) {
                   7439: #ifdef DEBUG_STACK
                   7440:                        fprintf(stderr,"Close: popped %s\n", oldname);
                   7441: #endif
                   7442:                        xmlFree(oldname);
                   7443:                    }
                   7444:                }
                   7445:                xmlFree(name);
                   7446:                ctxt->instate = XML_PARSER_CONTENT;
                   7447: #ifdef DEBUG_PUSH
                   7448:                fprintf(stderr, "PP: entering CONTENT\n");
                   7449: #endif
                   7450:                 break;
                   7451:            }
1.128     daniel   7452:             case XML_PARSER_CONTENT:
1.140     daniel   7453:                 /*
                   7454:                 * Handle preparsed entities and charRef
                   7455:                 */
                   7456:                if (ctxt->token != 0) {
                   7457:                    xmlChar cur[2] = { 0 , 0 } ;
                   7458: 
                   7459:                    cur[0] = (xmlChar) ctxt->token;
                   7460:                    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
                   7461:                        ctxt->sax->characters(ctxt->userData, cur, 1);
                   7462:                    ctxt->token = 0;
                   7463:                }
                   7464:                if (avail < 2)
                   7465:                    goto done;
                   7466:                cur = in->cur[0];
                   7467:                next = in->cur[1];
                   7468:                if ((cur == '<') && (next == '?')) {
1.143     daniel   7469:                    if ((!terminate) &&
                   7470:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
1.140     daniel   7471:                        goto done;
                   7472: #ifdef DEBUG_PUSH
                   7473:                    fprintf(stderr, "PP: Parsing PI\n");
                   7474: #endif
                   7475:                    xmlParsePI(ctxt);
                   7476:                } else if ((cur == '<') && (next == '!') &&
                   7477:                           (in->cur[2] == '-') && (in->cur[3] == '-')) {
1.143     daniel   7478:                    if ((!terminate) &&
                   7479:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
1.140     daniel   7480:                        goto done;
                   7481: #ifdef DEBUG_PUSH
                   7482:                    fprintf(stderr, "PP: Parsing Comment\n");
                   7483: #endif
                   7484:                    xmlParseComment(ctxt);
                   7485:                    ctxt->instate = XML_PARSER_CONTENT;
                   7486:                } else if ((cur == '<') && (in->cur[1] == '!') &&
                   7487:                    (in->cur[2] == '[') && (NXT(3) == 'C') &&
                   7488:                    (in->cur[4] == 'D') && (NXT(5) == 'A') &&
                   7489:                    (in->cur[6] == 'T') && (NXT(7) == 'A') &&
                   7490:                    (in->cur[8] == '[')) {
                   7491:                    SKIP(9);
                   7492:                    ctxt->instate = XML_PARSER_CDATA_SECTION;
                   7493: #ifdef DEBUG_PUSH
                   7494:                    fprintf(stderr, "PP: entering CDATA_SECTION\n");
                   7495: #endif
                   7496:                    break;
                   7497:                } else if ((cur == '<') && (next == '!') &&
                   7498:                           (avail < 9)) {
                   7499:                    goto done;
                   7500:                } else if ((cur == '<') && (next == '/')) {
                   7501:                    ctxt->instate = XML_PARSER_END_TAG;
                   7502: #ifdef DEBUG_PUSH
                   7503:                    fprintf(stderr, "PP: entering END_TAG\n");
                   7504: #endif
                   7505:                    break;
                   7506:                } else if (cur == '<') {
                   7507:                    ctxt->instate = XML_PARSER_START_TAG;
                   7508: #ifdef DEBUG_PUSH
                   7509:                    fprintf(stderr, "PP: entering START_TAG\n");
                   7510: #endif
                   7511:                    break;
                   7512:                } else if (cur == '&') {
1.143     daniel   7513:                    if ((!terminate) &&
                   7514:                        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
1.140     daniel   7515:                        goto done;
                   7516: #ifdef DEBUG_PUSH
                   7517:                    fprintf(stderr, "PP: Parsing Reference\n");
                   7518: #endif
                   7519:                    /* TODO: check generation of subtrees if noent !!! */
                   7520:                    xmlParseReference(ctxt);
                   7521:                } else {
                   7522:                    /* TODO Avoid the extra copy, handle directly !!!!!! */
                   7523:                    /*
                   7524:                     * Goal of the following test is :
                   7525:                     *  - minimize calls to the SAX 'character' callback
                   7526:                     *    when they are mergeable
                   7527:                     *  - handle an problem for isBlank when we only parse
                   7528:                     *    a sequence of blank chars and the next one is
                   7529:                     *    not available to check against '<' presence.
                   7530:                     *  - tries to homogenize the differences in SAX
                   7531:                     *    callbacks beween the push and pull versions
                   7532:                     *    of the parser.
                   7533:                     */
                   7534:                    if ((ctxt->inputNr == 1) &&
                   7535:                        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
1.143     daniel   7536:                        if ((!terminate) &&
                   7537:                            (xmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
1.140     daniel   7538:                            goto done;
                   7539:                     }
                   7540:                    ctxt->checkIndex = 0;
                   7541: #ifdef DEBUG_PUSH
                   7542:                    fprintf(stderr, "PP: Parsing char data\n");
                   7543: #endif
                   7544:                    xmlParseCharData(ctxt, 0);
                   7545:                }
                   7546:                /*
                   7547:                 * Pop-up of finished entities.
                   7548:                 */
                   7549:                while ((CUR == 0) && (ctxt->inputNr > 1))
                   7550:                    xmlPopInput(ctxt);
                   7551:                break;
                   7552:             case XML_PARSER_CDATA_SECTION: {
                   7553:                /*
                   7554:                 * The Push mode need to have the SAX callback for 
                   7555:                 * cdataBlock merge back contiguous callbacks.
                   7556:                 */
                   7557:                int base;
                   7558: 
                   7559:                in = ctxt->input;
                   7560:                base = xmlParseLookupSequence(ctxt, ']', ']', '>');
                   7561:                if (base < 0) {
                   7562:                    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
                   7563:                        if (ctxt->sax != NULL) {
                   7564:                            if (ctxt->sax->cdataBlock != NULL)
                   7565:                                ctxt->sax->cdataBlock(ctxt->userData, in->cur,
                   7566:                                          XML_PARSER_BIG_BUFFER_SIZE);
                   7567:                        }
                   7568:                        SKIP(XML_PARSER_BIG_BUFFER_SIZE);
                   7569:                        ctxt->checkIndex = 0;
                   7570:                    }
                   7571:                    goto done;
                   7572:                } else {
                   7573:                    if ((ctxt->sax != NULL) && (base > 0)) {
                   7574:                        if (ctxt->sax->cdataBlock != NULL)
                   7575:                            ctxt->sax->cdataBlock(ctxt->userData,
                   7576:                                                  in->cur, base);
                   7577:                    }
                   7578:                    SKIP(base + 3);
                   7579:                    ctxt->checkIndex = 0;
                   7580:                    ctxt->instate = XML_PARSER_CONTENT;
                   7581: #ifdef DEBUG_PUSH
                   7582:                    fprintf(stderr, "PP: entering CONTENT\n");
                   7583: #endif
                   7584:                }
                   7585:                break;
                   7586:            }
1.141     daniel   7587:             case XML_PARSER_END_TAG:
1.140     daniel   7588:                if (avail < 2)
                   7589:                    goto done;
1.143     daniel   7590:                if ((!terminate) &&
                   7591:                    (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
1.140     daniel   7592:                    goto done;
                   7593:                xmlParseEndTag(ctxt);
                   7594:                if (ctxt->name == NULL) {
                   7595:                    ctxt->instate = XML_PARSER_EPILOG;
                   7596: #ifdef DEBUG_PUSH
                   7597:                    fprintf(stderr, "PP: entering EPILOG\n");
                   7598: #endif
                   7599:                } else {
                   7600:                    ctxt->instate = XML_PARSER_CONTENT;
                   7601: #ifdef DEBUG_PUSH
                   7602:                    fprintf(stderr, "PP: entering CONTENT\n");
                   7603: #endif
                   7604:                }
                   7605:                break;
                   7606:             case XML_PARSER_DTD: {
                   7607:                /*
                   7608:                 * Sorry but progressive parsing of the internal subset
                   7609:                 * is not expected to be supported. We first check that
                   7610:                 * the full content of the internal subset is available and
                   7611:                 * the parsing is launched only at that point.
                   7612:                 * Internal subset ends up with "']' S? '>'" in an unescaped
                   7613:                 * section and not in a ']]>' sequence which are conditional
                   7614:                 * sections (whoever argued to keep that crap in XML deserve
                   7615:                 * a place in hell !).
                   7616:                 */
                   7617:                int base, i;
                   7618:                xmlChar *buf;
                   7619:                xmlChar quote = 0;
                   7620: 
                   7621:                base = in->cur - in->base;
                   7622:                if (base < 0) return(0);
                   7623:                if (ctxt->checkIndex > base)
                   7624:                    base = ctxt->checkIndex;
                   7625:                buf = in->buf->buffer->content;
                   7626:                for (;base < in->buf->buffer->use;base++) {
                   7627:                    if (quote != 0) {
                   7628:                        if (buf[base] == quote)
                   7629:                            quote = 0;
                   7630:                        continue;    
                   7631:                    }
                   7632:                    if (buf[base] == '"') {
                   7633:                        quote = '"';
                   7634:                        continue;
                   7635:                    }
                   7636:                    if (buf[base] == '\'') {
                   7637:                        quote = '\'';
                   7638:                        continue;
                   7639:                    }
                   7640:                    if (buf[base] == ']') {
                   7641:                        if (base +1 >= in->buf->buffer->use)
                   7642:                            break;
                   7643:                        if (buf[base + 1] == ']') {
                   7644:                            /* conditional crap, skip both ']' ! */
                   7645:                            base++;
                   7646:                            continue;
                   7647:                        }
                   7648:                        for (i = 0;base + i < in->buf->buffer->use;i++) {
                   7649:                            if (buf[base + i] == '>')
                   7650:                                goto found_end_int_subset;
                   7651:                        }
                   7652:                        break;
                   7653:                    }
                   7654:                }
                   7655:                /*
                   7656:                 * We didn't found the end of the Internal subset
                   7657:                 */
                   7658:                if (quote == 0) 
                   7659:                    ctxt->checkIndex = base;
                   7660: #ifdef DEBUG_PUSH
                   7661:                if (next == 0)
                   7662:                    fprintf(stderr, "PP: lookup of int subset end filed\n");
                   7663: #endif
                   7664:                goto done;
                   7665: 
                   7666: found_end_int_subset:
                   7667:                xmlParseInternalSubset(ctxt);
                   7668:                ctxt->instate = XML_PARSER_PROLOG;
                   7669:                ctxt->checkIndex = 0;
                   7670: #ifdef DEBUG_PUSH
                   7671:                fprintf(stderr, "PP: entering PROLOG\n");
                   7672: #endif
                   7673:                 break;
                   7674:            }
                   7675:             case XML_PARSER_COMMENT:
                   7676:                fprintf(stderr, "PP: internal error, state == COMMENT\n");
                   7677:                ctxt->instate = XML_PARSER_CONTENT;
                   7678: #ifdef DEBUG_PUSH
                   7679:                fprintf(stderr, "PP: entering CONTENT\n");
                   7680: #endif
                   7681:                break;
                   7682:             case XML_PARSER_PI:
                   7683:                fprintf(stderr, "PP: internal error, state == PI\n");
                   7684:                ctxt->instate = XML_PARSER_CONTENT;
                   7685: #ifdef DEBUG_PUSH
                   7686:                fprintf(stderr, "PP: entering CONTENT\n");
                   7687: #endif
                   7688:                break;
1.128     daniel   7689:             case XML_PARSER_ENTITY_DECL:
1.140     daniel   7690:                fprintf(stderr, "PP: internal error, state == ENTITY_DECL\n");
                   7691:                ctxt->instate = XML_PARSER_DTD;
                   7692: #ifdef DEBUG_PUSH
                   7693:                fprintf(stderr, "PP: entering DTD\n");
                   7694: #endif
                   7695:                break;
1.128     daniel   7696:             case XML_PARSER_ENTITY_VALUE:
1.140     daniel   7697:                fprintf(stderr, "PP: internal error, state == ENTITY_VALUE\n");
                   7698:                ctxt->instate = XML_PARSER_CONTENT;
                   7699: #ifdef DEBUG_PUSH
                   7700:                fprintf(stderr, "PP: entering DTD\n");
                   7701: #endif
                   7702:                break;
1.128     daniel   7703:             case XML_PARSER_ATTRIBUTE_VALUE:
1.140     daniel   7704:                fprintf(stderr, "PP: internal error, state == ATTRIBUTE_VALUE\n");
                   7705:                ctxt->instate = XML_PARSER_START_TAG;
                   7706: #ifdef DEBUG_PUSH
                   7707:                fprintf(stderr, "PP: entering START_TAG\n");
                   7708: #endif
                   7709:                break;
1.128     daniel   7710:        }
                   7711:     }
1.140     daniel   7712: done:    
                   7713: #ifdef DEBUG_PUSH
                   7714:     fprintf(stderr, "PP: done %d\n", ret);
                   7715: #endif
1.128     daniel   7716:     return(ret);
                   7717: }
                   7718: 
                   7719: /**
1.143     daniel   7720:  * xmlParseTry:
                   7721:  * @ctxt:  an XML parser context
                   7722:  *
                   7723:  * Try to progress on parsing
                   7724:  *
                   7725:  * Returns zero if no parsing was possible
                   7726:  */
                   7727: int
                   7728: xmlParseTry(xmlParserCtxtPtr ctxt) {
                   7729:     return(xmlParseTryOrFinish(ctxt, 0));
                   7730: }
                   7731: 
                   7732: /**
1.128     daniel   7733:  * xmlParseChunk:
                   7734:  * @ctxt:  an XML parser context
                   7735:  * @chunk:  an char array
                   7736:  * @size:  the size in byte of the chunk
                   7737:  * @terminate:  last chunk indicator
                   7738:  *
                   7739:  * Parse a Chunk of memory
                   7740:  *
                   7741:  * Returns zero if no error, the xmlParserErrors otherwise.
                   7742:  */
1.140     daniel   7743: int
1.128     daniel   7744: xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
                   7745:               int terminate) {
1.132     daniel   7746:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
1.140     daniel   7747:         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
                   7748:        int base = ctxt->input->base - ctxt->input->buf->buffer->content;
                   7749:        int cur = ctxt->input->cur - ctxt->input->base;
                   7750:        
1.132     daniel   7751:        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);              
1.140     daniel   7752:        ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   7753:        ctxt->input->cur = ctxt->input->base + cur;
                   7754: #ifdef DEBUG_PUSH
                   7755:        fprintf(stderr, "PP: pushed %d\n", size);
                   7756: #endif
                   7757: 
1.143     daniel   7758:         xmlParseTryOrFinish(ctxt, terminate);
1.140     daniel   7759:     } else if (ctxt->instate != XML_PARSER_EOF)
1.143     daniel   7760:         xmlParseTryOrFinish(ctxt, terminate);
1.140     daniel   7761:     if (terminate) {
                   7762:        if ((ctxt->instate != XML_PARSER_EOF) &&
                   7763:            (ctxt->instate != XML_PARSER_EPILOG)) {
                   7764:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   7765:                ctxt->sax->error(ctxt->userData,
                   7766:                    "Extra content at the end of the document\n");
                   7767:            ctxt->wellFormed = 0;
                   7768:            ctxt->errNo = XML_ERR_DOCUMENT_END;
                   7769:        } 
                   7770:        if (ctxt->instate != XML_PARSER_EOF) {
                   7771:            if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   7772:                ctxt->sax->endDocument(ctxt->userData);
                   7773:        }
                   7774:        ctxt->instate = XML_PARSER_EOF;
1.128     daniel   7775:     }
                   7776:     return((xmlParserErrors) ctxt->errNo);           
                   7777: }
                   7778: 
                   7779: /************************************************************************
                   7780:  *                                                                     *
1.98      daniel   7781:  *             I/O front end functions to the parser                   *
                   7782:  *                                                                     *
                   7783:  ************************************************************************/
                   7784: 
1.50      daniel   7785: /**
1.140     daniel   7786:  * xmlCreatePushParserCtxt :
                   7787:  * @sax:  a SAX handler
                   7788:  * @user_data:  The user data returned on SAX callbacks
                   7789:  * @chunk:  a pointer to an array of chars
                   7790:  * @size:  number of chars in the array
                   7791:  * @filename:  an optional file name or URI
                   7792:  *
                   7793:  * Create a parser context for using the XML parser in push mode
                   7794:  * To allow content encoding detection, @size should be >= 4
                   7795:  * The value of @filename is used for fetching external entities
                   7796:  * and error/warning reports.
                   7797:  *
                   7798:  * Returns the new parser context or NULL
                   7799:  */
                   7800: xmlParserCtxtPtr
                   7801: xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, 
                   7802:                         const char *chunk, int size, const char *filename) {
                   7803:     xmlParserCtxtPtr ctxt;
                   7804:     xmlParserInputPtr inputStream;
                   7805:     xmlParserInputBufferPtr buf;
                   7806:     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
                   7807: 
                   7808:     /*
                   7809:      * plug some encoding conversion routines here. !!!
                   7810:      */
                   7811:     if ((chunk != NULL) && (size >= 4))
                   7812:        enc = xmlDetectCharEncoding((const xmlChar *) chunk);
                   7813: 
                   7814:     buf = xmlAllocParserInputBuffer(enc);
                   7815:     if (buf == NULL) return(NULL);
                   7816: 
                   7817:     ctxt = xmlNewParserCtxt();
                   7818:     if (ctxt == NULL) {
                   7819:        xmlFree(buf);
                   7820:        return(NULL);
                   7821:     }
                   7822:     if (sax != NULL) {
                   7823:        if (ctxt->sax != &xmlDefaultSAXHandler)
                   7824:            xmlFree(ctxt->sax);
                   7825:        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
                   7826:        if (ctxt->sax == NULL) {
                   7827:            xmlFree(buf);
                   7828:            xmlFree(ctxt);
                   7829:            return(NULL);
                   7830:        }
                   7831:        memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
                   7832:        if (user_data != NULL)
                   7833:            ctxt->userData = user_data;
                   7834:     }  
                   7835:     if (filename == NULL) {
                   7836:        ctxt->directory = NULL;
                   7837:     } else {
                   7838:         ctxt->directory = xmlParserGetDirectory(filename);
                   7839:     }
                   7840: 
                   7841:     inputStream = xmlNewInputStream(ctxt);
                   7842:     if (inputStream == NULL) {
                   7843:        xmlFreeParserCtxt(ctxt);
                   7844:        return(NULL);
                   7845:     }
                   7846: 
                   7847:     if (filename == NULL)
                   7848:        inputStream->filename = NULL;
                   7849:     else
                   7850:        inputStream->filename = xmlMemStrdup(filename);
                   7851:     inputStream->buf = buf;
                   7852:     inputStream->base = inputStream->buf->buffer->content;
                   7853:     inputStream->cur = inputStream->buf->buffer->content;
                   7854: 
                   7855:     inputPush(ctxt, inputStream);
                   7856: 
                   7857:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
                   7858:         (ctxt->input->buf != NULL))  {       
                   7859:        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);              
                   7860: #ifdef DEBUG_PUSH
                   7861:        fprintf(stderr, "PP: pushed %d\n", size);
                   7862: #endif
                   7863:     }
                   7864: 
                   7865:     return(ctxt);
                   7866: }
                   7867: 
                   7868: /**
1.86      daniel   7869:  * xmlCreateDocParserCtxt :
1.123     daniel   7870:  * @cur:  a pointer to an array of xmlChar
1.50      daniel   7871:  *
1.69      daniel   7872:  * Create a parser context for an XML in-memory document.
                   7873:  *
                   7874:  * Returns the new parser context or NULL
1.16      daniel   7875:  */
1.69      daniel   7876: xmlParserCtxtPtr
1.123     daniel   7877: xmlCreateDocParserCtxt(xmlChar *cur) {
1.16      daniel   7878:     xmlParserCtxtPtr ctxt;
1.40      daniel   7879:     xmlParserInputPtr input;
1.75      daniel   7880:     xmlCharEncoding enc;
1.16      daniel   7881: 
1.97      daniel   7882:     ctxt = xmlNewParserCtxt();
1.16      daniel   7883:     if (ctxt == NULL) {
                   7884:        return(NULL);
                   7885:     }
1.96      daniel   7886:     input = xmlNewInputStream(ctxt);
1.40      daniel   7887:     if (input == NULL) {
1.97      daniel   7888:        xmlFreeParserCtxt(ctxt);
1.40      daniel   7889:        return(NULL);
                   7890:     }
                   7891: 
1.75      daniel   7892:     /*
                   7893:      * plug some encoding conversion routines here. !!!
                   7894:      */
                   7895:     enc = xmlDetectCharEncoding(cur);
                   7896:     xmlSwitchEncoding(ctxt, enc);
                   7897: 
1.40      daniel   7898:     input->base = cur;
                   7899:     input->cur = cur;
                   7900: 
                   7901:     inputPush(ctxt, input);
1.69      daniel   7902:     return(ctxt);
                   7903: }
                   7904: 
                   7905: /**
                   7906:  * xmlSAXParseDoc :
                   7907:  * @sax:  the SAX handler block
1.123     daniel   7908:  * @cur:  a pointer to an array of xmlChar
1.69      daniel   7909:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   7910:  *             documents
                   7911:  *
                   7912:  * parse an XML in-memory document and build a tree.
                   7913:  * It use the given SAX function block to handle the parsing callback.
                   7914:  * If sax is NULL, fallback to the default DOM tree building routines.
                   7915:  * 
                   7916:  * Returns the resulting document tree
                   7917:  */
                   7918: 
                   7919: xmlDocPtr
1.123     daniel   7920: xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar *cur, int recovery) {
1.69      daniel   7921:     xmlDocPtr ret;
                   7922:     xmlParserCtxtPtr ctxt;
                   7923: 
                   7924:     if (cur == NULL) return(NULL);
1.16      daniel   7925: 
                   7926: 
1.69      daniel   7927:     ctxt = xmlCreateDocParserCtxt(cur);
                   7928:     if (ctxt == NULL) return(NULL);
1.74      daniel   7929:     if (sax != NULL) { 
                   7930:         ctxt->sax = sax;
                   7931:         ctxt->userData = NULL;
                   7932:     }
1.69      daniel   7933: 
1.16      daniel   7934:     xmlParseDocument(ctxt);
1.72      daniel   7935:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
1.59      daniel   7936:     else {
                   7937:        ret = NULL;
1.72      daniel   7938:        xmlFreeDoc(ctxt->myDoc);
                   7939:        ctxt->myDoc = NULL;
1.59      daniel   7940:     }
1.86      daniel   7941:     if (sax != NULL) 
                   7942:        ctxt->sax = NULL;
1.69      daniel   7943:     xmlFreeParserCtxt(ctxt);
1.16      daniel   7944:     
1.1       veillard 7945:     return(ret);
                   7946: }
                   7947: 
1.50      daniel   7948: /**
1.55      daniel   7949:  * xmlParseDoc :
1.123     daniel   7950:  * @cur:  a pointer to an array of xmlChar
1.55      daniel   7951:  *
                   7952:  * parse an XML in-memory document and build a tree.
                   7953:  * 
1.68      daniel   7954:  * Returns the resulting document tree
1.55      daniel   7955:  */
                   7956: 
1.69      daniel   7957: xmlDocPtr
1.123     daniel   7958: xmlParseDoc(xmlChar *cur) {
1.59      daniel   7959:     return(xmlSAXParseDoc(NULL, cur, 0));
1.76      daniel   7960: }
                   7961: 
                   7962: /**
                   7963:  * xmlSAXParseDTD :
                   7964:  * @sax:  the SAX handler block
                   7965:  * @ExternalID:  a NAME* containing the External ID of the DTD
                   7966:  * @SystemID:  a NAME* containing the URL to the DTD
                   7967:  *
                   7968:  * Load and parse an external subset.
                   7969:  * 
                   7970:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   7971:  */
                   7972: 
                   7973: xmlDtdPtr
1.123     daniel   7974: xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
                   7975:                           const xmlChar *SystemID) {
1.76      daniel   7976:     xmlDtdPtr ret = NULL;
                   7977:     xmlParserCtxtPtr ctxt;
1.83      daniel   7978:     xmlParserInputPtr input = NULL;
1.76      daniel   7979:     xmlCharEncoding enc;
                   7980: 
                   7981:     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
                   7982: 
1.97      daniel   7983:     ctxt = xmlNewParserCtxt();
1.76      daniel   7984:     if (ctxt == NULL) {
                   7985:        return(NULL);
                   7986:     }
                   7987: 
                   7988:     /*
                   7989:      * Set-up the SAX context
                   7990:      */
                   7991:     if (ctxt == NULL) return(NULL);
                   7992:     if (sax != NULL) { 
1.93      veillard 7993:        if (ctxt->sax != NULL)
1.119     daniel   7994:            xmlFree(ctxt->sax);
1.76      daniel   7995:         ctxt->sax = sax;
                   7996:         ctxt->userData = NULL;
                   7997:     }
                   7998: 
                   7999:     /*
                   8000:      * Ask the Entity resolver to load the damn thing
                   8001:      */
                   8002: 
                   8003:     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
                   8004:        input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, SystemID);
                   8005:     if (input == NULL) {
1.86      daniel   8006:         if (sax != NULL) ctxt->sax = NULL;
1.76      daniel   8007:        xmlFreeParserCtxt(ctxt);
                   8008:        return(NULL);
                   8009:     }
                   8010: 
                   8011:     /*
                   8012:      * plug some encoding conversion routines here. !!!
                   8013:      */
                   8014:     xmlPushInput(ctxt, input);
                   8015:     enc = xmlDetectCharEncoding(ctxt->input->cur);
                   8016:     xmlSwitchEncoding(ctxt, enc);
                   8017: 
1.95      veillard 8018:     if (input->filename == NULL)
1.116     daniel   8019:        input->filename = (char *) xmlStrdup(SystemID); /* !!!!!!! */
1.76      daniel   8020:     input->line = 1;
                   8021:     input->col = 1;
                   8022:     input->base = ctxt->input->cur;
                   8023:     input->cur = ctxt->input->cur;
                   8024:     input->free = NULL;
                   8025: 
                   8026:     /*
                   8027:      * let's parse that entity knowing it's an external subset.
                   8028:      */
1.79      daniel   8029:     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
1.76      daniel   8030: 
                   8031:     if (ctxt->myDoc != NULL) {
                   8032:        if (ctxt->wellFormed) {
                   8033:            ret = ctxt->myDoc->intSubset;
                   8034:            ctxt->myDoc->intSubset = NULL;
                   8035:        } else {
                   8036:            ret = NULL;
                   8037:        }
                   8038:         xmlFreeDoc(ctxt->myDoc);
                   8039:         ctxt->myDoc = NULL;
                   8040:     }
1.86      daniel   8041:     if (sax != NULL) ctxt->sax = NULL;
1.76      daniel   8042:     xmlFreeParserCtxt(ctxt);
                   8043:     
                   8044:     return(ret);
                   8045: }
                   8046: 
                   8047: /**
                   8048:  * xmlParseDTD :
                   8049:  * @ExternalID:  a NAME* containing the External ID of the DTD
                   8050:  * @SystemID:  a NAME* containing the URL to the DTD
                   8051:  *
                   8052:  * Load and parse an external subset.
                   8053:  * 
                   8054:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   8055:  */
                   8056: 
                   8057: xmlDtdPtr
1.123     daniel   8058: xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
1.76      daniel   8059:     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
1.59      daniel   8060: }
                   8061: 
                   8062: /**
1.144     daniel   8063:  * xmlSAXParseBalancedChunk :
                   8064:  * @ctx:  an XML parser context (possibly NULL)
                   8065:  * @sax:  the SAX handler bloc (possibly NULL)
                   8066:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   8067:  * @input:  a parser input stream
                   8068:  * @enc:  the encoding
                   8069:  *
                   8070:  * Parse a well-balanced chunk of an XML document
                   8071:  * The user has to provide SAX callback block whose routines will be
                   8072:  * called by the parser
                   8073:  * The allowed sequence for the Well Balanced Chunk is the one defined by
                   8074:  * the content production in the XML grammar:
                   8075:  *
                   8076:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   8077:  *
                   8078:  * Returns 0 id the chunk is well balanced, -1 in case of args problem and
                   8079:  *    the error code otherwise
                   8080:  */
                   8081: 
                   8082: int
                   8083: xmlSAXParseBalancedChunk(xmlParserCtxtPtr ctx, xmlSAXHandlerPtr sax,
                   8084:                          void *user_data, xmlParserInputPtr input,
                   8085:                         xmlCharEncoding enc) {
                   8086:     xmlParserCtxtPtr ctxt;
                   8087:     int ret;
                   8088: 
                   8089:     if (input == NULL) return(-1);
                   8090: 
                   8091:     if (ctx != NULL)
                   8092:         ctxt = ctx;
                   8093:     else {     
                   8094:        ctxt = xmlNewParserCtxt();
                   8095:        if (ctxt == NULL)
                   8096:            return(-1);
                   8097:         if (sax == NULL)
                   8098:            ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
                   8099:     }  
                   8100: 
                   8101:     /*
                   8102:      * Set-up the SAX context
                   8103:      */
                   8104:     if (sax != NULL) {
                   8105:        if (ctxt->sax != NULL)
                   8106:            xmlFree(ctxt->sax);
                   8107:        ctxt->sax = sax;
                   8108:        ctxt->userData = user_data;
                   8109:     }
                   8110: 
                   8111:     /*
                   8112:      * plug some encoding conversion routines here.
                   8113:      */
                   8114:     xmlPushInput(ctxt, input);
                   8115:     if (enc != XML_CHAR_ENCODING_NONE)
                   8116:        xmlSwitchEncoding(ctxt, enc);
                   8117: 
                   8118:     /*
                   8119:      * let's parse that entity knowing it's an external subset.
                   8120:      */
                   8121:     xmlParseContent(ctxt);
                   8122:     ret = ctxt->errNo;
                   8123: 
                   8124:     if (ctx == NULL) {
                   8125:        if (sax != NULL) 
                   8126:            ctxt->sax = NULL;
                   8127:        else
                   8128:            xmlFreeDoc(ctxt->myDoc);
                   8129:        xmlFreeParserCtxt(ctxt);
                   8130:     }
                   8131:     return(ret);
                   8132: }
                   8133: 
                   8134: /**
                   8135:  * xmlParseBalancedChunk :
                   8136:  * @doc:  the document the chunk pertains to
                   8137:  * @node:  the node defining the context in which informations will be added
                   8138:  *
                   8139:  * Parse a well-balanced chunk of an XML document present in memory
                   8140:  * 
                   8141:  * Returns the resulting list of nodes resulting from the parsing,
                   8142:  *     they are not added to @node
                   8143:  */
                   8144: 
                   8145: xmlNodePtr
                   8146: xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlNodePtr node) {
                   8147: }
                   8148: 
                   8149: /**
                   8150:  * xmlParseBalancedChunkFile :
                   8151:  * @doc:  the document the chunk pertains to
                   8152:  *
                   8153:  * Parse a well-balanced chunk of an XML document contained in a file
                   8154:  * 
                   8155:  * Returns the resulting list of nodes resulting from the parsing,
                   8156:  *     they are not added to @node
                   8157:  */
                   8158: 
                   8159: xmlNodePtr
                   8160: xmlParseBalancedChunkFile(xmlDocPtr doc, xmlNodePtr node) {
                   8161: }
                   8162: 
                   8163: /**
1.59      daniel   8164:  * xmlRecoverDoc :
1.123     daniel   8165:  * @cur:  a pointer to an array of xmlChar
1.59      daniel   8166:  *
                   8167:  * parse an XML in-memory document and build a tree.
                   8168:  * In the case the document is not Well Formed, a tree is built anyway
                   8169:  * 
1.68      daniel   8170:  * Returns the resulting document tree
1.59      daniel   8171:  */
                   8172: 
1.69      daniel   8173: xmlDocPtr
1.123     daniel   8174: xmlRecoverDoc(xmlChar *cur) {
1.59      daniel   8175:     return(xmlSAXParseDoc(NULL, cur, 1));
1.55      daniel   8176: }
                   8177: 
                   8178: /**
1.69      daniel   8179:  * xmlCreateFileParserCtxt :
1.50      daniel   8180:  * @filename:  the filename
                   8181:  *
1.69      daniel   8182:  * Create a parser context for a file content. 
                   8183:  * Automatic support for ZLIB/Compress compressed document is provided
                   8184:  * by default if found at compile-time.
1.50      daniel   8185:  *
1.69      daniel   8186:  * Returns the new parser context or NULL
1.9       httpng   8187:  */
1.69      daniel   8188: xmlParserCtxtPtr
                   8189: xmlCreateFileParserCtxt(const char *filename)
                   8190: {
                   8191:     xmlParserCtxtPtr ctxt;
1.40      daniel   8192:     xmlParserInputPtr inputStream;
1.91      daniel   8193:     xmlParserInputBufferPtr buf;
1.111     daniel   8194:     char *directory = NULL;
1.9       httpng   8195: 
1.91      daniel   8196:     buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
                   8197:     if (buf == NULL) return(NULL);
1.9       httpng   8198: 
1.97      daniel   8199:     ctxt = xmlNewParserCtxt();
1.16      daniel   8200:     if (ctxt == NULL) {
                   8201:        return(NULL);
                   8202:     }
1.97      daniel   8203: 
1.96      daniel   8204:     inputStream = xmlNewInputStream(ctxt);
1.40      daniel   8205:     if (inputStream == NULL) {
1.97      daniel   8206:        xmlFreeParserCtxt(ctxt);
1.40      daniel   8207:        return(NULL);
                   8208:     }
                   8209: 
1.119     daniel   8210:     inputStream->filename = xmlMemStrdup(filename);
1.91      daniel   8211:     inputStream->buf = buf;
                   8212:     inputStream->base = inputStream->buf->buffer->content;
                   8213:     inputStream->cur = inputStream->buf->buffer->content;
1.16      daniel   8214: 
1.40      daniel   8215:     inputPush(ctxt, inputStream);
1.110     daniel   8216:     if ((ctxt->directory == NULL) && (directory == NULL))
1.106     daniel   8217:         directory = xmlParserGetDirectory(filename);
                   8218:     if ((ctxt->directory == NULL) && (directory != NULL))
1.110     daniel   8219:         ctxt->directory = directory;
1.106     daniel   8220: 
1.69      daniel   8221:     return(ctxt);
                   8222: }
                   8223: 
                   8224: /**
                   8225:  * xmlSAXParseFile :
                   8226:  * @sax:  the SAX handler block
                   8227:  * @filename:  the filename
                   8228:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   8229:  *             documents
                   8230:  *
                   8231:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   8232:  * compressed document is provided by default if found at compile-time.
                   8233:  * It use the given SAX function block to handle the parsing callback.
                   8234:  * If sax is NULL, fallback to the default DOM tree building routines.
                   8235:  *
                   8236:  * Returns the resulting document tree
                   8237:  */
                   8238: 
1.79      daniel   8239: xmlDocPtr
                   8240: xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
1.69      daniel   8241:                           int recovery) {
                   8242:     xmlDocPtr ret;
                   8243:     xmlParserCtxtPtr ctxt;
1.111     daniel   8244:     char *directory = NULL;
1.69      daniel   8245: 
                   8246:     ctxt = xmlCreateFileParserCtxt(filename);
                   8247:     if (ctxt == NULL) return(NULL);
1.74      daniel   8248:     if (sax != NULL) {
1.93      veillard 8249:        if (ctxt->sax != NULL)
1.119     daniel   8250:            xmlFree(ctxt->sax);
1.74      daniel   8251:         ctxt->sax = sax;
                   8252:         ctxt->userData = NULL;
                   8253:     }
1.106     daniel   8254: 
1.110     daniel   8255:     if ((ctxt->directory == NULL) && (directory == NULL))
1.106     daniel   8256:         directory = xmlParserGetDirectory(filename);
                   8257:     if ((ctxt->directory == NULL) && (directory != NULL))
1.123     daniel   8258:         ctxt->directory = (char *) xmlStrdup((xmlChar *) directory); /* !!!!!!! */
1.16      daniel   8259: 
                   8260:     xmlParseDocument(ctxt);
1.40      daniel   8261: 
1.72      daniel   8262:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
1.59      daniel   8263:     else {
                   8264:        ret = NULL;
1.72      daniel   8265:        xmlFreeDoc(ctxt->myDoc);
                   8266:        ctxt->myDoc = NULL;
1.59      daniel   8267:     }
1.86      daniel   8268:     if (sax != NULL)
                   8269:         ctxt->sax = NULL;
1.69      daniel   8270:     xmlFreeParserCtxt(ctxt);
1.20      daniel   8271:     
                   8272:     return(ret);
                   8273: }
                   8274: 
1.55      daniel   8275: /**
                   8276:  * xmlParseFile :
                   8277:  * @filename:  the filename
                   8278:  *
                   8279:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   8280:  * compressed document is provided by default if found at compile-time.
                   8281:  *
1.68      daniel   8282:  * Returns the resulting document tree
1.55      daniel   8283:  */
                   8284: 
1.79      daniel   8285: xmlDocPtr
                   8286: xmlParseFile(const char *filename) {
1.59      daniel   8287:     return(xmlSAXParseFile(NULL, filename, 0));
                   8288: }
                   8289: 
                   8290: /**
                   8291:  * xmlRecoverFile :
                   8292:  * @filename:  the filename
                   8293:  *
                   8294:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   8295:  * compressed document is provided by default if found at compile-time.
                   8296:  * In the case the document is not Well Formed, a tree is built anyway
                   8297:  *
1.68      daniel   8298:  * Returns the resulting document tree
1.59      daniel   8299:  */
                   8300: 
1.79      daniel   8301: xmlDocPtr
                   8302: xmlRecoverFile(const char *filename) {
1.59      daniel   8303:     return(xmlSAXParseFile(NULL, filename, 1));
1.55      daniel   8304: }
1.32      daniel   8305: 
1.50      daniel   8306: /**
1.69      daniel   8307:  * xmlCreateMemoryParserCtxt :
1.68      daniel   8308:  * @buffer:  an pointer to a char array
1.127     daniel   8309:  * @size:  the size of the array
1.50      daniel   8310:  *
1.69      daniel   8311:  * Create a parser context for an XML in-memory document.
1.50      daniel   8312:  *
1.69      daniel   8313:  * Returns the new parser context or NULL
1.20      daniel   8314:  */
1.69      daniel   8315: xmlParserCtxtPtr
                   8316: xmlCreateMemoryParserCtxt(char *buffer, int size) {
1.20      daniel   8317:     xmlParserCtxtPtr ctxt;
1.40      daniel   8318:     xmlParserInputPtr input;
1.75      daniel   8319:     xmlCharEncoding enc;
1.40      daniel   8320: 
                   8321:     buffer[size - 1] = '\0';
                   8322: 
1.97      daniel   8323:     ctxt = xmlNewParserCtxt();
1.20      daniel   8324:     if (ctxt == NULL) {
                   8325:        return(NULL);
                   8326:     }
1.97      daniel   8327: 
1.96      daniel   8328:     input = xmlNewInputStream(ctxt);
1.40      daniel   8329:     if (input == NULL) {
1.97      daniel   8330:        xmlFreeParserCtxt(ctxt);
1.40      daniel   8331:        return(NULL);
                   8332:     }
1.20      daniel   8333: 
1.40      daniel   8334:     input->filename = NULL;
                   8335:     input->line = 1;
                   8336:     input->col = 1;
1.96      daniel   8337:     input->buf = NULL;
1.91      daniel   8338:     input->consumed = 0;
1.45      daniel   8339: 
                   8340:     /*
1.75      daniel   8341:      * plug some encoding conversion routines here. !!!
1.45      daniel   8342:      */
1.116     daniel   8343:     enc = xmlDetectCharEncoding(BAD_CAST buffer);
1.75      daniel   8344:     xmlSwitchEncoding(ctxt, enc);
                   8345: 
1.116     daniel   8346:     input->base = BAD_CAST buffer;
                   8347:     input->cur = BAD_CAST buffer;
1.69      daniel   8348:     input->free = NULL;
1.20      daniel   8349: 
1.40      daniel   8350:     inputPush(ctxt, input);
1.69      daniel   8351:     return(ctxt);
                   8352: }
                   8353: 
                   8354: /**
                   8355:  * xmlSAXParseMemory :
                   8356:  * @sax:  the SAX handler block
                   8357:  * @buffer:  an pointer to a char array
1.127     daniel   8358:  * @size:  the size of the array
                   8359:  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
1.69      daniel   8360:  *             documents
                   8361:  *
                   8362:  * parse an XML in-memory block and use the given SAX function block
                   8363:  * to handle the parsing callback. If sax is NULL, fallback to the default
                   8364:  * DOM tree building routines.
                   8365:  * 
                   8366:  * Returns the resulting document tree
                   8367:  */
                   8368: xmlDocPtr
                   8369: xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer, int size, int recovery) {
                   8370:     xmlDocPtr ret;
                   8371:     xmlParserCtxtPtr ctxt;
                   8372: 
                   8373:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   8374:     if (ctxt == NULL) return(NULL);
1.74      daniel   8375:     if (sax != NULL) {
                   8376:         ctxt->sax = sax;
                   8377:         ctxt->userData = NULL;
                   8378:     }
1.20      daniel   8379: 
                   8380:     xmlParseDocument(ctxt);
1.40      daniel   8381: 
1.72      daniel   8382:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
1.59      daniel   8383:     else {
                   8384:        ret = NULL;
1.72      daniel   8385:        xmlFreeDoc(ctxt->myDoc);
                   8386:        ctxt->myDoc = NULL;
1.59      daniel   8387:     }
1.86      daniel   8388:     if (sax != NULL) 
                   8389:        ctxt->sax = NULL;
1.69      daniel   8390:     xmlFreeParserCtxt(ctxt);
1.16      daniel   8391:     
1.9       httpng   8392:     return(ret);
1.17      daniel   8393: }
                   8394: 
1.55      daniel   8395: /**
                   8396:  * xmlParseMemory :
1.68      daniel   8397:  * @buffer:  an pointer to a char array
1.55      daniel   8398:  * @size:  the size of the array
                   8399:  *
                   8400:  * parse an XML in-memory block and build a tree.
                   8401:  * 
1.68      daniel   8402:  * Returns the resulting document tree
1.55      daniel   8403:  */
                   8404: 
                   8405: xmlDocPtr xmlParseMemory(char *buffer, int size) {
1.59      daniel   8406:    return(xmlSAXParseMemory(NULL, buffer, size, 0));
                   8407: }
                   8408: 
                   8409: /**
                   8410:  * xmlRecoverMemory :
1.68      daniel   8411:  * @buffer:  an pointer to a char array
1.59      daniel   8412:  * @size:  the size of the array
                   8413:  *
                   8414:  * parse an XML in-memory block and build a tree.
                   8415:  * In the case the document is not Well Formed, a tree is built anyway
                   8416:  * 
1.68      daniel   8417:  * Returns the resulting document tree
1.59      daniel   8418:  */
                   8419: 
                   8420: xmlDocPtr xmlRecoverMemory(char *buffer, int size) {
                   8421:    return(xmlSAXParseMemory(NULL, buffer, size, 1));
1.17      daniel   8422: }
                   8423: 
                   8424: 
1.50      daniel   8425: /**
                   8426:  * xmlSetupParserForBuffer:
                   8427:  * @ctxt:  an XML parser context
1.123     daniel   8428:  * @buffer:  a xmlChar * buffer
1.50      daniel   8429:  * @filename:  a file name
                   8430:  *
1.19      daniel   8431:  * Setup the parser context to parse a new buffer; Clears any prior
                   8432:  * contents from the parser context. The buffer parameter must not be
                   8433:  * NULL, but the filename parameter can be
                   8434:  */
1.55      daniel   8435: void
1.123     daniel   8436: xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
1.17      daniel   8437:                              const char* filename)
                   8438: {
1.96      daniel   8439:     xmlParserInputPtr input;
1.40      daniel   8440: 
1.96      daniel   8441:     input = xmlNewInputStream(ctxt);
                   8442:     if (input == NULL) {
                   8443:         perror("malloc");
1.119     daniel   8444:         xmlFree(ctxt);
1.145     daniel   8445:         return;
1.96      daniel   8446:     }
                   8447:   
                   8448:     xmlClearParserCtxt(ctxt);
                   8449:     if (filename != NULL)
1.119     daniel   8450:         input->filename = xmlMemStrdup(filename);
1.96      daniel   8451:     input->base = buffer;
                   8452:     input->cur = buffer;
                   8453:     inputPush(ctxt, input);
1.17      daniel   8454: }
                   8455: 
1.123     daniel   8456: /**
                   8457:  * xmlSAXUserParseFile:
                   8458:  * @sax:  a SAX handler
                   8459:  * @user_data:  The user data returned on SAX callbacks
                   8460:  * @filename:  a file name
                   8461:  *
                   8462:  * parse an XML file and call the given SAX handler routines.
                   8463:  * Automatic support for ZLIB/Compress compressed document is provided
                   8464:  * 
                   8465:  * Returns 0 in case of success or a error number otherwise
                   8466:  */
1.131     daniel   8467: int
                   8468: xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
                   8469:                     const char *filename) {
1.123     daniel   8470:     int ret = 0;
                   8471:     xmlParserCtxtPtr ctxt;
                   8472:     
                   8473:     ctxt = xmlCreateFileParserCtxt(filename);
                   8474:     if (ctxt == NULL) return -1;
1.134     daniel   8475:     if (ctxt->sax != &xmlDefaultSAXHandler)
                   8476:        xmlFree(ctxt->sax);
1.123     daniel   8477:     ctxt->sax = sax;
1.140     daniel   8478:     if (user_data != NULL)
                   8479:        ctxt->userData = user_data;
1.123     daniel   8480:     
                   8481:     xmlParseDocument(ctxt);
                   8482:     
                   8483:     if (ctxt->wellFormed)
                   8484:        ret = 0;
                   8485:     else {
                   8486:         if (ctxt->errNo != 0)
                   8487:            ret = ctxt->errNo;
                   8488:        else
                   8489:            ret = -1;
                   8490:     }
                   8491:     if (sax != NULL)
                   8492:        ctxt->sax = NULL;
                   8493:     xmlFreeParserCtxt(ctxt);
                   8494:     
                   8495:     return ret;
                   8496: }
                   8497: 
                   8498: /**
                   8499:  * xmlSAXUserParseMemory:
                   8500:  * @sax:  a SAX handler
                   8501:  * @user_data:  The user data returned on SAX callbacks
                   8502:  * @buffer:  an in-memory XML document input
1.127     daniel   8503:  * @size:  the length of the XML document in bytes
1.123     daniel   8504:  *
                   8505:  * A better SAX parsing routine.
                   8506:  * parse an XML in-memory buffer and call the given SAX handler routines.
                   8507:  * 
                   8508:  * Returns 0 in case of success or a error number otherwise
                   8509:  */
                   8510: int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
                   8511:                          char *buffer, int size) {
                   8512:     int ret = 0;
                   8513:     xmlParserCtxtPtr ctxt;
                   8514:     
                   8515:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   8516:     if (ctxt == NULL) return -1;
                   8517:     ctxt->sax = sax;
                   8518:     ctxt->userData = user_data;
                   8519:     
                   8520:     xmlParseDocument(ctxt);
                   8521:     
                   8522:     if (ctxt->wellFormed)
                   8523:        ret = 0;
                   8524:     else {
                   8525:         if (ctxt->errNo != 0)
                   8526:            ret = ctxt->errNo;
                   8527:        else
                   8528:            ret = -1;
                   8529:     }
                   8530:     if (sax != NULL)
                   8531:        ctxt->sax = NULL;
                   8532:     xmlFreeParserCtxt(ctxt);
                   8533:     
                   8534:     return ret;
                   8535: }
                   8536: 
1.32      daniel   8537: 
1.98      daniel   8538: /************************************************************************
                   8539:  *                                                                     *
1.127     daniel   8540:  *                             Miscellaneous                           *
1.98      daniel   8541:  *                                                                     *
                   8542:  ************************************************************************/
                   8543: 
1.132     daniel   8544: /**
                   8545:  * xmlCleanupParser:
                   8546:  *
                   8547:  * Cleanup function for the XML parser. It tries to reclaim all
                   8548:  * parsing related global memory allocated for the parser processing.
                   8549:  * It doesn't deallocate any document related memory. Calling this
                   8550:  * function should not prevent reusing the parser.
                   8551:  */
                   8552: 
                   8553: void
                   8554: xmlCleanupParser(void) {
                   8555:     xmlCleanupCharEncodingHandlers();
1.133     daniel   8556:     xmlCleanupPredefinedEntities();
1.132     daniel   8557: }
1.98      daniel   8558: 
1.50      daniel   8559: /**
                   8560:  * xmlParserFindNodeInfo:
                   8561:  * @ctxt:  an XML parser context
                   8562:  * @node:  an XML node within the tree
                   8563:  *
                   8564:  * Find the parser node info struct for a given node
                   8565:  * 
1.68      daniel   8566:  * Returns an xmlParserNodeInfo block pointer or NULL
1.32      daniel   8567:  */
                   8568: const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* ctx,
                   8569:                                                const xmlNode* node)
                   8570: {
                   8571:   unsigned long pos;
                   8572: 
                   8573:   /* Find position where node should be at */
                   8574:   pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
                   8575:   if ( ctx->node_seq.buffer[pos].node == node )
                   8576:     return &ctx->node_seq.buffer[pos];
                   8577:   else
                   8578:     return NULL;
                   8579: }
                   8580: 
                   8581: 
1.50      daniel   8582: /**
                   8583:  * xmlInitNodeInfoSeq :
                   8584:  * @seq:  a node info sequence pointer
                   8585:  *
                   8586:  * -- Initialize (set to initial state) node info sequence
1.32      daniel   8587:  */
1.55      daniel   8588: void
                   8589: xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
1.32      daniel   8590: {
                   8591:   seq->length = 0;
                   8592:   seq->maximum = 0;
                   8593:   seq->buffer = NULL;
                   8594: }
                   8595: 
1.50      daniel   8596: /**
                   8597:  * xmlClearNodeInfoSeq :
                   8598:  * @seq:  a node info sequence pointer
                   8599:  *
                   8600:  * -- Clear (release memory and reinitialize) node
1.32      daniel   8601:  *   info sequence
                   8602:  */
1.55      daniel   8603: void
                   8604: xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
1.32      daniel   8605: {
                   8606:   if ( seq->buffer != NULL )
1.119     daniel   8607:     xmlFree(seq->buffer);
1.32      daniel   8608:   xmlInitNodeInfoSeq(seq);
                   8609: }
                   8610: 
                   8611: 
1.50      daniel   8612: /**
                   8613:  * xmlParserFindNodeInfoIndex:
                   8614:  * @seq:  a node info sequence pointer
                   8615:  * @node:  an XML node pointer
                   8616:  *
                   8617:  * 
1.32      daniel   8618:  * xmlParserFindNodeInfoIndex : Find the index that the info record for
                   8619:  *   the given node is or should be at in a sorted sequence
1.68      daniel   8620:  *
                   8621:  * Returns a long indicating the position of the record
1.32      daniel   8622:  */
                   8623: unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
                   8624:                                          const xmlNode* node)
                   8625: {
                   8626:   unsigned long upper, lower, middle;
                   8627:   int found = 0;
                   8628: 
                   8629:   /* Do a binary search for the key */
                   8630:   lower = 1;
                   8631:   upper = seq->length;
                   8632:   middle = 0;
                   8633:   while ( lower <= upper && !found) {
                   8634:     middle = lower + (upper - lower) / 2;
                   8635:     if ( node == seq->buffer[middle - 1].node )
                   8636:       found = 1;
                   8637:     else if ( node < seq->buffer[middle - 1].node )
                   8638:       upper = middle - 1;
                   8639:     else
                   8640:       lower = middle + 1;
                   8641:   }
                   8642: 
                   8643:   /* Return position */
                   8644:   if ( middle == 0 || seq->buffer[middle - 1].node < node )
                   8645:     return middle;
                   8646:   else 
                   8647:     return middle - 1;
                   8648: }
                   8649: 
                   8650: 
1.50      daniel   8651: /**
                   8652:  * xmlParserAddNodeInfo:
                   8653:  * @ctxt:  an XML parser context
1.68      daniel   8654:  * @info:  a node info sequence pointer
1.50      daniel   8655:  *
                   8656:  * Insert node info record into the sorted sequence
1.32      daniel   8657:  */
1.55      daniel   8658: void
                   8659: xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt, 
1.68      daniel   8660:                      const xmlParserNodeInfo* info)
1.32      daniel   8661: {
                   8662:   unsigned long pos;
                   8663:   static unsigned int block_size = 5;
                   8664: 
                   8665:   /* Find pos and check to see if node is already in the sequence */
1.55      daniel   8666:   pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, info->node);
                   8667:   if ( pos < ctxt->node_seq.length
                   8668:        && ctxt->node_seq.buffer[pos].node == info->node ) {
                   8669:     ctxt->node_seq.buffer[pos] = *info;
1.32      daniel   8670:   }
                   8671: 
                   8672:   /* Otherwise, we need to add new node to buffer */
                   8673:   else {
                   8674:     /* Expand buffer by 5 if needed */
1.55      daniel   8675:     if ( ctxt->node_seq.length + 1 > ctxt->node_seq.maximum ) {
1.32      daniel   8676:       xmlParserNodeInfo* tmp_buffer;
1.55      daniel   8677:       unsigned int byte_size = (sizeof(*ctxt->node_seq.buffer)
                   8678:                                 *(ctxt->node_seq.maximum + block_size));
1.32      daniel   8679: 
1.55      daniel   8680:       if ( ctxt->node_seq.buffer == NULL )
1.119     daniel   8681:         tmp_buffer = (xmlParserNodeInfo*) xmlMalloc(byte_size);
1.32      daniel   8682:       else 
1.119     daniel   8683:         tmp_buffer = (xmlParserNodeInfo*) xmlRealloc(ctxt->node_seq.buffer, byte_size);
1.32      daniel   8684: 
                   8685:       if ( tmp_buffer == NULL ) {
1.55      daniel   8686:         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1.74      daniel   8687:            ctxt->sax->error(ctxt->userData, "Out of memory\n");
1.123     daniel   8688:        ctxt->errNo = XML_ERR_NO_MEMORY;
1.32      daniel   8689:         return;
                   8690:       }
1.55      daniel   8691:       ctxt->node_seq.buffer = tmp_buffer;
                   8692:       ctxt->node_seq.maximum += block_size;
1.32      daniel   8693:     }
                   8694: 
                   8695:     /* If position is not at end, move elements out of the way */
1.55      daniel   8696:     if ( pos != ctxt->node_seq.length ) {
1.32      daniel   8697:       unsigned long i;
                   8698: 
1.55      daniel   8699:       for ( i = ctxt->node_seq.length; i > pos; i-- )
                   8700:         ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
1.32      daniel   8701:     }
                   8702:   
                   8703:     /* Copy element and increase length */
1.55      daniel   8704:     ctxt->node_seq.buffer[pos] = *info;
                   8705:     ctxt->node_seq.length++;
1.32      daniel   8706:   }   
                   8707: }
1.77      daniel   8708: 
1.98      daniel   8709: 
                   8710: /**
                   8711:  * xmlSubstituteEntitiesDefault :
                   8712:  * @val:  int 0 or 1 
                   8713:  *
                   8714:  * Set and return the previous value for default entity support.
                   8715:  * Initially the parser always keep entity references instead of substituting
                   8716:  * entity values in the output. This function has to be used to change the
                   8717:  * default parser behaviour
                   8718:  * SAX::subtituteEntities() has to be used for changing that on a file by
                   8719:  * file basis.
                   8720:  *
                   8721:  * Returns the last value for 0 for no substitution, 1 for substitution.
                   8722:  */
                   8723: 
                   8724: int
                   8725: xmlSubstituteEntitiesDefault(int val) {
                   8726:     int old = xmlSubstituteEntitiesDefaultValue;
                   8727: 
                   8728:     xmlSubstituteEntitiesDefaultValue = val;
                   8729:     return(old);
                   8730: }
1.77      daniel   8731: 

Webmaster