Annotation of XML/parser.c, revision 1.147

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

Webmaster