| 3553 | */ |
| 3554 | |
| 3555 | static void |
| 3556 | htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) { |
| 3557 | const xmlChar *name; |
| 3558 | xmlChar *ExternalID = NULL; |
| 3559 | xmlChar *URI = NULL; |
| 3560 | |
| 3561 | /* |
| 3562 | * We know that '<!DOCTYPE' has been detected. |
| 3563 | */ |
| 3564 | SKIP(9); |
| 3565 | |
| 3566 | SKIP_BLANKS; |
| 3567 | |
| 3568 | /* |
| 3569 | * Parse the DOCTYPE name. |
| 3570 | */ |
| 3571 | name = htmlParseName(ctxt); |
| 3572 | if (name == NULL) { |
| 3573 | htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED, |
| 3574 | "htmlParseDocTypeDecl : no DOCTYPE name !\n", |
| 3575 | NULL, NULL); |
| 3576 | } |
| 3577 | /* |
| 3578 | * Check that upper(name) == "HTML" !!!!!!!!!!!!! |
| 3579 | */ |
| 3580 | |
| 3581 | SKIP_BLANKS; |
| 3582 | |
| 3583 | /* |
| 3584 | * Check for SystemID and ExternalID |
| 3585 | */ |
| 3586 | URI = htmlParseExternalID(ctxt, &ExternalID); |
| 3587 | SKIP_BLANKS; |
| 3588 | |
| 3589 | /* |
| 3590 | * We should be at the end of the DOCTYPE declaration. |
| 3591 | */ |
| 3592 | if (CUR != '>') { |
| 3593 | htmlParseErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, |
| 3594 | "DOCTYPE improperly terminated\n", NULL, NULL); |
| 3595 | /* Ignore bogus content */ |
| 3596 | while ((CUR != 0) && (CUR != '>') && |
| 3597 | (PARSER_STOPPED(ctxt) == 0)) |
| 3598 | NEXT; |
| 3599 | } |
| 3600 | if (CUR == '>') |
| 3601 | NEXT; |
| 3602 | |
| 3603 | /* |
| 3604 | * Create or update the document accordingly to the DOCTYPE |
| 3605 | */ |
| 3606 | if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) && |
| 3607 | (!ctxt->disableSAX)) |
| 3608 | ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI); |
| 3609 | |
| 3610 | /* |
| 3611 | * Cleanup, since we don't use all those identifiers |
| 3612 | */ |
no test coverage detected