%{ /* ***************************************************************************** * * $RCSfile: parsutil.y,v $ * $Date: 1999/09/27 20:36:10 $ * $Source: /home/richard/Xml/RCS/parsutil.y,v $ * $Revision: 1.217 $ * $Author: richard $ * ***************************************************************************** * * Copyright 1998, 1999 Brown University and Richard Goerwitz * ***************************************************************************** * * Parsing, validating routines for xml_file structs (initializers and * destructors for these are in fileutil.c). * * NOTE WELL: For proper viewing, set your editor so that it shows * you at least 120 columns of fixed-width text. Otherwise the YACC * action code will wrap, and become very hard to read. * ***************************************************************************** * * I. Overview * * This file contains specifications for a parser that processes and * validates XML text. Its sole entry point is parse_xml_file(), * which takes an xml_file structure as its argument. xml_file * structures may have child xml_file structures, which are used * for external entities and are pushed on and off the flex input * stream stack as needed (see below). * * In brief, the steps the processor goes through are as follows: * * 1) finds and checks the XML declaration (if one is present) * * 2) find the doctype declaration, and then process * a) the internal DTD subset * b) the external DTD subset * * 3) while doing 2a and 2b, the processor also resolves external * entity decls and parses the files they point to; it also * parses entity replacement text for syntax errors * * 4) finally, the parser processes the actual XML file content, * making sure that elements and attributes encountered are * declared, and that they have values and orderings allowed by * the DTD (if required attributes are missing, these are also * flagged) * * 5) idref attributes are checked for corresponding ids * * Note that the parser does not need to worry about character * encoding variations. All I/O is done via the lexer, which uses * get_xml_char() (in fileutil.c; it can autodetect UTF-8, 16 and * UCS-4, both big and little endian). Everything is converted to * my_wchar_t internally, and output (e.g., in the case of error * messages) as UTF-8. * * All information about the file being scanned is contained in the * currently active xml_file structure (pointed to by the global var, * this_file). * * Note that all xml_file structures (which are created every time a * PUBLIC/SYSTEM identifier gets resolved) are registered for garbage * collection by hanging them off the parent xml_file structure. In * the case of the external DTD, this "hanging" is done by a call to * add_xml_file(). This particular routine actually merges the data * structures for the two xml_file structs, and marks the one for the * external DTD as xf->child == yes. Other subordinate xml_file * structs are marked for garbage collection without being so merged * via add_xml_file_nomerge(). This latter routine sets their child * field to "maybe" (i.e., xf->child == maybe). It is used, e.g., on * external entities. * * I mention all of this because whether an xml_file's status as a * child is yes, no, or maybe tells us whether we should be doing * full validation or not. In both the parent xml_file struct and * the external DTD, full validation is on, except when we are * scanning entity replacement text. For other subordinate xml_file * structs it is off (i.e., if we are just doing a quick syntax check * on an external entity). * * On the question of how the parser tells the lexer to switch from * the main document, to the external DTD an/or to whatever external * entity files are defined, see the section on "Use of Stacks", * below. * ***************************************************************************** * * II. Use of Stacks * * The parser defined here makes considerable use of stacks that are, * under error conditions, likely to wander out of sync with the main * parser stack. For example, to facilitate one-pass checking of * content models (i.e., checking of content models while the parse * tree is being built), check_node_against_dfa(), which lives in * nfadfa.c, keeps its own internal stack of DFAs, which are * synchronized with the main parser by calling it with one of two * final arguments, INITIALIZE_DFA_WALK (which pushes a new DFA for * the current STag) or FINISH_DFA_WALK (which pops the DFA off the * DFA stack. Note that check_node_against_dfa() is only called for * elements with "children" content models. * * Another area in which stacks are used is when stream-switching * occurs. This happens a) when the parser sees an external DTD * subset, b) when it sees an entity definition, or c) when the lexer * is replacing an entity reference with its replacement text. The * stream-switch is achieved by calls to stream-pushing routines, * which in cases (a) and (b) happen within the parser, but in case * (c) happens in the lexer. These stream-pushing routines are: * * push_xml_file() # called from parser * push_entity_text() # called from parser * push_xml_string() # called from lexer * * The first routine above is called whenever the parser wants to * check an external entity for well-formedness, e.g., in the case * of DTD directives like and in * the case of the external DTD subset. The same rule that calls * push_xml_file() must then also call pop_xml_file(). See below. * * The second routine above, push_entity_text() is called whenever * the parser wants to check the literal text of an internal entity * for well-formedness. It simply maps whatever entities need to be * mapped (e.g., char entitites), pushes the mapped text onto the * lexer stack, then runs the mapped text through a non-validating * check. The same rule that pushed the entity text then pops it off * the scan stack by calling pop_xml_file(), as with push_xml_file() * above. * * In cases where the lexer is manipulating its own stack, via * push_xml_string(), the <> pattern is where the call to * pop_xml_file() gets executed. Note that, once entity replacement * text has been pushed, error messages that come up are still * attached to the parent xml_file structure, so that line numbers in * any emitted warnings or errors refer to the parent file, and not * to the source (internal or external) of the entity in question's * replacement text. * ***************************************************************************** * * III. Processing This File * * Note that this file should be processed with the -p xml_yy option, * so that global variables take on names unlikely to bother people * who link xmlparse routines to programs that already use GNU Bison * for other purposes. * ***************************************************************************** */ #include "parsutil.h" #include "dtdutil.h" #include "errabort.h" #include "grammutil.h" #include "hashutil.h" #include "namespace.h" #include "parstree.h" #include "xtrautil.h" #define YYERROR_VERBOSE #ifndef XML_NODEBUG # define YYDEBUG 1 #endif #ifdef YYDEBUG extern int xml_yydebug; #else int xml_yydebug = 0; #endif int xml_yywrap (void); int xml_yylex (void); int xml_yyerror (char *); int seen_doctype_decl = 0; int expecting_cpseq_or_choice = 0; int in_document_content = 0; static struct xml_file *this_file; struct default_decl { enum default_types type; my_wchar_t *string; }; struct xml_element_list { size_t len; xml_element **elements; }; static struct malloc_block_list *add_default_attvals (struct xml_file *, my_wchar_t *, struct malloc_block_list *); static void check_for_duplicate_atts (struct xml_file *, struct xml_node *); static int check_for_requireds (struct xml_file *, my_wchar_t *, struct malloc_block_list *); static int check_builtin (struct xml_file *, my_wchar_t *, my_wchar_t *); static int check_gt_and_lt (my_wchar_t *); static int check_notations (struct xml_file *); static int clobber_dummy_elements (struct xml_file *); static int check_uperefs (struct xml_file *); static int find_dangling_elements (struct xml_file *, my_wchar_t *); static int add_symbols_in_cmnode (xml_file *, struct cmnode *, struct rg_htable *, struct rg_htable *); static void add_ancestor_links_to_elements (xml_file *); static size_t add_ancestor_links_to_element (xml_file *xf, xml_element *, struct rg_htable *); static xml_element *add_ancestor_link_to_element (xml_file *, xml_element *, xml_element *); static size_t add_parent_links_to_elements (xml_file *); static int add_symbols_in_cmnode_to_parents_table (xml_file *, cmnode *, xml_element *, struct rg_htable *); static xml_element *add_parent_to_parents_table (xml_file *, my_wchar_t *, xml_element *, struct rg_htable *); static int check_case (struct xml_file *, my_wchar_t *, enum yesno); #define YY_INPUT(buf, result, max_size) \ { \ int c = '*', n; \ if (! this_file->file || feof (this_file->file)) \ result = 0; \ else { \ for (n = 0; n < max_size && (c = this_file->get_xml_char (this_file)) != EOF && c != '\n'; ++n) \ buf[n] = c; \ if (c == '\n') \ buf[n++] = c; \ if (c == EOF && ferror (this_file->file)) \ YY_FATAL_ERROR ("input in flex scanner failed"); \ result = n; \ } \ } %} %union { my_wchar_t *wstr; struct xml_file *xf; struct rg_htable *ht; struct malloc_block_list *mbl; struct default_decl *dd; struct xml_attribute *xa; struct xml_node *xn; struct cmnode *cmn; struct name_val *nv; int i; } %token ELEMENT ETAG EMPTY_ELEMENT_END_DELIM CURRENT CONREF %token ELEMENT_OR_ETAG_END_DELIM BAD_ENTITY_REF XMLSTART_DELIM %token VERSION ENCODING STANDALONE EQUALS XML_DECL_END_DELIM %token PI_TARGET PIDATA COMMENT_DELIM COMMDATA CDATA DOCTYPEDECL %token DIGIT_INITIAL_NAME BEGIN_DTD_DELIM ELEMENTDECL_DELIM %token ATTLISTDECL_DELIM PARAMETER_ENTITY_DECL_DELIM %token ENTITYDECL_DELIM NOTATIONDECL_DELIM BAD_DECL %token END_DTD_DELIM LEFTPAREND RIGHTPAREND VSLASH QUESTIONMARK %token STAR PLUS MINUS COMMA AMPERSAND FIXED PCDATA REQUIRED %token IMPLIED PUBLIC SYSTEM EMPTY ANY RCDATA CDATA_ ID IDREF ENTITY %token DEFAULT NMTOKEN_ IDREFS NAMES NUMBERS NUTOKENS ENTITIES %token NMTOKENS NOTATION SDATA NDATA QUOTEDSTRING NAME NMTOKEN %token ELEMENT_OR_ETAG_END_DELIM CHAR_DATA BAD_CHAR WHITESPACE %token DECL_END END_FILE %type DoctypeDecl Prolog EncodingDecl PubID SysID Name ETag NDataDecl %type NameOrNmtoken CharData %type ExternalID %type NotationType Enumeration NoteNameAlternatives NmtokenAlternatives %type AttDefs NameAlternatives Mixed Attributes Content NameGroup %type
DefaultDecl %type AttDef %type Document NullElement Element EmptyElemTag STag Pi Comment %type Children ChoiceOrSeq CpChoice CpSequence Cp ChoiceOrNameOrSeq %type QName AQName EQName %type TextDecl MarkupOrPERefs ExternalSubset ExternalContent %start Document %{ YYSTYPE yylval; #include "lexutil.c" %} %% Document : Prolog error { my_wchar_t *wp; wp = utf_8_to_utf_16 ("(EOF)"); if (validating (this_file) && $1 == NULL) /* oops; missing DOCTYPE decl */ add_xml_error (this_file, 402, wp); /* general parsing failure */ add_xml_error (this_file, 300, wp); } | Prolog error CharData { add_xml_error (this_file, 1104, $3); free ($3); } | Prolog NullElement NullElement Element NotInContent Misc { my_wchar_t *wp; /* * NullElement is just there to make sure * a NULL pointer is on the stack before * Element. NotInContent is there only to * set in_document_content to zero */ if (validating (this_file)) { wp = $4 ? $4->name : NULL; if ($1 == NULL) { /* oops; missing DOCTYPE decl */ add_xml_error (this_file, 402, wp); } else { if ($4 != NULL) { /* DTD name must match top element */ if ($4->name == NULL || uni_strcmp ($1, $4->name)) { add_xml_error (this_file, 401, wp); free_xml_node ($4); } else { /* clear DFA stack */ check_node_against_dfa (this_file, NULL, NULL, CLOBBER_STACK); /* install finished parse tree */ this_file->parstree = $4; } } } } } | Prolog NullElement NullElement Element NotInContent Misc error { /* shouldn't have anything after Misc */ my_wchar_t *wp; if (validating (this_file)) { wp = $4 ? $4->name : NULL; if ($1 == NULL) { /* oops; missing DOCTYPE decl */ add_xml_error (this_file, 402, wp); } else { if ($4 != NULL) { /* DTD name must match top element */ if (($4->name == NULL) || (uni_strcmp ($1, $4->name))) { add_xml_error (this_file, 401, wp); free_xml_node ($4); } else { /* clear DFA stack */ check_node_against_dfa (this_file, NULL, NULL, CLOBBER_STACK); /* install finished parse tree */ this_file->parstree = $4; } } } } /* shouldn't have anything after Misc */ wp = utf_8_to_utf_16 ("(EOF)"); add_xml_error (this_file, 302, wp); } ; NullElement : { /* my only use is to push a NULL pointer */ $$ = NULL; } NotInContent : { /* finished with document content */ in_document_content = 0; } Prolog : XMLDecl Misc DoctypeDecl Misc { $$ = $3; } | XMLDecl Misc { $$ = NULL; } ; XMLDecl : XMLSTART_DELIM error { /* line numbers may now be off */ add_xml_error (this_file, 321, NULL); add_xml_error (this_file, 351, $1); yy_pop_state (); } | XMLSTART_DELIM error XML_DECL_END_DELIM { /* bogus PI (XML decl is a kind of PI) */ add_xml_error (this_file, 351, $1); } | XMLSTART_DELIM XMLDeclInfo XML_DECL_END_DELIM {} | /* epsilon */ ; XMLDeclInfo : VersionInfo EncodingDecl SDDecl {} | VersionInfo EncodingDecl {} | VersionInfo SDDecl {} | VersionInfo {} | EncodingDecl { add_xml_error (this_file, 359, $1); } | EncodingDecl VersionInfo { add_xml_error (this_file, 358, $1); } | EncodingDecl VersionInfo SDDecl { add_xml_error (this_file, 358, $1); } ; TextDecl : XMLSTART_DELIM error { /* line numbers may now be off */ add_xml_error (this_file, 321, NULL); /* bogus PI (XML decl is a kind of PI) */ add_xml_error (this_file, 351, $1); yy_pop_state (); $$ = 0; } | XMLSTART_DELIM error XML_DECL_END_DELIM { /* bogus PI (XML decl is a kind of PI) */ add_xml_error (this_file, 351, $1); $$ = 0; } | XMLSTART_DELIM TextDeclInfo error { /* line numbers may now be off */ add_xml_error (this_file, 321, NULL); /* probably an unterminated TextDecl */ add_xml_error (this_file, 364, $1); yy_pop_state (); $$ = 0; } | XMLSTART_DELIM TextDeclInfo XML_DECL_END_DELIM { $$ = 1; } | /* epsilon */ { $$ = 2; } ; TextDeclInfo : VersionInfo EncodingDecl SDDecl { /* standalone not allowed in text decl */ add_unique_error (this_file, 353, NULL); } | VersionInfo SDDecl { /* standalone not allowed in text decl */ add_xml_error (this_file, 352, NULL); } | VersionInfo EncodingDecl {} | VersionInfo error { add_xml_error (this_file, 370, NULL); } | VersionInfo { add_xml_error (this_file, 352, NULL); } | EncodingDecl error { add_xml_error (this_file, 370, NULL); } | EncodingDecl SDDecl { /* standalone not allowed in text decl */ add_unique_error (this_file, 353, NULL); } | EncodingDecl {} ; VersionInfo : error Name EQUALS QUOTEDSTRING { add_xml_error (this_file, 366, $2); } | VERSION EQUALS error { my_wchar_t *wp; wp = utf_8_to_utf_16 ("= ..."); add_xml_error (this_file, 360, wp); } | VERSION EQUALS QUOTEDSTRING { char *cp; float f; my_wchar_t *p; for (p = $3; *p != 0; p++) if (! isalnum (*p) && ! uni_utf_any (p, "_.:-")) /* invalid XML version name/num */ add_xml_error (this_file, 360, $3); cp = strdup (utf_16_to_utf_8 ($3)); if ((sscanf (cp, "%f", &f) <= 0) || (f > 1)) /* can't handle XML versions > 1 */ add_xml_error (this_file, 360, $3); free (cp); } ; EncodingDecl : ENCODING EQUALS error { my_wchar_t *wp; wp = utf_8_to_utf_16 ("="); add_xml_error (this_file, 350, wp); $$ = $1; } | ENCODING EQUALS QUOTEDSTRING { if ($3) set_encoding (this_file, $3); $$ = $1; } ; SDDecl : STANDALONE EQUALS error { my_wchar_t *wp; wp = utf_8_to_utf_16 ("="); add_xml_error (this_file, 362, wp); } | STANDALONE EQUALS QUOTEDSTRING { /* if we're in a child xml_file struct */ if (this_file->child != no) { /* can't have standalone in TextDecl */ add_xml_error (this_file, 353, NULL); } else { if (uni_utf_strcmp ($3, "yes") == 0) this_file->standalone = yes; else if (uni_utf_strcmp ($3, "no") == 0) this_file->standalone = no; else /* must be "yes" or "no" */ add_xml_error (this_file, 362, $3); } } ; DoctypeDecl : DOCTYPEDECL error DECL_END { add_xml_error (this_file, 400, NULL); seen_doctype_decl = 1; $$ = NULL; } | DOCTYPEDECL Name error DECL_END { add_xml_error (this_file, 400, $2); seen_doctype_decl = 1; $$ = NULL; } | DOCTYPEDECL Name ExternalID InternalSubset DECL_END { struct xml_file *xf; seen_doctype_decl = 1; if (this_file->standalone == yes) add_xml_warning (this_file, 406, NULL); if ((xf = $3)) { /* merge ext tables with internal */ if (! add_xml_file (this_file, xf)) { /* ext entity refers to a parent */ free_xml_file (xf); xf = NULL; } } if (! xf || ! validating (this_file)) if ((xf = create_xml_file ("/dev/null"))) add_xml_file (this_file, xf); if (xf) /* push_xml_file (in lexutil.l) pushes * a new object onto the lexer's scan * stack; this lets us switch to a new * input stream */ push_xml_file (xf, DTD); } ExternalSubset END_FILE { /* pop_xml_file switches to old stream */ pop_xml_file (); if (! $7) /* $7 returns false if parse failed */ add_xml_error (this_file, 774, $2); else if (validating (this_file)) { /* Undeclared NOTATIONs in attlists? */ check_notations (this_file); /* Get rid of undeclared dummy elems */ clobber_dummy_elements (this_file); /* Undeclared NOTATIONs in uperefs? */ check_uperefs (this_file); /* elements in cont models declared? */ check_content_models (this_file); /* check for unused elements */ find_dangling_elements (this_file, $2); /* add links back to ancestor elements; not used */ /* add_ancestor_links_to_elements (this_file); */ } /* sic; $2 refers to Name above */ $$ = $2; } | DOCTYPEDECL Name PubID InternalSubset DECL_END { seen_doctype_decl = 1; /* Unlike SGML, XML needs a SysID here */ add_xml_error (this_file, 420, NULL); if (validating (this_file)) { /* Undeclared NOTATIONs in attlists? */ check_notations (this_file); /* Get rid of undeclared dummy elems */ clobber_dummy_elements (this_file); /* Undeclared NOTATIONs in uperefs? */ check_uperefs (this_file); /* elements in cont models declared? */ check_content_models (this_file); /* check for unused elements */ find_dangling_elements (this_file, $2); /* add links back to ancestor elements; not used */ /* add_ancestor_links_to_elements (this_file); */ $$ = $2; } } | DOCTYPEDECL Name InternalSubset DECL_END { seen_doctype_decl = 1; /* this must match top xml_node name */ if (validating (this_file)) { /* Undeclared NOTATIONs in attlists? */ check_notations (this_file); /* Get rid of undeclared dummy elems */ clobber_dummy_elements (this_file); /* Undeclared NOTATIONs in uperefs? */ check_uperefs (this_file); /* elements in cont models declared? */ check_content_models (this_file); /* check for unused elements */ find_dangling_elements (this_file, $2); /* add links back to ancestor elements; not used */ /* add_ancestor_links_to_elements (this_file); */ $$ = $2; } } ; ExternalID : PubID SysID { my_wchar_t *wp; struct xml_file *xf; wp = utf_8_to_utf_16 ("SYSTEM"); add_xml_warning (this_file, 304, wp); if (! validating (this_file)) $$ = NULL; else { if ($1 == NULL) /* error msg already generated */ $$ = NULL; else { xf = resolve_pub_or_sysid (this_file, $1, NULL); if (xf == NULL) { uni_map_whitespace_to_space ($1); uni_map_spaces_to_space ($1); add_xml_warning (this_file, 562, $1); xf = resolve_pub_or_sysid (this_file, NULL, $2); if (xf == NULL) add_xml_error (this_file, 563, $2); } $$ = xf; } } } | PubID QUOTEDSTRING { struct xml_file *xf; if (! validating (this_file)) $$ = NULL; else { if ($1 == NULL) /* error msg already generated */ $$ = NULL; else { xf = resolve_pub_or_sysid (this_file, $1, NULL); if (xf == NULL) { uni_map_whitespace_to_space ($1); uni_map_spaces_to_space ($1); add_xml_warning (this_file, 562, $1); xf = resolve_pub_or_sysid (this_file, NULL, $2); if (xf == NULL) add_xml_error (this_file, 563, $2); } $$ = xf; } } } | PubID NameOrNmtoken error { struct xml_file *xf; if (! validating (this_file)) $$ = NULL; else { if ($1 == NULL) /* error msg already generated */ $$ = NULL; else { if ($2) add_xml_error (this_file, 551, $2); xf = resolve_pub_or_sysid (this_file, $1, NULL); if (xf == NULL) { uni_map_whitespace_to_space ($1); uni_map_spaces_to_space ($1); add_xml_warning (this_file, 562, $1); xf = resolve_pub_or_sysid (this_file, NULL, $2); if (xf == NULL) add_xml_error (this_file, 563, $2); } $$ = xf; } } } | SysID { if (! validating (this_file)) $$ = NULL; else { if ($1 == NULL) $$ = NULL; else { $$ = resolve_pub_or_sysid (this_file, NULL, $1); if ($$ == NULL) add_xml_error (this_file, 563, $1); } } } ; PubID : PUBLIC error { my_wchar_t *wp; wp = utf_8_to_utf_16 ("PUBLIC"); add_xml_error (this_file, 567, wp); $$ = NULL; } | PUBLIC QUOTEDSTRING { $$ = NULL; check_case (this_file, $1, no); if ($2 && validating (this_file)) $$ = $2; } | PUBLIC NameOrNmtoken error { $$ = NULL; check_case (this_file, $1, no); if ($2 && validating (this_file)) { add_xml_error (this_file, 551, $2); $$ = $2; } } ; SysID : SYSTEM error { my_wchar_t *msg; msg = utf_8_to_utf_16 ("(unspecified)"); add_xml_error (this_file, 568, msg); $$ = NULL; } | SYSTEM QUOTEDSTRING { $$ = NULL; check_case (this_file, $1, no); if ($2 && validating (this_file)) $$ = $2; } | SYSTEM NameOrNmtoken error { $$ = NULL; check_case (this_file, $1, no); if ($2 && validating (this_file)) { add_xml_error (this_file, 550, $2); $$ = $2; } } ; ExternalSubset : TextDecl MarkupOrPERefs { $$ = ($1 && $2) ? 1 : 0; } | MarkupOrPERefs { $$ = $1 ? 1 : 0; } ; ExternalContent : ExternalContent error { /* 0 means failure */ $$ = 0; } | TextDecl Content { $$ = $1 ? 1 : 0; } | Content { $$ = 1; } ; InternalSubset : BEGIN_DTD_DELIM MarkupOrPERefs END_DTD_DELIM {} | /* epsilon */ ; MarkupOrPERefs : MarkupOrPERefs error { /* More trouble than it's worth */ /* my_wchar_t *msg; * msg = utf_8_to_utf_16 ("(unspecified)"); * add_xml_error (this_file, 463, msg); */ $$ = 0; } | MarkupOrPERefs MarkupDecl { $$ = $1 ? 1 : 0; } | { $$ = 1; } ; MarkupDecl : ElementDecl {} | AttlistDecl {} | PEntityDecl {} | EntityDecl {} | NotationDecl {} | BadDecl {} | Comment { if (validating (this_file) && $1) /* not needed in markup section */ free_xml_node ($1); } | Pi { if (validating (this_file) && $1) /* not needed in markup section */ free_xml_node ($1); } ; ElementDecl : ELEMENTDECL_DELIM error DECL_END { my_wchar_t *wp; /* turn off check on balanced PE parends */ expecting_cpseq_or_choice = 0; wp = utf_8_to_utf_16 ("(Name token)"); add_xml_error (this_file, 651, wp); } | ELEMENTDECL_DELIM NameGroup error DECL_END { my_wchar_t *wp; if (validating (this_file)) { if (! $2) { wp = utf_8_to_utf_16 ("blocks[i],$3)) /* oops; list already has name */ break; if (i < get_block_len ($1)) { /* oops; list already has this name */ add_xml_error (this_file, 670, $3); $$ = $1; } else { /* accumulate list of alternatives */ len = uni_strlen ($3) + 1; len *= sizeof (my_wchar_t); $$ = push_block ($1, $3, len); } } } | Name { if (validating (this_file)) { /* add Name to block array */ size_t len; len = uni_strlen ($1) + 1; len *= sizeof (my_wchar_t); $$ = push_block (NULL, $1, len); } } ; Children : ChoiceOrSeq QUESTIONMARK { if ($1 == NULL) $$ = NULL; else if (validating (this_file)) $$ = create_cmnode ($1, NULL, qmark); } | ChoiceOrSeq STAR { if ($1 == NULL) $$ = NULL; else if (validating (this_file)) $$ = create_cmnode ($1, NULL, star); } | ChoiceOrSeq PLUS { if ($1 == NULL) $$ = NULL; else if (validating (this_file)) $$ = create_cmnode ($1, NULL, plus); } | ChoiceOrSeq { if (validating (this_file)) $$ = $1; } ; ChoiceOrSeq : LeftParend error RIGHTPAREND { $$ = NULL; } | LeftParend CpChoice RIGHTPAREND { if (validating (this_file)) $$ = $2; } | LeftParend CpSequence RIGHTPAREND { if (validating (this_file)) $$ = $2; } ; CpChoice : CpChoice VSLASH Cp { if (($1 == NULL) || ($3 == NULL)) { if ($3) free_cmnode ($3); if ($1) free_cmnode ($1); $$ = NULL; } else { if (validating (this_file)) $$ = create_cmnode ($1, $3, slash); } } | Cp VSLASH Cp { if (($1 == NULL) || ($3 == NULL)) { if ($3) free_cmnode ($3); if ($1) free_cmnode ($1); $$ = NULL; } else { if (validating (this_file)) $$ = create_cmnode ($1, $3, slash); } } | Cp AMPERSAND Cp { my_wchar_t *tmp; if (($1 == NULL) || ($3 == NULL)) { if ($3) free_cmnode ($3); if ($1) free_cmnode ($1); $$ = NULL; } else { /* unlike SGML, & is illegal in XML */ tmp = utf_8_to_utf_16 ("&"); add_xml_error (this_file, 669, tmp); if (validating (this_file)) /* treat the '&' like a slash */ $$ = create_cmnode ($1, $3, slash); } } ; CpSequence : CpSequence COMMA Cp { if (($1 == NULL) || ($3 == NULL)) { if ($3) free_cmnode ($3); if ($1) free_cmnode ($1); $$ = NULL; } else { if (validating (this_file)) $$ = create_cmnode ($1, $3, comma); } } | Cp { if (validating (this_file)) $$ = $1; } ; Cp : ChoiceOrNameOrSeq QUESTIONMARK { if ($1 == NULL) $$ = NULL; else if (validating (this_file)) $$ = create_cmnode ($1, NULL, qmark); } | ChoiceOrNameOrSeq STAR { if ($1 == NULL) $$ = NULL; else if (validating (this_file)) $$ = create_cmnode ($1, NULL, star); } | ChoiceOrNameOrSeq PLUS { if ($1 == NULL) $$ = NULL; else if (validating (this_file)) $$ = create_cmnode ($1, NULL, plus); } | ChoiceOrNameOrSeq error { /* catch (a, b | c) (best: (a, (b | c)) */ add_xml_error (this_file, 676, NULL); if (validating (this_file)) $$ = $1; } | ChoiceOrNameOrSeq { if (validating (this_file)) $$ = $1; } ; ChoiceOrNameOrSeq : ChoiceOrSeq { if (validating (this_file)) $$ = $1; } | Name { if (validating (this_file)) $$ = create_cmleaf ($1); } | PCDATA { my_wchar_t *wp; wp = utf_8_to_utf_16 ("#PCDATA"); add_xml_error (this_file, 675, wp); wp = uni_add_string (wp); if (validating (this_file)) $$ = create_cmleaf (wp); } ; AttlistDecl : ATTLISTDECL_DELIM NameGroup error DECL_END { my_wchar_t *wp; if (validating (this_file)) { if (! $2) { wp = utf_8_to_utf_16 ("attlistlen > 0) add_xml_warning (this_file, 652, $2); while ((xa = pop_block ($3))) if (! add_attribute (this_file, $2, xa)) free_xml_attribute (xa); /* if xe was NULL, it's not now */ xe = expand_element (this_file, $2); /* see XML 1.0 standard, 3.3.1 */ check_dup_enum_vals (this_file, xe); free ($3); } } } AttDefs : AttDefs AttDef { if (validating (this_file)) { if ($2 == NULL) $$ = $1; else /* save AttDef in AttDefs list */ $$ = push_block ($1, $2, 0); } } | { $$ = NULL; } ; AttDef : AttDef error { my_wchar_t *msg; if (validating (this_file)) { msg = utf_8_to_utf_16 ("(?)"); add_xml_error (this_file, 610, msg); } yyclearin; $$ = $1; } | NMTOKEN error DefaultDecl { /* oops; illegal attribute name */ if (uni_isdigit ($1[0])) { /* digit-initial attribute name */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 1353, $1); if (yychar == NAME) this_file->lineno++; } /* general invalid attribute name */ add_xml_error (this_file, 611, $1); if (validating (this_file)) { if ($3) { if ($3->string) free ($3->string); free ($3); } } $$ = NULL; } | Name error { /* general AttDef failure; this rule * will cause a lot of shift/reduce * conflicts to show up */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 660, $1); if (yychar == NAME) this_file->lineno++; $$ = NULL; } | Name error DefaultDecl { /* oops; no AttType; skip this one */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 660, $1); if (yychar == NAME) this_file->lineno++; if (validating (this_file)) { if ($3) { if ($3->string) free ($3->string); free ($3); } } $$ = NULL; } | Name NAMES DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { /* NAME and NAMES not allowed in XML */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 602, $2); if (yychar == NAME) this_file->lineno++; /* treat as CDATA */ $$ = create_xml_attribute (this_file, $1, cdata, 0, NULL, $3->type, $3->string); free ($3); } } } | Name NUMBERS DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { /* NUMBER/NUMBERS disallowed in XML */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 602, $2); if (yychar == NAME) this_file->lineno++; /* treat as CDATA */ $$ = create_xml_attribute (this_file, $1, cdata, 0, NULL, $3->type, $3->string); free ($3); } } } | Name NUTOKENS DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { /* no NUTOKEN/NUTOKENS in XML */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 602, $2); if (yychar == NAME) this_file->lineno++; /* treat as CDATA */ $$ = create_xml_attribute (this_file, $1, cdata, 0, NULL, $3->type, $3->string); free ($3); } } } | Name CDATA_ DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { $$ = create_xml_attribute (this_file, $1, cdata, 0, NULL, $3->type, $3->string); free ($3); } } } | Name ID DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { /* ID att - required or implied */ if ($3->type == defaulted || $3->type == fixed) add_xml_error (this_file, 586, $1); $$ = create_xml_attribute (this_file, $1, id, 0, NULL, $3->type, $3->string); free ($3); } } } | Name IDREF DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { $$ = create_xml_attribute (this_file, $1, idref, 0, NULL, $3->type, $3->string); free ($3); } } } | Name IDREFS DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { $$ = create_xml_attribute (this_file, $1, idrefs, 0, NULL, $3->type, $3->string); free ($3); } } } | Name ENTITY DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { $$ = create_xml_attribute (this_file, $1, entity, 0, NULL, $3->type, $3->string); free ($3); } } } | Name ENTITIES DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { $$ = create_xml_attribute (this_file, $1, entities, 0, NULL, $3->type, $3->string); free ($3); } } } | Name NMTOKEN_ DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { $$ = create_xml_attribute (this_file, $1, nmtoken, 0, NULL, $3->type, $3->string); free ($3); } } } | Name NMTOKENS DefaultDecl { check_case (this_file, $2, yes); if (validating (this_file)) { if (! $3) $$ = NULL; else { $$ = create_xml_attribute (this_file, $1, nmtokens, 0, NULL, $3->type, $3->string); free ($3); } } } | Name NOTATION NotationType DefaultDecl { my_wchar_t *wp, **strings; check_case (this_file, $2, yes); if (validating (this_file)) { if (! $4) $$ = NULL; else { if ($3 == NULL) { if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 702, $1); if (yychar == NAME) this_file->lineno++; } strings = (my_wchar_t **)get_blocks ($3); $$ = create_xml_attribute (this_file, $1, notation, get_block_len ($3), strings, $4->type, $4->string); } if ($3) { if ($$ == NULL) { /* if problems, free notnames */ while ((wp = pop_block ($3))) if (wp) free (wp); if ($4 && $4->string) free ($4->string); } free ($3); } if ($4) free ($4); } } | Name Enumeration DefaultDecl { my_wchar_t *wp, **strings; if (validating (this_file)) { if (! $3) $$ = NULL; else { if ($2 == NULL) { /* empty enumeration */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 585, $1); if (yychar == NAME) this_file->lineno++; } strings = (my_wchar_t **)get_blocks ($2); $$ = create_xml_attribute (this_file, $1, enumeration, get_block_len ($2), strings, $3->type, $3->string); } if ($2) { if ($$ == NULL) { /* if problems, free enum'd vals */ while ((wp = pop_block ($2))) if (wp) free (wp); if ($3 && $3->string) free ($3->string); } free ($2); } if ($3) free ($3); } } ; NotationType : LEFTPAREND NoteNameAlternatives RIGHTPAREND { if (validating (this_file)) /* pass malloc_block_list on up */ $$ = $2; } NoteNameAlternatives : NoteNameAlternatives VSLASH NameOrNmtoken { size_t len; if (validating (this_file)) { if (! expand_notname (this_file, $3)) /* not a declared notation name */ add_xml_warning (this_file, 810, $3); /* add alternative to list */ len = uni_strlen ($3) + 1; len *= sizeof (my_wchar_t); $$ = push_block ($1, $3, len); } } | NameOrNmtoken { size_t len; if (validating (this_file)) { if (! expand_notname (this_file, $1)) /* not a declared notation name */ add_xml_warning (this_file, 810, $1); len = uni_strlen ($1) + 1; len *= sizeof (my_wchar_t); $$ = push_block (NULL, $1, len); } } ; Enumeration : LEFTPAREND NmtokenAlternatives RIGHTPAREND { if (validating (this_file)) /* pass malloc_block_list on up */ $$ = $2; } NmtokenAlternatives : NmtokenAlternatives VSLASH NameOrNmtoken { size_t len; if (validating (this_file)) { len = uni_strlen ($3) + 1; len *= sizeof (my_wchar_t); $$ = push_block ($1, $3, len); } } | NmtokenAlternatives COMMA NameOrNmtoken { my_wchar_t *tmp; size_t len; /* legal in SMGL, illegal in XML */ tmp = uni_strdup(utf_8_to_utf_16("\",\"")); add_xml_error (this_file, 603, tmp); free (tmp); if (validating (this_file)) { len = uni_strlen ($3) + 1; len *= sizeof (my_wchar_t); $$ = push_block ($1, $3, len); } } | NameOrNmtoken { size_t len; if (validating (this_file)) { len = uni_strlen ($1) + 1; len *= sizeof (my_wchar_t); $$ = push_block (NULL, $1, len); } } ; DefaultDecl : NameOrNmtoken { struct default_decl *d; /* change this && change QUOTEDSTRING rule */ if (YYRECOVERING ()) YYERROR; else { /* oops; forgot to quote default */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 600, $1); if (uni_utf_strcasecmp ($1, "REQUIRED") == 0) add_xml_error (this_file, 511, $1); if (uni_utf_strcasecmp ($1, "IMPLIED") == 0) add_xml_error (this_file, 511, $1); if (yychar == NAME) this_file->lineno++; if (validating (this_file)) { d = malloc (sizeof (struct default_decl)); /* whitespace gets normalized later on */ d->string = uni_strdup ($1); d->type = defaulted; $$ = d; } } } | NameOrNmtoken QUOTEDSTRING { int errnum; struct default_decl *d; /* change this && change QUOTEDSTRING rule */ if (YYRECOVERING ()) YYERROR; else { if (yychar == NAME) this_file->lineno--; errnum = uni_utf_strcasecmp ($1, "FIXED") ? 612 : 511; add_xml_error (this_file, errnum, $1); if (yychar == NAME) this_file->lineno++; if (validating (this_file)) { d = malloc (sizeof (struct default_decl)); /* whitespace gets normalized later on */ d->string = uni_strdup ($2); d->type = defaulted; $$ = d; } } } | CONREF { struct default_decl *d; /* #CONREF isn't allowed in XML */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 601, $1); if (yychar == NAME) this_file->lineno++; if (validating (this_file)) { /* treat it as #IMPLIED */ d = malloc (sizeof (struct default_decl)); d->type = implied; d->string = NULL; $$ = d; } } | CURRENT { struct default_decl *d; /* #CURRENT isn't allowed in XML */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 601, $1); if (yychar == NAME) this_file->lineno++; if (validating (this_file)) { /* treat it as #IMPLIED */ d = malloc (sizeof (struct default_decl)); d->type = implied; d->string = NULL; $$ = d; } } | FIXED NameOrNmtoken { struct default_decl *d; /* oops; forgot to quote default */ if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 600, $2); if (yychar == NAME) this_file->lineno++; check_case (this_file, $1, yes); if (validating (this_file)) { d = malloc (sizeof (struct default_decl)); /* whitespace gets normalized later on */ d->string = uni_strdup ($2); d->type = fixed; $$ = d; } } | REQUIRED QUOTEDSTRING { struct default_decl *d; if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 590, $2); if (yychar == NAME) this_file->lineno++; check_case (this_file, $1, yes); if (validating (this_file)) { d = malloc (sizeof (struct default_decl)); d->type = required; d->string = NULL; $$ = d; } } | REQUIRED { struct default_decl *d; check_case (this_file, $1, yes); if (validating (this_file)) { d = malloc (sizeof(struct default_decl)); d->type = required; d->string = NULL; $$ = d; } } | IMPLIED QUOTEDSTRING { struct default_decl *d; if (yychar == NAME) this_file->lineno--; add_xml_error (this_file, 590, $2); if (yychar == NAME) this_file->lineno++; check_case (this_file, $1, yes); if (validating (this_file)) { d = malloc (sizeof(struct default_decl)); d->type = implied; d->string = NULL; $$ = d; } } | IMPLIED { struct default_decl *d; check_case (this_file, $1, yes); if (validating (this_file)) { d = malloc (sizeof(struct default_decl)); d->type = implied; d->string = NULL; $$ = d; } } | QUOTEDSTRING { struct default_decl *d; /* change this && change NameOrNmtoken rule */ if (validating (this_file)) { if (in_external_dtd_subset (this_file) && this_file->standalone == yes) { /* ext att default in standalone doc */ if (yychar == NAME) this_file->lineno--; add_xml_warning (this_file, 592, $1); if (yychar == NAME) this_file->lineno++; } if (uni_strchr ($1, '<')) add_xml_error (this_file, 1230, $1); d = malloc (sizeof (struct default_decl)); /* whitespace gets normalized later on */ d->string = uni_strdup ($1); d->type = defaulted; $$ = d; } } | FIXED QUOTEDSTRING { /* change this rule, change the one above */ struct default_decl *d; check_case (this_file, $1, yes); if (validating (this_file)) { if (in_external_dtd_subset (this_file) && this_file->standalone == yes) { /* ext att default in standalone doc */ if (yychar == NAME) this_file->lineno--; add_xml_warning (this_file, 592, $1); if (yychar == NAME) this_file->lineno++; } if (uni_strchr ($2, '<')) add_xml_error (this_file, 1230, $2); d = malloc (sizeof (struct default_decl)); /* whitespace gets normalized later on */ d->string = uni_strdup ($2); d->type = fixed; $$ = d; } } ; PEntityDecl : PARAMETER_ENTITY_DECL_DELIM error DECL_END { my_wchar_t *wp; /* catch-all error production */ wp = utf_8_to_utf_16 ("standalone == yes) add_xml_warning (this_file, 803, $2); } ExternalSubset END_FILE { char *msg; int i, len; my_wchar_t *wp; struct xml_file *xf; /* save this_file; switch to old stream */ xf = this_file; if (what_are_we_scanning () == file) pop_xml_file (); if (! validating (this_file)) { if (! $6) /* if $6 is false, sub-parse failed */ add_xml_error (this_file, 771, $2); } else { /* add to parameter_entity_names tbl */ wp = add_ext_peref (this_file, $2, xf, UNRESOLVABLES_OKAY | MAP_PARAMETER_ENTITIES | MAP_CHAR_ENTITIES); /* check for balanced <, > delims */ if (wp && (i = check_gt_and_lt (wp))) { len = strlen (xf->filename); msg = malloc (len + 32 + 1); sprintf (msg, "%s, line %d", xf->filename, i); add_xml_error (this_file, 771, utf_8_to_utf_16 (msg)); free (msg); } } /* sic; $2 refers to Name above */ xwrap (errdebug (5, "Done ext ent.\n")); /* * ExternalSubset was only a preliminary * scan, so take out most error messages */ remove_all_errors_and_warnings_except ($3, 330, 331, 332, 333, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 381, 382, 383, 384, 385, 386, 410, 411, 460, 461, 465, 466, 501, 502, 503, 505, 510, 511, 550, 567, 568, 569, 586, 590, 591, 600, 603, 653, 654, 655, 658, 659, 673, 675, 678, 681, 682, 684, 685, 745, 756, 757, 758, 781, 820, 821, 822, 830, 850, 851, 852, 900, 901, 902, 903, 1002, 1004, 1014, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1112, 1300, 1301, 1310, 1311, 1312, 1315, 1350, 1380, 1381, 1382, /* don't forget the zero -> */ 0); } | PARAMETER_ENTITY_DECL_DELIM Name PubID DECL_END { /* Unlike SGML, XML needs a SysID here */ add_xml_error (this_file, 820, $2); } ; EntityDecl : ENTITYDECL_DELIM error DECL_END { my_wchar_t *wp; /* catch-all error production */ wp = utf_8_to_utf_16 ("standalone == yes && in_external_dtd_subset (this_file)) add_xml_warning (this_file, 753, $2); } Content END_FILE { /* pop_xml_file switches to old stream */ if (what_are_we_scanning () == entity_replacement_text) pop_xml_file (); xwrap (errdebug (7, "Entity text OK.\n")); } | ENTITYDECL_DELIM Name QUOTEDSTRING DECL_END { my_wchar_t *expan; if ($3 && validating (this_file)) { /* If built-in, declared correctly? */ check_builtin (this_file, $2, $3); /* Can't have internal PErefs */ if (! in_external_dtd_subset (this_file)) if (uni_strchr ($3, '%')) add_xml_error (this_file, 842, $3); /* map_entities calls malloc */ expan = map_entities (this_file, $3, FLAG_BYPASSED_AMPERSANDS | MAP_PARAMETER_ENTITIES | MAP_CHAR_ENTITIES, 0); /* add to entity_names table */ add_eref (this_file, $2, expan); push_entity_text (this_file, expan, 0); free (expan); } else { /* If we get to here, QUOTEDSTRING is * NULL or we aren't validating because * we're in an external entity, etc. */ if (! validating (this_file)) { /* Builtin redefined in an external entity? */ if (is_builtin ($2)) add_xml_warning (this_file, 756, $2); else if ($3) { if (uni_utf_strncmp ($2, "per", 3) == 0 && uni_utf_strcmp ($3, "%") == 0) add_xml_warning (this_file, 757, $2); else if ($3[0] == '%' && $3[1] == 0) add_xml_warning (this_file, 758, $2); } } expan = utf_8_to_utf_16 (""); push_entity_text (this_file, expan, 0); } if (this_file->standalone == yes && in_external_dtd_subset (this_file)) add_xml_warning (this_file, 753, $2); } Content END_FILE { /* pop_xml_file switches to old stream */ if (what_are_we_scanning () == entity_replacement_text) pop_xml_file (); xwrap (errdebug (7, "Entity text OK.\n")); } | ENTITYDECL_DELIM Name SDATA QUOTEDSTRING DECL_END { my_wchar_t *expan; /* SDATA doesn't exist in XML */ add_xml_error (this_file, 821, $2); if ($4 && validating (this_file)) { /* If built-in, declared correctly? */ check_builtin (this_file, $2, $4); /* Can't have internal PErefs */ if (! in_external_dtd_subset (this_file)) if (uni_strchr ($3, '%')) add_xml_error (this_file, 842, $3); /* map_entities calls malloc */ expan = map_entities (this_file, $4, MAP_PARAMETER_ENTITIES | MAP_CHAR_ENTITIES, 0); /* add to entity_names table */ add_eref (this_file, $2, expan); push_entity_text (this_file, expan, 0); free (expan); } else { expan = utf_8_to_utf_16 (""); push_entity_text (this_file, expan, 0); } if (this_file->standalone == yes && in_external_dtd_subset (this_file)) add_xml_warning (this_file, 753, $2); } Content END_FILE { /* pop_xml_file switches to old stream */ if (what_are_we_scanning () == entity_replacement_text) pop_xml_file (); xwrap (errdebug (7, "Entity text OK.\n")); } | ENTITYDECL_DELIM Name CDATA_ QUOTEDSTRING DECL_END { my_wchar_t *expan; /* CDATA entities aren't allowed in XML */ add_xml_error (this_file, 821, $2); if ($4 && validating (this_file)) { /* If built-in, declared correctly? */ check_builtin (this_file, $2, $4); /* Can't have internal PErefs */ if (! in_external_dtd_subset (this_file)) if (uni_strchr ($3, '%')) add_xml_error (this_file, 842, $3); /* map_entities calls malloc */ expan = map_entities (this_file, $4, MAP_PARAMETER_ENTITIES | MAP_CHAR_ENTITIES, 0); /* add to entity_names table */ add_eref (this_file, $2, expan); push_entity_text (this_file, expan, 0); free (expan); } else { expan = utf_8_to_utf_16 (""); push_entity_text (this_file, expan, 0); } if (this_file->standalone == yes && in_external_dtd_subset (this_file)) add_xml_warning (this_file, 753, $2); } Content END_FILE { /* pop_xml_file switches to old stream */ if (what_are_we_scanning () == entity_replacement_text) pop_xml_file (); xwrap (errdebug (7, "Entity text OK.\n")); } | ENTITYDECL_DELIM Name ExternalID DECL_END { struct xml_file *xf; if (! validating (this_file)) { if ($3) free_xml_file ($3); xf = NULL; } else { if ((xf = $3)) { if (add_xml_file_nomerge (this_file, xf) && validating (this_file)) { add_ext_eref (this_file, $2, xf, MAP_PARAMETER_ENTITIES | MAP_CHAR_ENTITIES); } else { /* we aren't using it; free it */ free_xml_file (xf); xf = NULL; } } } if (! xf) if ((xf = create_xml_file ("/dev/null"))) add_xml_file_nomerge (this_file, xf); if (xf) { /* see below, pop_xml_file() */ push_xml_file (xf, INITIAL); $3 = xf; } /* external ent in standalone file */ if (this_file->standalone == yes) add_xml_warning (this_file, 803, $2); } ExternalContent END_FILE { /* pop_xml_file switches to old stream */ if (what_are_we_scanning () == file) pop_xml_file (); if (! $6) /* $6 returns false if parse failed */ add_xml_error (this_file, 305, $2); /* sic; $2 refers to Name above */ xwrap (errdebug (7, "Done ext entity.\n")); } | ENTITYDECL_DELIM Name PubID DECL_END { /* Unlike SGML, XML needs a SysID here */ add_xml_error (this_file, 820, $2); } | ENTITYDECL_DELIM Name ExternalID NDataDecl DECL_END { char *p; my_wchar_t *sysid; if (validating (this_file)) { if (is_builtin ($2)) add_xml_error (this_file, 754, $2); if ($4) { p = $3 ? $3->filename : "(unresolvable URI)"; sysid = utf_8_to_utf_16 (p); /* add to unparsed entity table */ add_uperef (this_file, $2, $4, sysid); } if (this_file->standalone == yes && in_external_dtd_subset (this_file)) /* external ent in standalone file */ add_xml_warning (this_file, 753, $2); } if ($3) /* don't need the external ID file struct */ free_xml_file ($3); } | ENTITYDECL_DELIM Name PubID NDataDecl DECL_END { /* Unlike SGML, XML needs a SysID here */ add_xml_error (this_file, 820, $2); } ; NDataDecl : NDATA Name { check_case (this_file, $1, no); if (validating (this_file)) $$ = $2; } NotationDecl : NOTATIONDECL_DELIM Name PubID QUOTEDSTRING DECL_END { my_wchar_t *sysid; /* this variable is set in the lexer */ if (validating (this_file)) { if ($3 == NULL) /* error msg already generated */ add_notname (this_file, $2, $4); else { /* try to convert pubid to sysid, and * save it; if this fails, use sysid */ sysid = resolve_pubid_as_uri ( this_file, $3); if (sysid != NULL) add_notname (this_file, $2, sysid); else { uni_map_whitespace_to_space ($3); uni_map_spaces_to_space ($3); add_xml_warning (this_file, 562, $3); add_notname (this_file, $2, $4); } } } } | NOTATIONDECL_DELIM Name SysID DECL_END { /* this variable is set in the lexer */ if (validating (this_file)) { if ($3 == NULL) add_xml_error (this_file, 563, NULL); else { /* add sysid to table literally */ add_notname (this_file, $2, $3); } } } | NOTATIONDECL_DELIM Name PubID DECL_END { my_wchar_t *sysid; /* this variable is set in the lexer */ if (validating (this_file)) { if ($3 == NULL) add_xml_error (this_file, 562, NULL); else { /* convert pubid to sysid and add it */ sysid = resolve_pubid_as_uri ( this_file, $3); if (sysid != NULL) add_notname (this_file, $2, sysid); else { uni_map_whitespace_to_space ($3); uni_map_spaces_to_space ($3); add_xml_warning (this_file, 562, $3); add_notname (this_file, $2, $3); } } } } ; BadDecl : BAD_DECL error DECL_END { add_xml_error (this_file, 500, $1); } | BAD_DECL DECL_END { add_xml_error (this_file, 500, $1); } ; Comment : COMMENT_DELIM error { my_wchar_t *tmp; /* line numbers may now be off */ add_xml_error (this_file, 321, NULL); /* generally bogus comment */ tmp = utf_8_to_utf_16 ("