| 8138 | */ |
| 8139 | |
| 8140 | void |
| 8141 | xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) { |
| 8142 | const xmlChar *name = NULL; |
| 8143 | xmlChar *ExternalID = NULL; |
| 8144 | xmlChar *URI = NULL; |
| 8145 | |
| 8146 | /* |
| 8147 | * We know that '<!DOCTYPE' has been detected. |
| 8148 | */ |
| 8149 | SKIP(9); |
| 8150 | |
| 8151 | SKIP_BLANKS; |
| 8152 | |
| 8153 | /* |
| 8154 | * Parse the DOCTYPE name. |
| 8155 | */ |
| 8156 | name = xmlParseName(ctxt); |
| 8157 | if (name == NULL) { |
| 8158 | xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, |
| 8159 | "xmlParseDocTypeDecl : no DOCTYPE name !\n"); |
| 8160 | } |
| 8161 | ctxt->intSubName = name; |
| 8162 | |
| 8163 | SKIP_BLANKS; |
| 8164 | |
| 8165 | /* |
| 8166 | * Check for SystemID and ExternalID |
| 8167 | */ |
| 8168 | URI = xmlParseExternalID(ctxt, &ExternalID, 1); |
| 8169 | |
| 8170 | if ((URI != NULL) || (ExternalID != NULL)) { |
| 8171 | ctxt->hasExternalSubset = 1; |
| 8172 | } |
| 8173 | ctxt->extSubURI = URI; |
| 8174 | ctxt->extSubSystem = ExternalID; |
| 8175 | |
| 8176 | SKIP_BLANKS; |
| 8177 | |
| 8178 | /* |
| 8179 | * Create and update the internal subset. |
| 8180 | */ |
| 8181 | if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) && |
| 8182 | (!ctxt->disableSAX)) |
| 8183 | ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI); |
| 8184 | |
| 8185 | /* |
| 8186 | * Is there any internal subset declarations ? |
| 8187 | * they are handled separately in xmlParseInternalSubset() |
| 8188 | */ |
| 8189 | if (RAW == '[') |
| 8190 | return; |
| 8191 | |
| 8192 | /* |
| 8193 | * We should be at the end of the DOCTYPE declaration. |
| 8194 | */ |
| 8195 | if (RAW != '>') { |
| 8196 | xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL); |
| 8197 | } |
no test coverage detected