source: trunk/src/engine.c @ 175

Last change on this file since 175 was 175, checked in by lindanl, 11 years ago

Pubidliteral in ; skip general entityRef in entityValue.

File size: 70.0 KB
Line 
1/*  engine.c - Parabix XML parsing engine.
2    Copyright (c) 2007, 2008, Robert D. Cameron and Dan Lin.
3    Licensed to the public under the Open Software License 3.0.
4    Licensed to International Characters, Inc., under the Academic
5    Free License 3.0.
6*/
7
8#include "engine.h"
9#include "byteplex.h"
10#include "xmldecl.h"
11#include "bytelex.h"
12#include "bitlex.h"
13#include "contentmodel.h"
14#include "contentmodel.c"
15#include "xml_error.h"
16
17#include <assert.h>
18#include <stdlib.h>
19#include <errno.h>
20#include <string.h>
21#include <string>
22#include <iostream>
23using namespace std;
24       
25inline char * copy_string (unsigned char * s, int lgth){               
26        char * d = new char[lgth+1];
27        memcpy(d, (char *)s,lgth); 
28        d[lgth] = '\0'; 
29        return d;
30}
31
32inline char * cat_string (char * s1, char * s2, int lgth1, int lgth2){
33        char * s = new char[lgth1 + lgth2 + 1];
34        memcpy(s, s1,lgth1);
35        memcpy(&s[lgth1],s2,lgth2);
36        s[lgth1 + lgth2] = '\0';
37        return s;
38}
39       
40       
41       
42Parser_Interface * Parser_Interface::ParserFactory(char * filename) {
43       
44        int chars_read;
45        unsigned char signature[4];
46        FILE * infile;
47        infile = fopen(filename, "rb");
48        if (!infile) {
49                fprintf(stderr, "Error: cannot open %s for input.\n", filename);
50                exit(-1);
51        }
52        fread(signature,1,4,infile);
53        Entity_Info * e = new Entity_Info;
54        Model_Info * m = new Model_Info;
55        e->AnalyzeSignature(signature);
56        Byteplex * b = Byteplex::ByteplexFactory(e, infile);
57        b->InitializeBuffer(signature,4);
58        b->DoByteplex();
59        b->PreparePseudoASCII_Stream();
60       
61        if (e->code_unit_base == ASCII) {
62                XML_Decl_Parser<ASCII> decl_parser(b);
63                decl_parser.ReadXMLInfo(*e);
64                if (e->code_unit_size == SingleByte) {
65                        if (!(e->has_encoding_decl) || at_UTF_8(e->encoding))
66                                return new ParsingEngine< UTF8_Buffer>(e, m, b, false);         
67                        else return new ParsingEngine< X8_Buffer<ASCII> >(e, m, b, false);
68                }
69                else if (e->code_unit_size == DoubleByte) {
70                        return new ParsingEngine<U16_Buffer>(e, m, b, false);
71                }
72                else if (e->code_unit_size == QuadByte) {
73                        return new ParsingEngine<U32_Buffer>(e, m, b, false);
74                }
75        }
76        else /* if (e->code_unit_base == EBCDIC) */ {
77                XML_Decl_Parser<EBCDIC> decl_parser(b);
78                decl_parser.ReadXMLInfo(*e);
79                return new ParsingEngine< X8_Buffer<EBCDIC> >(e, m, b, false);
80        }       
81}
82
83Parser_Interface * Parser_Interface::ParserFactory(char * filename, Model_Info * m) {
84       
85        int chars_read;
86        unsigned char signature[4];
87        FILE * infile;
88        infile = fopen(filename, "rb");
89        if (!infile) {
90                fprintf(stderr, "Error: cannot open %s for input.\n", filename);
91                exit(-1);
92        }
93        fread(signature,1,4,infile);
94        Entity_Info * e = new Entity_Info;
95        e->AnalyzeSignature(signature);
96        Byteplex * b = Byteplex::ByteplexFactory(e, infile);
97        b->InitializeBuffer(signature,4);
98        b->DoByteplex();
99        b->PreparePseudoASCII_Stream();
100        if (e->code_unit_base == ASCII) {
101                XML_Decl_Parser<ASCII> decl_parser(b);
102                decl_parser.ReadXMLInfo(*e);
103                if (e->code_unit_size == SingleByte) {
104                        return new ParsingEngine< X8_Buffer<ASCII> >(e, m, b, true);
105                }
106                else if (e->code_unit_size == DoubleByte) {
107                        return new ParsingEngine<U16_Buffer>(e, m, b, true);
108                }
109                else if (e->code_unit_size == QuadByte) {
110                        return new ParsingEngine<U32_Buffer>(e, m, b, true);
111                }
112        }
113        else /* if (e->code_unit_base == EBCDIC) */ {
114                XML_Decl_Parser<EBCDIC> decl_parser(b);
115                decl_parser.ReadXMLInfo(*e);
116                return new ParsingEngine< X8_Buffer<EBCDIC> >(e, m, b, true);
117        }       
118}
119
120Parser_Interface * Parser_Interface::ParserFactory(char * byte_buffer, int byte_count, Entity_Info * e1, Model_Info * m){
121        Entity_Info * e = new Entity_Info;
122        e->BOM_units = 0;
123        e->code_unit_base=e1->code_unit_base;
124        e->code_unit_size=e1->code_unit_size;
125        e->version=e1->version;
126        e->encoding=e1->encoding;
127        e->content_start = 0;
128        Byteplex * b = Byteplex::ByteplexFactory(e, (unsigned char *) byte_buffer, byte_count);
129        b->DoByteplex();
130        b->PreparePseudoASCII_Stream();
131        if (e->code_unit_base == ASCII) {
132                if (e->code_unit_size == SingleByte) {
133                        return new ParsingEngine< X8_Buffer<ASCII> >(e, m, b, false);
134                }
135                else if (e->code_unit_size == DoubleByte) {
136                        return new ParsingEngine<U16_Buffer>(e, m, b, false);
137                }
138                else if (e->code_unit_size == QuadByte) {
139                        return new ParsingEngine<U32_Buffer>(e, m, b, false);
140                }
141        }
142        else /* if (e->code_unit_base == EBCDIC) */ {
143                return new ParsingEngine< X8_Buffer<EBCDIC> >(e, m, b, false);
144        }       
145}
146
147Parser_Interface::~Parser_Interface() {
148}
149
150
151bool Parser_Interface::has_ByteOrderMark() {
152        return entity_Info->BOM_units > 0;
153}
154
155XML_version Parser_Interface::get_version() {
156        return entity_Info->version;
157}
158
159XML_standalone Parser_Interface::standalone_status() {
160        return entity_Info->standalone;
161}
162
163bool Parser_Interface::has_EncodingDecl() {
164        return entity_Info->has_encoding_decl;
165}
166
167unsigned char * Parser_Interface::get_Encoding() {
168        return entity_Info->encoding;
169}
170
171unsigned char * Parser_Interface::GetCodeUnitPtr(int pos) {
172        int rel_pos = pos - buffer_base_pos;
173        return &((unsigned char *) (byteplex->src_buffer))[rel_pos * (int) entity_Info->code_unit_size];
174}
175
176template <class B>
177inline unsigned char * ParsingEngine<B>::GetCodeUnitPtr(int pos) {
178        int rel_pos = pos - buffer_base_pos;
179        return &((unsigned char *) (byteplex->src_buffer))[rel_pos * (int) B::Size];
180}
181
182
183
184
185template <class B>
186ParsingEngine<B>::ParsingEngine(Entity_Info * e, Model_Info * m, Byteplex * b, bool is_external) : Parser_Interface () {
187        entity_Info = e;
188        model_info = m;
189        byteplex = b;
190
191//      m->symbol_table = new Symbol_Table();
192//      m->SimpleEntity("lt", "<");
193//      m->SimpleEntity("gt", ">");
194//      m->SimpleEntity("amp", "&");
195//      m->SimpleEntity("quot", "\"");
196//      m->SimpleEntity("apos", "'");   
197        m->symbol_table->version = e->version;
198
199        StrictWellFormedness=false;
200        LastAttOccurrence.assign(m->globalAttributeCount+1, 0);
201       
202       
203        bitplex = new Bitplex;
204        buf = (LexicalStreamSet *) simd_new(sizeof(LexicalStreamSet)/PACKSIZE);
205
206  /* Install sentinels for every lexical item stream*/
207#ifndef OPTIMIZE_SHORT_SCAN
208        BitBlock sentinel_value = simd_const_1(1);
209#endif
210#ifdef OPTIMIZE_SHORT_SCAN
211        BitBlock sentinel_value = sisd_sfli(simd_const_1(1), 8*sizeof(unsigned long));
212#endif
213        for (int j = minLexicalItem; j < LexicalItemCount; j++) {
214                buf->item_stream[j][BUFFER_BLOCKS] = sentinel_value;
215        }
216
217        buffer_base_pos = 0;
218        buffer_rel_pos = e->content_start;
219        buffer_limit_pos = min(BUFFER_SIZE, byteplex->units_in_buffer);
220        int blocks_in_buffer = (buffer_limit_pos + BLOCKSIZE - 1)/BLOCKSIZE;
221        x8data = byteplex->x8data;
222        lexer = Lexer<B::Base>::LexerFactory(e, buf);
223        bitplex->TransposeToBitStreams(byteplex->x8data, blocks_in_buffer);
224        lexer->AnalyzeBuffer(bitplex->x8basis, buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
225}
226
227template <class B>
228ParsingEngine<B>::~ParsingEngine() {
229  // How do we do this?  model_info->~Model_Info();
230  entity_Info->~Entity_Info();
231  byteplex->~Byteplex();
232  bitplex->~Bitplex();
233  simd_delete((SIMD_type *) buf);
234  lexer->~Lexer_Interface();
235}
236
237template <class B>
238inline void ParsingEngine<B>::AdvanceBuffers(){
239#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
240        code_clocker->cc_start_interval();
241#endif
242
243        int advance_amt = text_or_markup_start - buffer_base_pos;
244        advance_amt &= -PACKSIZE; // maintain alignment
245        byteplex->AdvanceInputBuffer(advance_amt);
246        buffer_base_pos += advance_amt;
247        buffer_rel_pos -= advance_amt;
248        buffer_limit_pos = min(BUFFER_SIZE, byteplex->units_in_buffer);
249        int blocks_in_buffer = (buffer_limit_pos + BLOCKSIZE - 1)/BLOCKSIZE;
250#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
251        code_clocker->cc_start_interval();
252#endif
253        byteplex->DoByteplex();
254        byteplex->PreparePseudoASCII_Stream();
255#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
256        code_clocker->cc_end_interval(buffer_limit_pos);
257#endif
258#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
259        code_clocker->cc_start_interval();
260#endif
261        bitplex->TransposeToBitStreams(byteplex->x8data, blocks_in_buffer);
262#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
263        code_clocker->cc_end_interval(buffer_limit_pos);
264#endif
265        lexer->AnalyzeBuffer(bitplex->x8basis, buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
266#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
267        code_clocker->cc_end_interval(buffer_limit_pos);
268#endif
269
270}
271
272template <>
273inline void ParsingEngine<U16_Buffer>::AdvanceBuffers(){
274#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
275        code_clocker->cc_start_interval();
276#endif
277
278        int advance_amt = text_or_markup_start - buffer_base_pos;
279        advance_amt &= -PACKSIZE; // maintain alignment
280        byteplex->AdvanceInputBuffer(advance_amt);
281        buffer_base_pos += advance_amt;
282        buffer_rel_pos -= advance_amt;
283        buffer_limit_pos = min(BUFFER_SIZE, byteplex->units_in_buffer);
284        int blocks_in_buffer = (buffer_limit_pos + BLOCKSIZE - 1)/BLOCKSIZE;
285#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
286        code_clocker->cc_start_interval();
287#endif
288        byteplex->DoByteplex();
289        if (at_UTF_16(entity_Info->encoding)) ((U16_Buffer *) byteplex)->Validate_UTF16();
290        byteplex->PreparePseudoASCII_Stream();
291#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
292        code_clocker->cc_end_interval(buffer_limit_pos);
293#endif
294#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
295        code_clocker->cc_start_interval();
296#endif
297        bitplex->TransposeToBitStreams(byteplex->x8data, blocks_in_buffer);
298#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
299        code_clocker->cc_end_interval(buffer_limit_pos);
300#endif
301        lexer->AnalyzeBuffer(bitplex->x8basis, buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
302#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
303        code_clocker->cc_end_interval(buffer_limit_pos);
304#endif
305
306}
307
308template <class B>
309inline unsigned char * ParsingEngine<B>::cur() const {
310  return &((unsigned char *) x8data)[buffer_rel_pos];
311}
312
313template <class B>
314inline int ParsingEngine<B>::AbsPos() const {
315  return buffer_base_pos + buffer_rel_pos;
316}
317
318template <class B>
319inline int ParsingEngine<B>::LengthFrom(int start_pos) const {
320  return buffer_base_pos + buffer_rel_pos - start_pos;
321}
322
323
324
325template <class B>
326inline int ParsingEngine<B>::BufferRelPos() const {
327  return buffer_rel_pos;
328}
329
330
331template <class B>
332inline bool ParsingEngine<B>::at_EOF() const {
333  return (buffer_rel_pos >= buffer_limit_pos) && 
334         (buffer_limit_pos < BUFFER_SIZE);
335}
336
337template <class B>
338inline void ParsingEngine<B>::Advance(int n) {
339        buffer_rel_pos += n;
340  if (buffer_rel_pos >= BUFFER_SIZE) { 
341        FinalizeBuffer_action();
342        AdvanceBuffers();
343  }
344}
345
346template <class B> 
347inline void ParsingEngine<B>::AdjustBufferEndForIncompleteSequences() {
348}
349
350template <> 
351inline void ParsingEngine<UTF8_Buffer>::AdjustBufferEndForIncompleteSequences() {
352        if (*(cur()-1) >= 0xC0) buffer_rel_pos--;
353        else if (*(cur()-2) >= 0xE0) buffer_rel_pos -= 2;
354        else if (*(cur()-3) >= 0xF0) buffer_rel_pos -= 3;
355}
356
357template <> 
358inline void ParsingEngine<U16_Buffer>::AdjustBufferEndForIncompleteSequences() {
359        unsigned short last_u16_unit = *(GetCodeUnitPtr(AbsPos()-1));
360        if ((last_u16_unit >= 0xD800) & (last_u16_unit <= 0xDC00)) buffer_rel_pos--;
361}
362
363
364#ifndef OPTIMIZE_SHORT_SCAN
365template <class B>
366inline void ParsingEngine<B>::ScanTo(int item) {
367  buffer_rel_pos = bitstream_scan(buf->item_stream[item], 
368                                      buffer_rel_pos);
369  while (buffer_rel_pos >= BUFFER_SIZE) {
370        AdjustBufferEndForIncompleteSequences();
371        FinalizeBuffer_action();
372        AdvanceBuffers();
373        buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
374  }
375}
376#endif
377
378template <class B>
379inline void ParsingEngine<B>::ScanToMarkupStart() {
380        text_or_markup_start = AbsPos();
381        buffer_rel_pos = bitstream_scan(buf->item_stream[MarkupStart], buffer_rel_pos);
382        while (buffer_rel_pos >= BUFFER_SIZE) {
383                AdjustBufferEndForIncompleteSequences();
384                Text_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
385                text_or_markup_start = AbsPos();
386                FinalizeBuffer_action();
387                AdvanceBuffers();
388                buffer_rel_pos = bitstream_scan(buf->item_stream[MarkupStart], buffer_rel_pos);
389        }
390}
391
392template <class B>
393inline void ParsingEngine<B>::ScanToCD_End_check() {
394        buffer_rel_pos = bitstream_scan(buf->item_stream[CD_End_check], buffer_rel_pos);
395        while (buffer_rel_pos >= BUFFER_SIZE) {
396                AdjustBufferEndForIncompleteSequences();
397                Text_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
398                text_or_markup_start = AbsPos();
399                FinalizeBuffer_action();
400                AdvanceBuffers();
401                buffer_rel_pos = bitstream_scan(buf->item_stream[CD_End_check], buffer_rel_pos);
402        }
403}
404
405#ifdef OPTIMIZE_SHORT_SCAN
406template <class B>
407inline void ParsingEngine<B>::ScanTo(int item) {
408  SIMD_type * stream = buf->item_stream[item];
409  unsigned long * bitstream_ptr = (unsigned long *) (((intptr_t) stream) + buffer_rel_pos/8);
410  unsigned long bitstream_slice = *bitstream_ptr >> buffer_rel_pos % 8;
411  if (bitstream_slice != 0) {
412    buffer_rel_pos += __builtin_ctzl(bitstream_slice);
413  }
414  else {
415    buffer_rel_pos = (buffer_rel_pos & -8) + 8*sizeof(unsigned long);
416    buffer_rel_pos += bitstream_scan0((SIMD_type *) &bitstream_ptr[1]);
417    while (buffer_rel_pos >= BUFFER_BLOCKS * BLOCKSIZE) {
418        buffer_rel_pos = BUFFER_BLOCKS * BLOCKSIZE;
419        AdjustBufferEndForIncompleteSequences();
420        FinalizeBuffer_action();
421        AdvanceBuffers();
422      buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
423    }
424  }
425}
426#endif
427
428template <class B>
429inline void ParsingEngine<B>::WF_Error (XML_Constraint errCode) {
430        printf("Error at position %i in input.\n", AbsPos());
431        ShowConstraintError(errCode);
432        exit(-1);
433//      Error_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
434}
435       
436
437template <class B>
438inline void ParsingEngine<B>::Validity_Error (XML_Constraint errCode) {
439        printf("Error at position %i in input.\n", AbsPos());
440        ShowConstraintError(errCode);
441        exit(-1);
442//      Error_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
443}
444       
445template <class B>
446inline void ParsingEngine<B>::Syntax_Error (XML_NonTerminal errNT) {
447        printf("Error at position %i in input.\n", AbsPos());
448        ShowSyntaxError(errNT);
449        exit(-1);
450//      Error_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
451}
452       
453
454/* Parse a comment beginning "<!--" */
455template <class B>
456inline void ParsingEngine<B>::Parse_Comment() {
457
458        Advance(4); /* Skip "<!--". */
459        ScanTo(Hyphen);
460        while (!at_DoubleHyphen<B::Base>(cur())) {
461                if(at_EOF())
462                        Syntax_Error(NT_CDSect);
463                Advance(2); /* Skip hyphen-nonhyphen pair */
464                ScanTo(Hyphen); 
465        }
466        if (at_Comment_End<B::Base>(cur())) {
467                Advance(3); /* Skip "-->". */
468                Comment_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
469        }
470        else {
471                Advance(2);  /* "--" */
472                Syntax_Error(NT_Comment);
473        }
474}
475
476/* Parse an end tag beginning "</" */
477template <class B>
478inline void ParsingEngine<B>::Parse_EndTag() {
479        Advance(2); /* Skip "</". */
480        int nameID = Parse_Name();
481        if (AtChar<B::Base,'>'>(cur())) {
482                Advance(1);
483                EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
484        }
485        else {
486                ScanTo(NonWS);
487                if (AtChar<B::Base,'>'>(cur())) {
488                        Advance(1);
489                        EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
490                }
491                else Syntax_Error(NT_ETag);
492        }
493}
494
495/* Parse a CDATA section beginning "<![CDATA". */
496template <class B>
497inline void ParsingEngine<B>::Parse_CDATA() {
498                Advance(8); /* Skip "<![CDATA". */
499        if (!AtChar<B::Base,'['>(cur())) {
500                Syntax_Error(NT_CDStart);
501        }
502        else { 
503                Advance(1);
504                CDATA_start_action(GetCodeUnitPtr(text_or_markup_start));
505                text_or_markup_start = AbsPos();
506                ScanTo(CD_End_check);
507                while (!at_CDATA_End<B::Base>(cur())) {
508                        if(at_EOF())
509                                Syntax_Error(NT_CDSect);
510                        Advance(1);
511                        ScanTo(CD_End_check);
512                }
513                Text_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
514                Advance(3); /* Skip "]]>". */
515                CDATA_end_action(GetCodeUnitPtr(AbsPos()));
516        }
517}
518
519template <class B>
520inline void ParsingEngine<B>::Parse_EntityRef() {
521    Advance(1);  // skip "&"
522        int nameID = Parse_Name();  /* Name delimiter */
523    if (!AtChar<B::Base,';'>(cur())) {
524                Syntax_Error(NT_Reference);
525    }
526        else {
527                Advance(1);
528                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
529               
530                //      The following code will replace Reference_Action.
531                GEntity_info * this_info;
532                Parser_Interface * entity_parser;
533                int entityID = model_info->GlobalGEntityTable[nameID]; 
534                if (entityID == 0)
535                        WF_Error(wfErr_wf_entdeclared);
536                else{
537                        this_info = model_info->GEntityData[entityID-1];
538                        if (this_info->is_external){
539                               
540                        if (entity_Info->standalone != Standalone_no)
541                                WF_Error(wfErr_NoExternalRefs);
542                        else {
543                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
544                                        entity_parser->Parse_WF_Content();
545                                        if(!entity_parser->at_EOF())
546                                                Syntax_Error(NT_content);
547                                        entity_parser->~Parser_Interface();
548                        }
549                        }
550                        else {
551                                if (this_info->is_simple == true);
552//                                      printf("Entity is %s\n",this_info->ReplacementText);
553                                else{
554//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
555                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
556                                        entity_parser->Parse_WF_Content();
557                                        if(!entity_parser->at_EOF())
558                                                Syntax_Error(NT_content);
559                                        entity_parser->~Parser_Interface();
560                                }
561                        }
562                }
563               
564        }
565}
566
567template <class B>
568inline void ParsingEngine<B>::Parse_EntityRef_inMixed(symbol_set_t elems) {
569    Advance(1);  // skip "&"
570        int nameID = Parse_Name();  /* Name delimiter */
571    if (!AtChar<B::Base,';'>(cur())) {
572                Syntax_Error(NT_Reference);
573    }
574        else {
575                Advance(1);
576                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
577               
578                //      The following code will replace Reference_Action.
579                GEntity_info * this_info;
580                Parser_Interface * entity_parser;
581                int entityID = model_info->GlobalGEntityTable[nameID]; 
582                if (entityID == 0)
583                        WF_Error(wfErr_wf_entdeclared);
584                else{
585                        this_info = model_info->GEntityData[entityID-1];
586                        if (this_info->is_external){
587                               
588                        if (entity_Info->standalone != Standalone_no)
589                                WF_Error(wfErr_NoExternalRefs);
590                        else {
591                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
592                                        entity_parser->Parse_MixedContent(elems);
593                                        if(!entity_parser->at_EOF())
594                                                Syntax_Error(NT_content);
595                                        entity_parser->~Parser_Interface();
596                        }
597                        }
598                        else {
599                                if (this_info->is_simple == true);
600//                                      printf("Entity is %s\n",this_info->ReplacementText);
601                                else{
602//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
603                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
604                                        entity_parser->Parse_MixedContent(elems);
605                                        if(!entity_parser->at_EOF())
606                                                Syntax_Error(NT_content);
607                                        entity_parser->~Parser_Interface();
608                                }
609                        }
610                }
611               
612        }
613}
614
615template <class B>
616inline void ParsingEngine<B>::Parse_EntityRef_inAnyContent() {
617    Advance(1);  // skip "&"
618        int nameID = Parse_Name();  /* Name delimiter */
619    if (!AtChar<B::Base,';'>(cur())) {
620                Syntax_Error(NT_Reference);
621    }
622        else {
623                Advance(1);
624                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
625               
626                //      The following code will replace Reference_Action.
627                GEntity_info * this_info;
628                Parser_Interface * entity_parser;
629                int entityID = model_info->GlobalGEntityTable[nameID]; 
630                if (entityID == 0)
631                        WF_Error(wfErr_wf_entdeclared);
632                else{
633                        this_info = model_info->GEntityData[entityID-1];
634                        if (this_info->is_external){
635                               
636                        if (entity_Info->standalone != Standalone_no)
637                                WF_Error(wfErr_NoExternalRefs);
638                        else {
639                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
640                                        entity_parser->Parse_AnyContent();
641                                        if(!entity_parser->at_EOF())
642                                                Syntax_Error(NT_content);
643                                        entity_parser->~Parser_Interface();
644                        }
645                        }
646                        else {
647                                if (this_info->is_simple == true);
648//                                      printf("Entity is %s\n",this_info->ReplacementText);
649                                else{
650//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
651                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
652                                        entity_parser->Parse_AnyContent();
653                                        if(!entity_parser->at_EOF())
654                                                Syntax_Error(NT_content);
655                                        entity_parser->~Parser_Interface();
656                                }
657                        }
658                }
659               
660        }
661}
662
663template <class B>
664inline void ParsingEngine<B>::Parse_ValidEntityRef(CM_RegExp * cre, int & cur_state) {
665    Advance(1);  // skip "&"
666        int nameID = Parse_Name();  /* Name delimiter */
667    if (!AtChar<B::Base,';'>(cur())) {
668                Syntax_Error(NT_Reference);
669    }
670        else {
671                Advance(1);
672                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
673               
674                //      The following code will replace Reference_Action.
675                GEntity_info * this_info;
676                Parser_Interface * entity_parser;
677                int entityID = model_info->GlobalGEntityTable[nameID]; 
678                if (entityID == 0)
679                        WF_Error(wfErr_wf_entdeclared);
680                else{
681                        this_info = model_info->GEntityData[entityID-1];
682                        if (this_info->is_external){
683                               
684                        if (entity_Info->standalone != Standalone_no)
685                                WF_Error(wfErr_NoExternalRefs);
686                        else {
687                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
688                                        entity_parser->Parse_ValidContent(cre, cur_state);
689                                        if(!entity_parser->at_EOF())
690                                                Syntax_Error(NT_content);
691                                        entity_parser->~Parser_Interface();
692                        }
693                        }
694                        else {
695                                if (this_info->is_simple == true);
696//                                      printf("Entity is %s\n",this_info->ReplacementText);
697                                else{
698//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
699                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
700                                        entity_parser->Parse_ValidContent(cre, cur_state);
701                                        if(!entity_parser->at_EOF())
702                                                Syntax_Error(NT_content);
703                                        entity_parser->~Parser_Interface();
704                                }
705                        }
706                }
707               
708        }
709}
710       
711template <class B>
712inline void ParsingEngine<B>::Parse_CharRef() {
713        Advance(2);  // skip "&#"
714        int ch_val = 0;
715        if (AtChar<B::Base,'x'>(cur())) {
716                Advance(1);
717                while(at_HexDigit<B::Base>(cur())){
718                        ch_val = HexVal<B::Base>(cur()[0]) + (ch_val<<4);
719                        if (ch_val> 0x10FFFF )
720                                WF_Error(wfErr_wf_Legalchar);
721                        Advance(1);
722                }
723        }
724        else {
725                while(at_Digit<B::Base>(cur())){
726                        ch_val = DigitVal<B::Base>(cur()[0]) + ch_val*10;
727                        if (ch_val> 0x10FFFF )
728                                WF_Error(wfErr_wf_Legalchar);
729                        Advance(1);
730                }
731        }
732        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF))
733                                WF_Error(wfErr_wf_Legalchar);   
734                else  if (entity_Info->version != XML_1_1)
735                        if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA)))
736                                WF_Error(wfErr_wf_Legalchar); 
737                               
738        if (!AtChar<B::Base,';'>(cur())) {
739                        Syntax_Error(NT_CharRef);
740        }
741                else {
742                        Advance(1);
743                        Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
744                }
745}
746
747template <class B>
748inline void ParsingEngine<B>::Parse_PI (){
749        int nameID;
750        Advance(2); /* Skip "<?". */
751        int target_start = AbsPos();
752        if (at_XxMmLll<B::Base>(cur())) {
753                nameID = Parse_Name();
754                if (AbsPos() - target_start == 3) Syntax_Error(NT_PI);
755        }
756        else nameID = Parse_Name();
757        PI_Target_action(GetCodeUnitPtr(target_start), LengthFrom(target_start));
758        if (!at_PI_End<B::Base>(cur())) requireWS();
759        ScanTo(QMark);
760        while (!at_PI_End<B::Base>(cur())) {
761                if(at_EOF())
762                        Syntax_Error(NT_PI);
763                Advance(1);
764                ScanTo(QMark);
765        }
766        Advance(2); /* Skip "?>". */
767        PI_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
768}
769 
770/* Parse a start or empty element tag. */
771template <class B>
772inline void ParsingEngine<B>::Parse_StartTag (){
773        int att_name_start;
774        int att_val_start;
775        int att_name_end, att_val_end;
776        unsigned char quoteCh;
777        Advance(1);
778        int nameID = Parse_Name();  /* Name delimiter: WS, "/" or ">" */
779        ElementName_action(GetCodeUnitPtr(text_or_markup_start+1), LengthFrom(text_or_markup_start+1));
780        /* The following test optimizes the most common case of a
781        start tag with no attributes.  */
782        if (AtChar<B::Base,'>'>(cur())) {
783                Advance(1);
784                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
785        }
786        else {
787                ScanTo(NonWS);
788                if (AtChar<B::Base,'>'>(cur())) {
789                        Advance(1);
790                        StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
791                }
792                else if (at_EmptyElementDelim<B::Base>(cur())) {
793                        Advance(2);
794                        EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
795                }
796                else do {
797                        /* Must be an attribute-value pair or error. */
798                        att_name_start = AbsPos();
799                        int att_nameID = Parse_Name();
800                        att_name_end = AbsPos();
801               
802                        int attID = model_info->getOrInsertGlobalAttName(att_nameID);
803                        if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
804                        else {
805                                if (LastAttOccurrence[attID] > text_or_markup_start) {
806                                        WF_Error(wfErr_uniqattspec); /* Duplicate attribute. */
807                                        break;
808                                }                       
809                        }
810                        LastAttOccurrence[attID] = att_name_start;
811                        /* The following optimized tests handle the frequently occurring
812                        case that there are no blanks on either side of the equals sign.
813                        In many cases, the very first test handles 100% of actual
814                        attribute-value pairs encountered. */
815                        if (at_EqualsQuote<B::Base>(cur())) Advance(1); 
816                        else {
817                                ScanTo(NonWS);
818                                if (!AtChar<B::Base,'='>(cur())) {
819                                        Syntax_Error(NT_STag); 
820                                        break;
821                                }
822                                Advance(1);
823                                ScanTo(NonWS);
824                                if (!AtQuote<B::Base>(cur())) {
825                                        Syntax_Error(NT_STag); 
826                                        break;
827                                }
828                        }
829                        att_val_start = AbsPos()+1;
830                        Parse_AttValue();
831                        att_val_end = AbsPos()-1;
832                        if (at_xmlns<B::Base>(cur()+att_name_start-AbsPos())) {
833                                Namespace_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
834                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
835                        }
836                        else {
837                                AttributeValue_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
838                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
839                        }
840                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
841                        if (AtChar<B::Base,'>'>(cur())) {
842                                Advance(1);
843                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
844                                break;
845                        }
846                        else if (at_EmptyElementDelim<B::Base>(cur())) {
847                                Advance(2);
848                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
849                                break;
850                        }
851                        ScanTo(NonWS);
852                        if (AtChar<B::Base,'>'>(cur())) {
853                                Advance(1);
854                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
855                                break;
856                        }
857                        else if (at_EmptyElementDelim<B::Base>(cur())) {
858                                Advance(2);
859                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
860                                break;
861                        }
862                        else if (AbsPos() == att_val_end + 1) { 
863                                /* No WS following att value */
864                                Syntax_Error(NT_STag);
865                                break;
866                        }
867                } while (1);
868        }
869}
870
871template <class B>
872inline void ParsingEngine<B>::text_if_nonnull_action(){
873        if (AbsPos() > text_or_markup_start) {
874                Text_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
875                text_or_markup_start = AbsPos();
876        }
877}
878
879template <class B>
880inline void ParsingEngine<B>::Parse_WF_EndTag(int nameID) {
881        Advance(2);
882        int end_nameID = Parse_Name();
883        if(end_nameID != nameID)
884                WF_Error(wfErr_GIMatch);
885        if (AtChar<B::Base,'>'>(cur())) {
886                Advance(1);
887                EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
888        }
889    else {
890                ScanTo(NonWS);
891                if (AtChar<B::Base,'>'>(cur())) {
892                        Advance(1);
893                        EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
894                }
895                else Syntax_Error(NT_ETag);
896    }
897}
898
899template <>
900inline void ParsingEngine<UTF8_Buffer>::Parse_WF_EndTag(int nameID) {
901        Advance(2); /* Skip "</". */
902       
903        int name_start = AbsPos();
904//      ScanTo(NameFollow);
905//      int lgth = AbsPos()-name_start;
906
907#if (not defined(OMISSION)) or ((OMISSION != END_TAG_MATCHING)  and (OMISSION != NAME_LOOKUP))
908        char * start_elem_name = model_info->symbol_table->Get_UTF8_name(nameID);
909        int lgth = model_info->symbol_table->Get_UTF8_lgth(nameID);
910        char * end_elem_name = &((char *) x8data)[buffer_rel_pos];
911       
912        BytePack byte_compare =  simd_eq_8(sisd_load_unaligned((BytePack *) end_elem_name),
913                                                           sisd_load_unaligned((BytePack *) start_elem_name));
914        if (lgth < 16) {
915                int expected_bits = ~(-1 << lgth);
916            if ((_mm_movemask_epi8(byte_compare) & expected_bits) != expected_bits) {
917                        WF_Error(wfErr_GIMatch);
918            }
919        }
920        else {
921            /* Must compare with bytes beyond the first 16.  Set up to
922               compare 16 bytes at a time, with the first additional compare
923               overlapping with the first byte_compare. */
924            int pos = (lgth - 1) % PACKSIZE + 1;
925            byte_compare =  simd_or(byte_compare, simd_eq_8(sisd_load_unaligned((BytePack *) &end_elem_name[pos]),
926                                                                                        sisd_load_unaligned((BytePack *) &start_elem_name[pos])));
927            pos += 16;
928            while (pos < lgth) {
929                if (_mm_movemask_epi8(byte_compare) != 0xFFFF) {
930                        WF_Error(wfErr_GIMatch);
931                }
932                byte_compare =  simd_eq_8(sisd_load_unaligned((BytePack *) &end_elem_name[pos]),
933                                                  sisd_load_unaligned((BytePack *) &start_elem_name[pos]));
934                pos += 16;
935            }
936            if (_mm_movemask_epi8(byte_compare) != 0xFFFF) {
937                        WF_Error(wfErr_GIMatch);
938            }
939        }
940        Advance(lgth);
941
942#endif
943#if defined(OMISSION) and ((OMISSION == END_TAG_MATCHING) or (OMISSION == NAME_LOOKUP))
944        ScanTo(NameFollow);
945#endif
946//      for(int i=0; i<lgth; i++) {
947//              if (start_elem_name[i] != end_elem_name[i])
948//                      WF_Error(wfErr_GIMatch);
949//      }
950//      if (start_elem_name[lgth] != '\0') WF_Error(wfErr_GIMatch);
951
952        if (AtChar<ASCII,'>'>(cur())) {
953                Advance(1);
954                EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
955        }
956    else {
957                ScanTo(NonWS);
958                if (AtChar<ASCII,'>'>(cur())) {
959                        Advance(1);
960                        EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
961                }
962                else Syntax_Error(NT_ETag);
963    }
964}
965/* Parse a valid start or empty element tag. */
966template <class B>
967inline int ParsingEngine<B>::Parse_WF_StartTag (bool& is_emptyStartTag){
968        int att_name_start;
969        int att_val_start;
970        int att_name_end, att_val_end;
971        unsigned char quoteCh;
972        Advance(1);
973       
974        #if (not defined(OMISSION)) or (OMISSION != NAME_LOOKUP)
975        int nameID = Parse_Name(); 
976        #endif
977        #if (defined(OMISSION)) and (OMISSION == NAME_LOOKUP)
978        ScanTo(NameFollow);
979        int nameID = 0;
980        #endif
981        ElementName_action(GetCodeUnitPtr(text_or_markup_start+1), LengthFrom(text_or_markup_start+1));
982        /* The following test optimizes the most common case of a
983        start tag with no attributes.  */
984        if (AtChar<B::Base,'>'>(cur())) {
985                Advance(1);
986                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
987        }
988        else {
989                ScanTo(NonWS);
990                if (AtChar<B::Base,'>'>(cur())) {
991                        Advance(1);
992                        StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
993                }
994                else if (at_EmptyElementDelim<B::Base>(cur())) {
995                        Advance(2);
996                        is_emptyStartTag = true;
997                        EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
998                }
999                else do {
1000                        /* Must be an attribute-value pair or error. */
1001                        att_name_start = AbsPos();
1002                        #if (not defined(OMISSION)) or (OMISSION != NAME_LOOKUP)
1003                        int att_nameID = Parse_Name(); 
1004                        #endif
1005                        #if (defined(OMISSION)) and (OMISSION == NAME_LOOKUP)
1006                        ScanTo(NameFollow);
1007                        int att_nameID = 0;
1008                        #endif
1009            att_name_end = AbsPos();
1010                #if (not defined(OMISSION)) or ((OMISSION != ATTRIBUTE_UNIQUENESS) and (OMISSION != NAME_LOOKUP))
1011                        int attID = model_info->getOrInsertGlobalAttName(att_nameID);
1012                        if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
1013                        else {
1014                                if (LastAttOccurrence[attID] > text_or_markup_start) {
1015                                        WF_Error(wfErr_uniqattspec); /* Duplicate attribute. */
1016                                        break;
1017                                }                       
1018                        }
1019                        LastAttOccurrence[attID] = att_name_start;
1020                 #endif
1021                        /* The following optimized tests handle the frequently occurring
1022                        case that there are no blanks on either side of the equals sign.
1023                        In many cases, the very first test handles 100% of actual
1024                        attribute-value pairs encountered. */
1025                        if (at_EqualsQuote<B::Base>(cur())) Advance(1); 
1026                        else {
1027                                ScanTo(NonWS);
1028                                if (!AtChar<B::Base,'='>(cur())) {
1029                                        Syntax_Error(NT_STag); 
1030                                        break;
1031                                }
1032                                Advance(1);
1033                                ScanTo(NonWS);
1034                                if (!AtQuote<B::Base>(cur())) {
1035                                        Syntax_Error(NT_STag); 
1036                                        break;
1037                                }
1038                        }
1039                        att_val_start = AbsPos()+1;
1040                        Parse_AttValue();
1041                        att_val_end = AbsPos()-1;
1042                        if (at_xmlns<B::Base>(cur()+att_name_start-AbsPos())) {
1043                                Namespace_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
1044                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
1045                        }
1046                        else {
1047                                AttributeValue_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
1048                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
1049                        }
1050                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
1051                        if (AtChar<B::Base,'>'>(cur())) {
1052                                Advance(1);
1053                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1054                                break;
1055                        }
1056                        else if (at_EmptyElementDelim<B::Base>(cur())) {
1057                                Advance(2);
1058                                is_emptyStartTag = true;       
1059                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1060                                break;
1061                        }
1062                        ScanTo(NonWS);
1063                        if (AtChar<B::Base,'>'>(cur())) {
1064                                Advance(1);
1065                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1066                                break;
1067                        }
1068                        else if (at_EmptyElementDelim<B::Base>(cur())) {
1069                                Advance(2);
1070                                is_emptyStartTag = true;
1071                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1072                                break;
1073                        }
1074                        else if (AbsPos() == att_val_end + 1) { 
1075                                /* No WS following att value */
1076                                Syntax_Error(NT_STag);
1077                                break;
1078                        }
1079                } while (1);
1080        }
1081        return nameID;
1082}
1083
1084
1085
1086template <class B>
1087inline void ParsingEngine<B>::Parse_WF_Element() {
1088        bool is_emptyStartTag = false;
1089        int nameID = Parse_WF_StartTag(is_emptyStartTag);
1090#ifdef DEBUG
1091        printf("Parse_Element: nameID = %d, is_emptyStartTag=%i\n",nameID, is_emptyStartTag);
1092#endif
1093        if (!is_emptyStartTag) {
1094                Parse_WF_Content();
1095                Parse_WF_EndTag(nameID);
1096        }
1097}
1098
1099
1100template <class B>
1101inline void ParsingEngine<B>::Parse_WF_Content() {
1102        do {
1103                text_or_markup_start = AbsPos();
1104                ScanToMarkupStart(); /* '<', '&', or ']' for ']]>' test */
1105                if (at_ElementTag_Start<B::Base>(cur())) {
1106                        text_if_nonnull_action();
1107                        Parse_WF_Element();
1108                }
1109                else if (at_EndTag_Start<B::Base>(cur())) {
1110                        text_if_nonnull_action();
1111                        return;
1112                }
1113                else if (at_Comment_Start<B::Base>(cur())) {
1114                        text_if_nonnull_action();
1115                        Parse_Comment();
1116                }
1117                else if (at_CharRef_Start<B::Base>(cur())) {
1118                        text_if_nonnull_action();
1119                        Parse_CharRef();
1120                }
1121                else if (AtChar<B::Base,'&'>(cur())) {
1122                        text_if_nonnull_action();
1123                        Parse_EntityRef();
1124                }
1125                else if (at_CDATA_Start<B::Base>(cur())) {
1126                        text_if_nonnull_action();
1127                        Parse_CDATA();
1128                }
1129                else if (at_PI_Start<B::Base>(cur())) {
1130                        text_if_nonnull_action();
1131                        Parse_PI();
1132                }
1133                else if (at_CDATA_End<B::Base>(cur())) {
1134                        text_if_nonnull_action();
1135                        Advance(3);
1136                        Syntax_Error(NT_CharData);
1137                }
1138                else if (at_EOF()) {
1139                        text_if_nonnull_action();
1140                        return;
1141                }
1142                else if (AtChar<B::Base,'<'>(cur())) {
1143                        Syntax_Error(NT_markupdecl);
1144                }
1145                else {
1146                        Advance(1);
1147                        continue;
1148                }
1149        } while (1);
1150}
1151
1152
1153
1154template <class B>
1155inline void ParsingEngine<B>::ParseContent() {
1156        DocumentStart_action(); 
1157        bool is_emptyStartTag = false;
1158        do {
1159                text_or_markup_start = AbsPos();
1160                ScanToMarkupStart(); /* '<', '&', or ']' for ']]>' test */
1161/*              if (AtChar<B::Base,'<'>(cur())) {
1162                        text_if_nonnull_action();
1163                        Parse_Markup<B>();
1164                }*/
1165                if (at_ElementTag_Start<B::Base>(cur())) {
1166                        text_if_nonnull_action();
1167                        Parse_StartTag();
1168                }
1169                else if (at_EndTag_Start<B::Base>(cur())) {
1170                        text_if_nonnull_action();
1171                        Parse_EndTag();
1172                }
1173                else if (at_Comment_Start<B::Base>(cur())) {
1174                        text_if_nonnull_action();
1175                        Parse_Comment();
1176                }
1177                else if (at_CharRef_Start<B::Base>(cur())) {
1178                        text_if_nonnull_action();
1179                        Parse_CharRef();
1180                }
1181                else if (AtChar<B::Base,'&'>(cur())) {
1182                        text_if_nonnull_action();
1183                        Parse_EntityRef();
1184                }
1185                else if (at_CDATA_Start<B::Base>(cur())) {
1186                        text_if_nonnull_action();
1187                        Parse_CDATA();
1188                }
1189                else if (at_PI_Start<B::Base>(cur())) {
1190                        text_if_nonnull_action();
1191                        Parse_PI();
1192                }
1193                else if (at_CDATA_End<B::Base>(cur())) {
1194                        text_if_nonnull_action();
1195                        Advance(3);
1196                        Syntax_Error(NT_CharData);
1197                }
1198                else if (at_EOF()) {
1199                        text_if_nonnull_action();
1200                        break;
1201                }
1202                else if (AtChar<B::Base,'<'>(cur())) {
1203                        Syntax_Error(NT_markupdecl);
1204                }
1205                else {
1206                        Advance(1);
1207                        continue;
1208                }
1209        } while (1);
1210        DocumentEnd_action();   
1211}
1212
1213
1214template <class B>
1215inline void ParsingEngine<B>::Parse_DocType (){
1216
1217        int old_abspos, start_pos;
1218        ScanTo(NonWS);
1219        start_pos = AbsPos();
1220       
1221        if (at_DOCTYPE_start<B::Base>(cur()))
1222        Advance(9);
1223        else{
1224//              printf("No Document definition!\n");
1225                return;
1226        }
1227        requireWS();
1228        int nameID = Parse_Name();
1229
1230        old_abspos = AbsPos(); 
1231    ScanTo(NonWS);
1232    if(at_SYSTEM<B::Base>(cur())||at_PUBLIC<B::Base>(cur())){
1233        model_info->has_external_DTD = true;
1234        if(old_abspos == AbsPos())
1235                Syntax_Error(NT_doctypedecl);
1236        Parse_ExternalID(model_info->external_DTD_systemLiteral, model_info->external_DTD_pubidLiteral);
1237        Parser_Interface * entity_parser;
1238        entity_parser = ParserFactory(model_info->external_DTD_systemLiteral, model_info);
1239                entity_parser->Parse_ExtSubsetDecl();
1240                entity_parser->~Parser_Interface();
1241    }
1242    else model_info->has_external_DTD = false;
1243    ScanTo(NonWS);     
1244
1245        if (AtChar<B::Base,'['>(cur())){
1246                Advance(1);
1247                Parse_IntSubset();
1248                if (AtChar<B::Base,']'>(cur()))
1249                        Advance(1);
1250                else
1251                Syntax_Error(NT_doctypedecl);
1252                ScanTo(NonWS);
1253        }
1254       
1255        if (AtChar<B::Base,'>'>(cur())){
1256                Advance(1); 
1257
1258                CRE_Seq * rslt = new CRE_Seq();
1259                rslt->subCMs.push_back(new CRE_Name(nameID));
1260                CM_RegExp * cre = new CM_RegExp();
1261                cre->content_re = rslt;         
1262               
1263                int id_count = cre->content_re->Set_IDs(0);
1264                cre->content_re->Set_First_Map();               
1265                symbol_set_t * transition_map = new symbol_set_t[id_count+1];
1266                cre->content_re->follow_map[0] = id_count+1;
1267               
1268                cre->content_re->Set_Follow_Map(transition_map);
1269                transition_map[0] = cre->content_re->first_map;
1270                if (cre->content_re->matches_empty)
1271                        transition_map[0][0]=id_count+1;
1272                       
1273                cre -> transition_map = transition_map;
1274               
1275                model_info->rootModel = cre;
1276               
1277                /* Check for notations that were used, but not defined by the end of the DTD. */
1278                #if (VALIDATION_MODE == ON)
1279                hash_map<int, int >::iterator j;
1280                for (j=model_info->GlobalNotationTable.begin(); j!=model_info->GlobalNotationTable.end(); j++) {
1281                        if (j->second == -1)
1282                                Validity_Error(vErr_notatn);
1283                }
1284                #endif
1285        }
1286        else
1287                Syntax_Error(NT_doctypedecl);   
1288}
1289
1290template <class B>
1291inline void ParsingEngine<B>::Parse_ExternalID (char *& systemLiteral, char *& pubidLiteral){
1292        int quot_start, lgth;
1293        if(at_SYSTEM<B::Base>(cur())){
1294                Advance(6);
1295                pubidLiteral = NULL;
1296                requireWS();
1297                if (!AtQuote<B::Base>(cur())) Syntax_Error(NT_ExternalID);
1298                quot_start = AbsPos()+1;
1299                Parse_SystemLiteral (); /*  SystemLiteral */
1300                lgth = AbsPos() - quot_start - 1;                       
1301                systemLiteral = copy_string(GetCodeUnitPtr(quot_start),lgth);
1302        }
1303        else if (at_PUBLIC<B::Base>(cur())){
1304                Advance(6);
1305                requireWS();
1306                if (!AtQuote<B::Base>(cur())) Syntax_Error(NT_ExternalID);
1307                quot_start = AbsPos()+1;
1308                Parse_PubidLiteral ();/*  PubidLiteral */
1309                lgth = AbsPos() - quot_start - 1;                       
1310                pubidLiteral = copy_string(GetCodeUnitPtr(quot_start),lgth);
1311                systemLiteral = NULL;
1312                if (AtChar<B::Base, '>'>(cur())) return;
1313                requireWS();
1314                if (AtQuote<B::Base>(cur())) {
1315                        quot_start = AbsPos()+1;       
1316                        Parse_SystemLiteral ();/*  SystemLiteral */
1317                        lgth = AbsPos() - quot_start - 1;                       
1318                        systemLiteral = copy_string(GetCodeUnitPtr(quot_start),lgth);
1319                }
1320        }
1321        else
1322                Syntax_Error(NT_ExternalID); 
1323}
1324
1325template <class B>
1326inline void ParsingEngine<B>::Parse_SystemLiteral (){
1327        unsigned char quoteCh;
1328        if(AtQuote<B::Base>(cur())){
1329                quoteCh = cur()[0];
1330                Advance(1);
1331        }       
1332        ScanTo(Quote);                 
1333        while (cur()[0] != quoteCh){
1334                if(at_EOF())
1335                        Syntax_Error(NT_SystemLiteral);
1336                Advance(1);
1337                ScanTo(Quote);
1338        }
1339        Advance(1);
1340}
1341
1342template <class B>
1343inline void ParsingEngine<B>::Parse_PubidLiteral (){
1344        unsigned char quoteCh;
1345        quoteCh = cur()[0];
1346        Advance(1);
1347        while (at_PubidChar<B::Base>(cur()) && (cur()[0] != quoteCh)) {
1348                Advance(1);
1349        }
1350        if (cur()[0] != quoteCh){
1351                Syntax_Error(NT_PubidLiteral);
1352        }
1353        Advance(1);
1354}
1355
1356template <class B>
1357inline void ParsingEngine<B>::Parse_IntSubset (){
1358       
1359        while(1){
1360                ScanTo(NonWS); 
1361                text_or_markup_start = AbsPos();
1362                if (AtChar<B::Base,'%'>(cur()))
1363                        Parse_PEReference();   
1364                else if (at_PI_Start<B::Base>(cur())) {
1365                        Parse_PI();
1366                }
1367                else if (at_Comment_Start<B::Base>(cur())) {
1368                        Parse_Comment();
1369                }
1370                else if (AtChar<B::Base,'<'>(cur())){
1371                        Advance(1);
1372                        if(AtChar<B::Base,'!'>(cur())){
1373                                Advance(1);
1374                                if (at_ELEMENT<B::Base>(cur()))
1375                                        Parse_Elementdecl();
1376                                else if (at_ATTLIST<B::Base>(cur()))
1377                                        Parse_AttlistDecl();
1378                                else if (at_ENTITY<B::Base>(cur()))
1379                                        Parse_Entitydecl();
1380                                else if (at_NOTATION<B::Base>(cur()))
1381                                        Parse_Notationdecl();
1382                                else {
1383                                        Syntax_Error(NT_markupdecl);           
1384                                }                                                               
1385                        }
1386                        else
1387                                Syntax_Error(NT_markupdecl); 
1388                }
1389                else if (AtChar<B::Base,']'>(cur())){
1390                        break;
1391                }
1392                else
1393                        Syntax_Error(NT_intSubset); 
1394        }
1395}
1396
1397
1398template <class B>
1399inline void ParsingEngine<B>::Parse_PEReference (){
1400
1401        Advance(1); /* Skip "%". */
1402        int nameID = Parse_Name(); 
1403        if (AtChar<B::Base,';'>(cur())) {
1404                Advance(1);
1405                PEReference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1406                PEntity_info * this_info;
1407                Parser_Interface * entity_parser;
1408                int entityID = model_info->GlobalPEntityTable[nameID]; 
1409                if (entityID == 0)
1410                        WF_Error(wfErr_wf_entdeclared);
1411                else{
1412                        this_info = model_info->PEntityData[entityID-1];
1413                        if (this_info->is_external){
1414                               
1415//                      if (entity_Info->standalone != Standalone_no)
1416//                              WF_Error(wfErr_NoExternalRefs);
1417//                      else {
1418                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
1419                                        entity_parser->Parse_WF_Content();
1420                                        if(!entity_parser->at_EOF())
1421                                                Syntax_Error(NT_content);
1422                                        entity_parser->~Parser_Interface();
1423//                      }
1424                        }
1425                        else {
1426                        }
1427                }
1428        }
1429        else
1430                Syntax_Error(NT_PEReference);
1431}
1432
1433
1434template <class B>
1435inline void ParsingEngine<B>::Parse_Elementdecl (){
1436
1437        Advance(7); /* Skip "<!ELEMENT". */
1438
1439    requireWS();
1440        int nameID = Parse_Name();
1441        int elemID = model_info->getOrInsertGlobalElement(nameID);
1442
1443        requireWS();
1444        ContentModel * cm;
1445        /* Start parsing "contentspec"*/
1446        if (at_EMPTY<B::Base>(cur())) {
1447        Advance(5);
1448        cm = new CM_Empty();
1449        model_info->ContentModelData[nameID] = cm;
1450        }
1451    else if (at_ANY<B::Base>(cur())) {
1452        Advance(3);
1453        cm = new CM_Any();
1454        model_info->ContentModelData[nameID] = cm;
1455    }
1456    else {
1457        if (AtChar<B::Base,'('>(cur()))
1458                        Advance(1);
1459                ScanTo(NonWS);
1460                if (at_PCDATA<B::Base>(cur())){
1461                        cm = Parse_RemainingMixed();
1462                        model_info->ContentModelData[nameID] = cm;
1463                }
1464                else{
1465
1466                        CM_RegExp * cre = new CM_RegExp;
1467                        cre->content_re = Parse_RemainingChildren();
1468
1469                        int id_count = cre->content_re->Set_IDs(0);
1470                        cre->content_re->Set_First_Map();       
1471                        symbol_set_t * transition_map = new symbol_set_t[id_count+1];
1472                        cre->content_re->follow_map[0] = id_count+1;
1473                       
1474                        cre->content_re->Set_Follow_Map(transition_map);
1475                        transition_map[0] = cre->content_re->first_map;
1476                       
1477                        if (cre->content_re->matches_empty)
1478                                transition_map[0][0]=id_count+1;
1479                               
1480                        cre -> transition_map = transition_map;
1481                       
1482                        model_info->ContentModelData[nameID] = cre;
1483                        cm = cre;
1484                }                       
1485    }
1486    ScanTo(NonWS);   
1487
1488        if (AtChar<B::Base,'>'>(cur())) {
1489                Advance(1);
1490        }
1491        else
1492                Syntax_Error(NT_elementdecl);
1493}
1494template <class B>
1495inline ContentModel * ParsingEngine<B>::Parse_RemainingMixed (){
1496        CM_Mixed * r = new CM_Mixed();
1497        Advance(7);  /* Skip "#PCDATA". */
1498   
1499    if (AtChar<B::Base,')'>(cur())){
1500        if (AtChar<B::Base,'*'>(cur())) {
1501                Advance(2);
1502                }
1503                else {
1504                        Advance(1);
1505                }
1506    }
1507    else{
1508        ScanTo(NonWS);
1509        int k = 0;
1510        while (AtChar<B::Base,'|'>(cur())){
1511                        Advance(1);
1512                        ScanTo(NonWS);
1513                        int nameID = Parse_Name();
1514                        r->elements[nameID] = ++k;
1515                        ScanTo(NonWS);
1516                }
1517                if (at_Para_star<B::Base>(cur())) Advance(2);
1518                else {
1519                        Syntax_Error(NT_Mixed);
1520                        exit(-1);
1521        }
1522    }
1523    return r;
1524}
1525
1526
1527template <class B>
1528inline Content_RE * ParsingEngine<B>::Parse_RemainingChildren (){
1529        Content_RE * c1 = Parse_Cp();
1530        Content_RE * r = c1;
1531        ScanTo(NonWS);
1532        if(AtChar<B::Base,'|'>(cur())){
1533                CRE_Choice * rslt = new CRE_Choice;
1534                rslt->subCMs.push_back(c1);
1535                Advance(1);
1536                ScanTo(NonWS);
1537                rslt->subCMs.push_back(Parse_Cp());
1538                ScanTo(NonWS);
1539                while(!AtChar<B::Base,')'>(cur())){
1540                        if(AtChar<B::Base,'|'>(cur()))
1541                                Advance(1);
1542                        else
1543                                Syntax_Error(NT_children);
1544                        ScanTo(NonWS);
1545                        rslt->subCMs.push_back(Parse_Cp());
1546                        ScanTo(NonWS);
1547                }
1548                Advance(1);
1549                rslt->Compile();
1550                r = rslt;
1551        }
1552        else if(AtChar<B::Base,','>(cur())){
1553                CRE_Seq * rslt = new CRE_Seq;
1554                rslt->subCMs.push_back(c1);
1555                Advance(1);
1556                ScanTo(NonWS);
1557                rslt->subCMs.push_back(Parse_Cp());
1558                ScanTo(NonWS);
1559                while(!AtChar<B::Base,')'>(cur())){
1560                        if(AtChar<B::Base,','>(cur()))
1561                                Advance(1);
1562                        else
1563                                Syntax_Error(NT_children);
1564                        ScanTo(NonWS);
1565                        rslt->subCMs.push_back(Parse_Cp());
1566                        ScanTo(NonWS);
1567                }
1568                Advance(1);
1569                rslt->Compile();
1570                r = rslt;
1571        }       
1572        else if(AtChar<B::Base,')'>(cur())){
1573                Advance(1);
1574        }
1575        else
1576                Syntax_Error(NT_children);
1577               
1578        if (AtChar<B::Base,'?'>(cur())) {
1579                Advance(1);
1580                r = new CRE_Opt(r);
1581        }
1582        else if (AtChar<B::Base,'*'>(cur())) {
1583                Advance(1);
1584                r = new CRE_Star(r);
1585        }
1586        else if (AtChar<B::Base,'+'>(cur())) {
1587                Advance(1);
1588                r = new CRE_Plus(r);
1589        }
1590
1591        return r;
1592}
1593
1594template <class B>
1595inline Content_RE * ParsingEngine<B>::Parse_Cp (){
1596        if (AtChar<B::Base,'('>(cur())){
1597                Advance(1);
1598                ScanTo(NonWS);
1599                Parse_RemainingChildren();
1600        }
1601        else{
1602                int nameID = Parse_Name();
1603                CRE_Name * r = new CRE_Name(nameID);
1604
1605                if (AtChar<B::Base,'?'>(cur())) {
1606                        Advance(1);
1607                        return new CRE_Opt(r);
1608                }
1609                else if (AtChar<B::Base,'*'>(cur())) {
1610                        Advance(1);
1611                        return new CRE_Star(r);
1612                }
1613                else if (AtChar<B::Base,'+'>(cur())) {
1614                        Advance(1);
1615                        return new CRE_Plus(r);
1616                }
1617                else return r;
1618        }
1619}
1620
1621template <class B>
1622inline void ParsingEngine<B>::Parse_AttlistDecl (){
1623       
1624        int old_abspos;
1625       
1626        int name_start;
1627        int lgth;
1628       
1629        int elemID;
1630        int attID;
1631       
1632        Advance(7); /* Skip "ATTLIST. */
1633        requireWS();
1634       
1635        int nameID = Parse_Name();
1636        elemID = model_info->getOrInsertGlobalElement(nameID);
1637       
1638        old_abspos = AbsPos();
1639        ScanTo(NonWS);
1640        while(!AtChar<B::Base,'>'>(cur())) {
1641                if(old_abspos == AbsPos())
1642                Syntax_Error(NT_AttlistDecl);
1643               
1644                int att_nameID = Parse_Name();
1645               
1646                attID = model_info->getOrInsertGlobalAttName(att_nameID);
1647                if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
1648        ATT_info * this_info = new ATT_info;
1649        this_info->globalATT_id = attID;
1650        requireWS();
1651        if (at_CDATA<B::Base>(cur())){
1652                Advance(5);
1653                this_info->attType = CDATA_att;
1654        }
1655        else if(at_ID<B::Base>(cur())){
1656                Advance(2);
1657                this_info->attType = ID_att;
1658        }
1659        /* Make sure to check IDREFS before IDREF*/
1660        else if(at_IDREFS<B::Base>(cur())){
1661                Advance(6);
1662                this_info->attType = IDREFS_att;
1663        }
1664        else if(at_IDREF<B::Base>(cur())){
1665                Advance(5);
1666                this_info->attType = IDREF_att;
1667        }
1668        else if(at_ENTITY<B::Base>(cur())){
1669                Advance(6);
1670                this_info->attType = ENTITY_att;
1671        }
1672        else if(at_ENTITIES<B::Base>(cur())){
1673                Advance(8);
1674                this_info->attType = ENTITIES_att;
1675        }
1676        /* Make sure to check NMTOKENS before NMTOKEN*/
1677        else if(at_NMTOKENS<B::Base>(cur())){
1678                Advance(8);
1679                this_info->attType = NMTOKENS_att;
1680        }
1681        else if(at_NMTOKEN<B::Base>(cur())){
1682                Advance(7);
1683                this_info->attType = NMTOKEN_att;
1684        }
1685        else if(at_NOTATION<B::Base>(cur())){ /* NotationType = 'NOTATION' S Enumeration
1686                                                                         when Nmtoken = Name */
1687                Advance(8);
1688                        requireWS();
1689                Parse_Notation(this_info);
1690                this_info->attType = NOTATION_att;
1691        }
1692        else if(AtChar<B::Base,'('>(cur())){
1693                Parse_Enumeration(this_info);
1694                this_info->attType = enumeration_att;
1695        }
1696        else
1697                Syntax_Error(NT_AttlistDecl);
1698        requireWS();
1699        Parse_DefaultDecl(this_info);
1700
1701                ScanTo(NonWS);
1702                model_info->ElementAttributeData[elemID].push_back(this_info);
1703        }
1704
1705        Advance(1);
1706}
1707
1708template <class B>
1709inline void ParsingEngine<B>::Parse_Notation (ATT_info * this_info){
1710
1711        if(AtChar<B::Base,'('>(cur()))
1712                Advance(1);
1713        else
1714                Syntax_Error(NT_NotationType);
1715        ScanTo(NonWS);
1716       
1717    int notn_nameID = Parse_Name();
1718
1719        /*Notation name is not in the global table!*/
1720        if(model_info->GlobalNotationTable[notn_nameID]==0)
1721                model_info->GlobalNotationTable[notn_nameID] = -1;
1722       
1723        ScanTo(NonWS);
1724        while(AtChar<B::Base,'|'>(cur())){
1725                Advance(1);
1726                ScanTo(NonWS); 
1727                notn_nameID = Parse_Name();
1728                       
1729                if(model_info->GlobalNotationTable[notn_nameID]==0)
1730//                      Validity_Error(vErr_notatn);
1731                        model_info->GlobalNotationTable[notn_nameID] = -1;
1732                       
1733                ScanTo(NonWS);
1734        }
1735        if (AtChar<B::Base,')'>(cur())) 
1736                Advance(1);
1737        else
1738                Syntax_Error(NT_NotationType);
1739}
1740
1741template <class B>
1742inline void ParsingEngine<B>::Parse_Enumeration (ATT_info * this_info){
1743
1744        int enumCount=0;
1745        if(AtChar<B::Base,'('>(cur()))
1746                Advance(1);
1747        else
1748                Syntax_Error(NT_Enumeration);
1749        ScanTo(NonWS);
1750       
1751        int nmtokenID = Parse_Nmtoken();
1752       
1753        this_info->enumValues[nmtokenID]=++(enumCount);
1754       
1755        ScanTo(NonWS);
1756        while(AtChar<B::Base,'|'>(cur())){
1757                Advance(1);
1758                ScanTo(NonWS); 
1759                int nmtokenID = Parse_Nmtoken();
1760       
1761                int enumID = this_info->enumValues[nmtokenID];
1762                if(enumID==0){ 
1763                        this_info->enumValues[nmtokenID]=++(enumCount);
1764                        enumID = enumCount;
1765                }
1766                else if(!StrictWellFormedness){
1767                        Validity_Error(vErr_NoDuplicateTokens);
1768                }
1769                ScanTo(NonWS);
1770        }
1771        if (AtChar<B::Base,')'>(cur())) 
1772                Advance(1);
1773        else
1774                Syntax_Error(NT_Enumeration);
1775}
1776
1777template <class B>
1778inline void ParsingEngine<B>::Parse_DefaultDecl (ATT_info * this_info){
1779        if(at_REQUIRED<B::Base>(cur())){
1780                Advance(9);
1781                this_info->defaultKind = REQUIRED_att;
1782        }
1783        else if(at_IMPLIED<B::Base>(cur())){
1784                Advance(8);
1785                this_info->defaultKind = IMPLIED_att;
1786        }
1787        else {
1788                if(at_FIXED<B::Base>(cur())){
1789                        Advance(6);
1790                        requireWS();
1791                        this_info->defaultKind = FIXED_att;
1792                }
1793                else this_info->defaultKind = DEFAULT_att;
1794                if(AtQuote<B::Base>(cur())){
1795                        int quot_start = AbsPos()+1;
1796                        Parse_AttValue();
1797                        /* need to normalize */
1798                        this_info->defaultValueLgth = AbsPos() - quot_start - 1;
1799                       
1800                        this_info->defaultValue = new unsigned char[this_info->defaultValueLgth+1];
1801                        memcpy(this_info->defaultValue, GetCodeUnitPtr(quot_start),this_info->defaultValueLgth); 
1802                        this_info->defaultValue[this_info->defaultValueLgth] = '\0';
1803                        }
1804                else
1805                        Syntax_Error(NT_DefaultDecl);
1806        }
1807}
1808
1809template <class B>
1810inline void ParsingEngine<B>::Parse_Entitydecl (){
1811       
1812        int name_start;
1813        int quot_start;
1814        int lgth;
1815        int old_abspos;
1816        char * s;
1817       
1818        Advance(6); /* Skip "ENTITY. */
1819        requireWS();
1820       
1821        if (AtChar<B::Base,'%'>(cur())){
1822                Advance(1);
1823                requireWS();
1824               
1825                int nameID = Parse_Name();
1826                PEntity_info * this_info = new PEntity_info;
1827                int entityID = model_info->GlobalPEntityTable[nameID];
1828                if(entityID==0){       
1829                        model_info->GlobalPEntityTable[nameID]=++(model_info->globalPEntityCount);
1830                        entityID = model_info->globalPEntityCount;
1831                        this_info->globalPEntity_id = entityID;
1832                }
1833                else
1834                        printf("Warning: Entity definition already exist!\n");
1835       
1836                requireWS();
1837                if(AtQuote<B::Base>(cur())){
1838                Parse_PEntityValue(this_info);
1839                this_info->is_external = false;
1840        }
1841        else {
1842                Parse_ExternalID(this_info->systemLiteral, this_info->pubidLiteral);
1843                this_info->is_external = true;
1844                if (this_info->systemLiteral == NULL) Syntax_Error(NT_EntityDecl);
1845        }
1846        model_info->PEntityData.push_back(this_info);
1847        }
1848        else{
1849                int nameID = Parse_Name();
1850       
1851                GEntity_info * this_info = new GEntity_info();
1852                int entityID = model_info->GlobalGEntityTable[nameID];
1853                if(entityID==0){       
1854                        model_info->GlobalGEntityTable[nameID]=++(model_info->globalGEntityCount);
1855                        entityID = model_info->globalGEntityCount;
1856                        this_info->globalGEntity_id = entityID;
1857                }
1858                else
1859                        printf("Warning: Entity definition already exists!\n");
1860                       
1861                requireWS();
1862               
1863                if(AtQuote<B::Base>(cur())){
1864                Parse_GEntityValue(this_info);                 
1865                this_info->is_external = false;
1866        }
1867        else {
1868                Parse_ExternalID(this_info->systemLiteral, this_info->pubidLiteral);
1869                this_info->is_external = true;
1870                if (this_info->systemLiteral == NULL) Syntax_Error(NT_EntityDecl);
1871                        old_abspos = AbsPos();
1872                        ScanTo(NonWS);
1873                if(at_NDATA<B::Base>(cur())){
1874                        if(old_abspos == AbsPos())
1875                                Syntax_Error(NT_EntityDecl);
1876                        else
1877                                Advance(5);
1878                        requireWS();
1879                        name_start = AbsPos();
1880                        int nameID = Parse_Name();
1881                        lgth = AbsPos() - name_start;
1882                                this_info->NDataName = copy_string(GetCodeUnitPtr(name_start),lgth);
1883                }
1884                }
1885        model_info->GEntityData.push_back(this_info);
1886        }
1887        ScanTo(NonWS);
1888        if (AtChar<B::Base,'>'>(cur())){
1889                Advance(1);
1890        }
1891        else
1892                Syntax_Error(NT_EntityDecl);
1893}
1894
1895template <class B>
1896inline void ParsingEngine<B>::Parse_Notationdecl (){
1897
1898        int old_abspos;
1899        Advance(8); /* Skip "NOTATION. */
1900        requireWS();
1901       
1902        int nameID = Parse_Name();
1903
1904        int notationID = model_info->GlobalNotationTable[nameID];
1905        /* notationID == -1: used but not yet defined; == 0: new, > 0 prev. defined */
1906        if(notationID <= 0){   
1907                model_info->GlobalNotationTable[nameID]=++(model_info->globalNotationCount);
1908                notationID = model_info->globalNotationCount;
1909        }
1910        else /*Duplicate notation name!*/
1911                Validity_Error(vErr_NoDuplicateTokens);
1912        Notation_info * this_info = new Notation_info;
1913        ScanTo(NonWS);         
1914    Parse_ExternalID(this_info->systemLiteral, this_info->pubidLiteral);
1915        ScanTo(NonWS);
1916        if (AtChar<B::Base,'>'>(cur())) {
1917                Advance(1);
1918        }
1919        else
1920                Syntax_Error(NT_NotationDecl);
1921}
1922
1923template <class B>
1924inline void ParsingEngine<B>::requireWS(){
1925       
1926    int old_abspos = AbsPos(); 
1927    ScanTo(NonWS);
1928    if(old_abspos == AbsPos())
1929        Syntax_Error(NT_S);
1930}
1931
1932template <class B>
1933inline void ParsingEngine<B>::Parse_AttValue(){
1934       
1935        int     quoteCh = cur()[0];
1936        Advance(1); /* Skip " or ' */
1937
1938        ScanTo(Quote);                 
1939        while (cur()[0] != quoteCh){
1940                if (at_CharRef_Start<B::Base>(cur())){
1941                        Parse_CharRef();
1942                        ScanTo(Quote);
1943                }
1944                else if (AtChar<B::Base,'&'>(cur())){
1945                        Parse_EntityRef();
1946                        ScanTo(Quote);
1947                }
1948                else if (AtQuote<B::Base>(cur())) {
1949                        Advance(1);
1950                        ScanTo(Quote);
1951                }
1952                else /* if (AtChar<B::Base,'<'>(cur())) */
1953                        WF_Error(wfErr_CleanAttrVals);
1954        }
1955        Advance(1);
1956}
1957
1958template <class B>
1959inline void ParsingEngine<B>::Parse_GEntityValue(GEntity_info * this_info){
1960       
1961        int     quoteCh = cur()[0];
1962        Advance(1); /* Skip " or ' */
1963        this_info->is_simple = true;
1964        int quot_start = AbsPos();
1965        char * replText;
1966        ScanTo(Quote);         
1967        replText = copy_string(GetCodeUnitPtr(quot_start),AbsPos()-quot_start);
1968        while (cur()[0] != quoteCh){
1969                if (at_CharRef_Start<B::Base>(cur())){
1970                        strcat (replText,Replace_CharRef());
1971                        quot_start = AbsPos();
1972                        ScanTo(Quote);
1973                }
1974                else if (AtQuote<B::Base>(cur())) {
1975                        quot_start = AbsPos();
1976                        Advance(1);
1977                        ScanTo(Quote);
1978                }
1979                else if (at_EOF()) {
1980                        Syntax_Error(NT_EntityValue);
1981                }
1982                else { /* '<' or '&' found */
1983                        quot_start = AbsPos();
1984                        Advance(1);
1985                        ScanTo(Quote);
1986                        this_info->is_simple = false;                   
1987                }
1988                replText = cat_string (replText,(char *)GetCodeUnitPtr(quot_start), strlen(replText), AbsPos()-quot_start);
1989        }
1990        this_info->ReplacementText = replText;
1991        Advance(1);
1992}
1993
1994template <class B>
1995inline char * ParsingEngine<B>::Replace_EntityRef(bool& is_simple){
1996        Advance(1);
1997        int nameID = Parse_Name(); 
1998        if (AtChar<B::Base,';'>(cur()))
1999                Advance(1);
2000        else
2001                Syntax_Error(NT_EntityValue);
2002        int entityID = model_info->GlobalGEntityTable[nameID]; 
2003        if (entityID == 0)
2004                WF_Error(wfErr_wf_entdeclared);
2005        else{
2006                if (model_info->GEntityData[entityID-1]->is_simple == false)
2007                        is_simple = false;
2008                return model_info->GEntityData[entityID-1]->ReplacementText;
2009        }
2010       
2011}
2012
2013template <class B>
2014inline void ParsingEngine<B>::Parse_PEntityValue(PEntity_info * this_info){
2015        fprintf(stderr,"parsing of parameter entity value has not been completed yet.\n");
2016        exit(-1);
2017}
2018
2019template <class B>
2020inline char * ParsingEngine<B>::Replace_CharRef(){
2021        Advance(2);
2022        fprintf(stderr,"Replacement of Character Reference has not been completed yet.\n");
2023        exit(-1);
2024}
2025
2026template <class B>
2027inline void ParsingEngine<B>::Parse_Prolog(){
2028        ScanTo(NonWS);
2029        int old_pos = AbsPos();
2030        while (!at_DOCTYPE_start<B::Base>(cur())) {
2031                if (at_Comment_Start<B::Base>(cur())) 
2032                        Parse_Comment();
2033                else if (at_PI_Start<B::Base>(cur()))
2034                                Parse_PI();
2035                else{
2036                        Prolog_action(GetCodeUnitPtr(old_pos), LengthFrom(old_pos));
2037                        return;
2038                }
2039                ScanTo(NonWS);
2040        }
2041        Parse_DocType();
2042        ScanTo(NonWS);
2043        while(at_Comment_Start<B::Base>(cur()) || at_PI_Start<B::Base>(cur()) ){
2044                if (at_Comment_Start<B::Base>(cur()))
2045                        Parse_Comment();
2046                else 
2047                        Parse_PI();
2048                ScanTo(NonWS);
2049        }
2050        Prolog_action(GetCodeUnitPtr(old_pos), LengthFrom(old_pos));
2051}
2052
2053template <class B>
2054inline void ParsingEngine<B>::Parse_ExtSubsetDecl() {
2055        ScanTo(NonWS);
2056        int start_pos=AbsPos();
2057        while(!at_EOF()){
2058                if(at_condSect_start<B::Base>(cur())){         
2059                        Advance(3);
2060                        ScanTo(NonWS);
2061                        if (at_INCLUDE<B::Base>(cur())){
2062                                Advance(7);
2063                                ScanTo(NonWS);
2064                                if(AtChar<B::Base,'['>(cur())){
2065                                        Advance(1);
2066                                        Parse_ExtSubsetDecl();
2067                                        if(at_CDATA_End<B::Base>(cur()))
2068                                                Advance(3);
2069                                        else Syntax_Error(NT_includeSect);
2070                                }
2071                                else Syntax_Error(NT_includeSect);
2072                        }
2073                        else if (at_IGNORE<B::Base>(cur())){
2074                                Advance(6);
2075                                ScanTo(NonWS);         
2076                                if(AtChar<B::Base,'['>(cur())){
2077                                        int section_depth=1;
2078                                        Advance(1);
2079                                        while(!at_EOF()){
2080                                                ScanToMarkupStart();
2081                                                if(at_condSect_start<B::Base>(cur())){
2082                                                        Advance(3);
2083                                                        section_depth++;
2084                                                }
2085                                                else if(at_CDATA_End<B::Base>(cur())){
2086                                                        Advance(3);
2087                                                        section_depth--;
2088                                                }
2089                                                else
2090                                                        Advance(1);
2091                                                if(section_depth==0) return;                                   
2092                                        }
2093                                        Syntax_Error(NT_ignoreSectContents);   
2094                                }
2095                                else Syntax_Error(NT_ignoreSect);
2096                        }
2097                        else Syntax_Error(NT_conditionalSect);
2098                }
2099                else if (AtChar<B::Base,'%'>(cur()))
2100                        Parse_PEReference();   
2101                else if (at_PI_Start<B::Base>(cur())) {
2102                        Parse_PI();
2103                }
2104                else if (at_Comment_Start<B::Base>(cur())) {
2105                        Parse_Comment();
2106                }
2107                else if (AtChar<B::Base,'<'>(cur())){
2108                        Advance(1);
2109
2110                        if(AtChar<B::Base,'!'>(cur())){
2111                                Advance(1);
2112                                if(at_ELEMENT<B::Base>(cur()))
2113                                        Parse_Elementdecl();
2114                                else if(at_ATTLIST<B::Base>(cur()))
2115                                        Parse_AttlistDecl();
2116                                else if(at_ENTITY<B::Base>(cur()))
2117                                        Parse_Entitydecl();
2118                                else if(at_NOTATION<B::Base>(cur()))
2119                                        Parse_Notationdecl();                                   
2120                                else{
2121                                        Syntax_Error(NT_markupdecl);   
2122                                }                                                               
2123                        }
2124                        else
2125                                Syntax_Error(NT_markupdecl); 
2126                }
2127                else
2128                        Syntax_Error(NT_extSubsetDecl); 
2129                ScanTo(NonWS);
2130        }
2131        ExtSubsetDecl_action(GetCodeUnitPtr(start_pos), LengthFrom(start_pos));
2132}
2133
2134/* Parse a valid start or empty element tag. */
2135template <class B>
2136inline int ParsingEngine<B>::Parse_ValidStartTag (bool& is_emptyStartTag){
2137        int att_name_start;
2138        int att_val_start;
2139        int att_name_end, att_val_end;
2140        unsigned char quoteCh;
2141        Advance(1);
2142
2143        int nameID = Parse_Name(); 
2144        int elemID = model_info->GlobalElementTable[nameID];
2145        if(elemID==0)
2146                        Validity_Error(vErr_elementvalid);
2147       
2148        ElementName_action(GetCodeUnitPtr(text_or_markup_start+1), LengthFrom(text_or_markup_start+1));
2149        /* The following test optimizes the most common case of a
2150        start tag with no attributes.  */
2151        if (AtChar<B::Base,'>'>(cur())) {
2152                Advance(1);
2153                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2154        }
2155        else {
2156                ScanTo(NonWS);
2157                if (AtChar<B::Base,'>'>(cur())) {
2158                        Advance(1);
2159                        StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2160                }
2161                else if (at_EmptyElementDelim<B::Base>(cur())) {
2162                        Advance(2);
2163                        is_emptyStartTag = true;
2164                        EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2165                }
2166                else do {
2167                        /* Must be an attribute-value pair or error. */
2168                        att_name_start = AbsPos();
2169                        int att_nameID = Parse_Name();
2170                        #if (not defined(OMISSION)) or (OMISSION != ATTRIBUTE_UNIQUENESS) 
2171                        int attID = model_info->getOrInsertGlobalAttName(att_nameID);
2172                        if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
2173                        else {
2174                                if (LastAttOccurrence[attID] > text_or_markup_start) {
2175                                        WF_Error(wfErr_uniqattspec); /* Duplicate attribute. */
2176                                        break;
2177                                }                       
2178                        }
2179                        LastAttOccurrence[attID] = att_name_start;
2180                        #endif
2181                        /* The following optimized tests handle the frequently occurring
2182                        case that there are no blanks on either side of the equals sign.
2183                        In many cases, the very first test handles 100% of actual
2184                        attribute-value pairs encountered. */
2185                        if (at_EqualsQuote<B::Base>(cur())) Advance(1); 
2186                        else {
2187                                ScanTo(NonWS);
2188                                if (!AtChar<B::Base,'='>(cur())) {
2189                                        Syntax_Error(NT_STag); 
2190                                        break;
2191                                }
2192                                Advance(1); 
2193                                ScanTo(NonWS);
2194                                if (!AtQuote<B::Base>(cur())) {
2195                                        Syntax_Error(NT_STag); 
2196                                        break;
2197                                }
2198                        }
2199                        att_val_start = AbsPos()+1;
2200                        Parse_AttValue();
2201                        att_val_end = AbsPos()-1;
2202                        if (at_xmlns<B::Base>(cur()+att_name_start-AbsPos())) {
2203                                Namespace_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
2204                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
2205                        }
2206                        else {
2207                                AttributeValue_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
2208                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
2209                        }
2210                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
2211                        if (AtChar<B::Base,'>'>(cur())) {
2212                                Advance(1);
2213                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2214                                break;
2215                        }
2216                        else if (at_EmptyElementDelim<B::Base>(cur())) {
2217                                Advance(2);
2218                                is_emptyStartTag = true;       
2219                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2220                                break;
2221                        }
2222                        ScanTo(NonWS);
2223                        if (AtChar<B::Base,'>'>(cur())) {
2224                                Advance(1);
2225                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2226                                break;
2227                        }
2228                        else if (at_EmptyElementDelim<B::Base>(cur())) {
2229                                Advance(2);
2230                                is_emptyStartTag = true;
2231                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2232                                break;
2233                        }
2234                        else if (AbsPos() == att_val_end + 1) { 
2235                                /* No WS following att value */
2236                                Syntax_Error(NT_STag);
2237                                break;
2238                        }
2239                } while (1);
2240        }
2241        return nameID;
2242}
2243
2244template <class B>
2245inline int ParsingEngine<B>::Parse_ValidElement() {
2246        bool is_emptyStartTag = false;
2247        int nameID = Parse_ValidStartTag(is_emptyStartTag);
2248#ifdef DEBUG
2249        printf("Parse_ValidElement: nameID = %d, name = %s, is_emptyStartTag=%i\n",nameID, model_info->symbol_table->Get_UTF8_name(nameID), is_emptyStartTag);
2250#endif
2251        ContentModel * cm = model_info->ContentModelData[nameID];
2252        switch (cm->cm_type) {
2253                case cm_Empty:
2254                        if (!is_emptyStartTag) {
2255                                if (at_EndTag_Start<B::Base>(cur())) {
2256                                        Parse_WF_EndTag(nameID);
2257                                }
2258                                else {
2259                                        Validity_Error(vErr_elementvalid);
2260                                }
2261                        }
2262                        break;
2263                case cm_Any:           
2264                        if (!is_emptyStartTag) {
2265                                Parse_AnyContent();
2266                                Parse_WF_EndTag(nameID);
2267                        }
2268                        break;
2269                case cm_Mixed:         
2270                        if (!is_emptyStartTag) {
2271                                Parse_MixedContent(((CM_Mixed *) cm)->elements);
2272                                Parse_WF_EndTag(nameID);
2273                        }
2274                        break;
2275                case cm_RegExp:
2276                        CM_RegExp * cre = (CM_RegExp *) cm;
2277                        int content_state = 0;
2278                        if (!is_emptyStartTag) {
2279                                Parse_ValidContent(cre, content_state);
2280                                #ifdef DEBUG
2281                                printf("Final content_state = %i, nameID = %i\n", content_state, nameID);
2282                                #endif
2283                                Parse_WF_EndTag(nameID);               
2284                        }
2285                        if (cre->transition_map[content_state][0]==0) {
2286                                Validity_Error(vErr_elementvalid);
2287                        }
2288        }
2289        return nameID;
2290}
2291
2292template <class B>
2293inline void ParsingEngine<B>::Parse_ValidContent(CM_RegExp * cre, int & cur_state) {
2294        do {
2295                ScanTo(NonWS);
2296                /* If non-null report WS  WS_action()? */
2297                text_or_markup_start = AbsPos();
2298                if (at_EndTag_Start<B::Base>(cur())) {
2299                        break;
2300                }
2301                else if (at_ElementTag_Start<B::Base>(cur())) {
2302                        int nameID = Parse_ValidElement();
2303#ifdef DEBUG
2304                        printf("Content model state transition %i", cur_state);
2305#endif
2306                        cur_state = cre->transition_map[cur_state][nameID];
2307#ifdef DEBUG
2308                        printf("-> %i\n", cur_state);
2309#endif
2310                }
2311                else if (at_Comment_Start<B::Base>(cur())) {
2312                        Parse_Comment();
2313                }
2314                else if (at_PI_Start<B::Base>(cur())) {
2315                        Parse_PI();
2316                }
2317                else if (AtChar<B::Base,'&'>(cur())) {
2318                        Parse_ValidEntityRef(cre, cur_state);
2319#ifdef DEBUG
2320                        printf("EntityRef complete, cur_state = %i\n", cur_state);
2321#endif
2322                       
2323                }
2324                else if (at_EOF()) {
2325                        break;
2326                }
2327                else if (AtChar<B::Base,'<'>(cur())) {
2328                        Syntax_Error(NT_markupdecl);
2329                }
2330                else {
2331                        Validity_Error(vErr_elementvalid);
2332                }
2333        } while(1);
2334}
2335
2336
2337template <class B>
2338inline void ParsingEngine<B>::Parse_AnyContent() {
2339        do {
2340                text_or_markup_start = AbsPos();
2341                ScanToMarkupStart(); /* '<', '&', or ']' for ']]>' test */
2342                if (at_ElementTag_Start<B::Base>(cur())) {
2343                        text_if_nonnull_action();
2344                        int nameID = Parse_ValidElement();
2345                }
2346                else if (at_EndTag_Start<B::Base>(cur())) {
2347                        text_if_nonnull_action();
2348                        return;
2349                }
2350                else if (at_Comment_Start<B::Base>(cur())) {
2351                        text_if_nonnull_action();
2352                        Parse_Comment();
2353                }
2354                else if (at_CharRef_Start<B::Base>(cur())) {
2355                        text_if_nonnull_action();
2356                        Parse_CharRef();
2357                }
2358                else if (AtChar<B::Base,'&'>(cur())) {
2359                        text_if_nonnull_action();
2360                        Parse_EntityRef_inAnyContent();
2361                }
2362                else if (at_CDATA_Start<B::Base>(cur())) {
2363                        text_if_nonnull_action();
2364                        Parse_CDATA();
2365                }
2366                else if (at_PI_Start<B::Base>(cur())) {
2367                        text_if_nonnull_action();
2368                        Parse_PI();
2369                }
2370                else if (at_CDATA_End<B::Base>(cur())) {
2371                        text_if_nonnull_action();
2372                        Advance(3);
2373                        Syntax_Error(NT_CharData);
2374                }
2375                else if (at_EOF()) {
2376                        text_if_nonnull_action();
2377                        return;
2378                }
2379                else if (AtChar<B::Base,'<'>(cur())) {
2380                        Syntax_Error(NT_markupdecl);
2381                }
2382                else {
2383                        Advance(1);
2384                        continue;
2385                }
2386        } while (1);
2387}
2388template <class B>
2389inline void ParsingEngine<B>::Parse_MixedContent(symbol_set_t elems) {
2390        do {
2391                text_or_markup_start = AbsPos();
2392                ScanToMarkupStart(); /* '<', '&', or ']' for ']]>' test */
2393/*              if (AtChar<B::Base,'<'>(cur())) {
2394                        text_if_nonnull_action();
2395                        Parse_Markup<B>();
2396                }*/
2397                if (at_ElementTag_Start<B::Base>(cur())) {
2398                        text_if_nonnull_action();
2399                        int nameID = Parse_ValidElement();
2400                        if (elems[nameID] == 0) {
2401                                Validity_Error(vErr_elementvalid);
2402                        }
2403                }
2404                else if (at_EndTag_Start<B::Base>(cur())) {
2405                        text_if_nonnull_action();
2406                        return;
2407                }
2408                else if (at_Comment_Start<B::Base>(cur())) {
2409                        text_if_nonnull_action();
2410                        Parse_Comment();
2411                }
2412                else if (at_CharRef_Start<B::Base>(cur())) {
2413                        text_if_nonnull_action();
2414                        Parse_CharRef();
2415                }
2416                else if (AtChar<B::Base,'&'>(cur())) {
2417                        text_if_nonnull_action();
2418                        Parse_EntityRef_inMixed(elems);
2419                }
2420                else if (at_CDATA_Start<B::Base>(cur())) {
2421                        text_if_nonnull_action();
2422                        Parse_CDATA();
2423                }
2424                else if (at_PI_Start<B::Base>(cur())) {
2425                        text_if_nonnull_action();
2426                        Parse_PI();
2427                }
2428                else if (at_CDATA_End<B::Base>(cur())) {
2429                        text_if_nonnull_action();
2430                        Advance(3);
2431                        Syntax_Error(NT_CharData);
2432                }
2433                else if (at_EOF()) {
2434                        text_if_nonnull_action();
2435                        return;
2436                }
2437                else if (AtChar<B::Base,'<'>(cur())) {
2438                        Syntax_Error(NT_markupdecl);
2439                }
2440                else {
2441                        Advance(1);
2442                        continue;
2443                }
2444        } while (1);
2445}
2446
2447
2448template <class B>
2449inline int ParsingEngine<B>::Parse_Name() {
2450        int name_pos = AbsPos();
2451        ScanTo(NameFollow);
2452        int lgth = AbsPos()-name_pos;
2453        int nameID = model_info->symbol_table->ASCII_Lookup_or_Insert_Name(&((char *) x8data)[buffer_rel_pos-lgth], lgth);
2454        if (nameID != 0) return nameID;
2455        else {
2456                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2457                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2458                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2459                return model_info->symbol_table->LookupOrInsertReserved();
2460        }
2461}
2462
2463template <>
2464inline int ParsingEngine< X8_Buffer<EBCDIC> >::Parse_Name() {
2465        int name_pos = AbsPos();
2466        ScanTo(NameFollow);
2467        int lgth = AbsPos()-name_pos;
2468//      int nameID = local_EBCDIC_table->Lookup_or_Insert(GetCodeUnitPtr(name_pos), lgth);
2469//      if (nameID != 0) return nameID;
2470//      else {
2471                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2472                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2473                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2474                return model_info->symbol_table->LookupOrInsertReserved();
2475//      }
2476}
2477
2478template <>
2479inline int ParsingEngine<UTF8_Buffer>::Parse_Name() {
2480        int name_pos = AbsPos();
2481        ScanTo(NameFollow);
2482        int lgth = AbsPos()-name_pos;
2483        return model_info->symbol_table->UTF8_Lookup_or_Insert_Name(&((char *)x8data)[buffer_rel_pos-lgth], lgth);
2484}
2485
2486template <class B>
2487inline int ParsingEngine<B>::Parse_Nmtoken() {
2488        int name_pos = AbsPos();
2489        ScanTo(NameFollow);
2490        int lgth = AbsPos()-name_pos;
2491        int nameID = model_info->symbol_table->ASCII_Lookup_or_Insert_Nmtoken(&((char *) x8data)[buffer_rel_pos-lgth], lgth);
2492        if (nameID != 0) return nameID;
2493        else {
2494                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2495                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2496                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2497                return model_info->symbol_table->LookupOrInsertReserved_nmtoken();
2498        }
2499}
2500
2501template <>
2502inline int ParsingEngine< X8_Buffer<EBCDIC> >::Parse_Nmtoken() {
2503        int name_pos = AbsPos();
2504        ScanTo(NameFollow);
2505        int lgth = AbsPos()-name_pos;
2506//      int nameID = local_EBCDIC_table->Lookup_or_Insert(GetCodeUnitPtr(name_pos), lgth);
2507//      if (nameID != 0) return nameID;
2508//      else {
2509                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2510                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2511                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2512                return model_info->symbol_table->LookupOrInsertReserved_nmtoken();
2513//      }
2514}
2515template <>
2516inline int ParsingEngine<UTF8_Buffer>::Parse_Nmtoken() {
2517        int name_pos = AbsPos();
2518        ScanTo(NameFollow);
2519        int lgth = AbsPos()-name_pos;
2520        return model_info->symbol_table->UTF8_Lookup_or_Insert_Nmtoken(&((char *)x8data)[buffer_rel_pos-lgth], lgth);
2521}
2522
2523template <class B>
2524inline void ParsingEngine<B>::Parse_DocumentContent() {
2525#if (VALIDATION_MODE == ON)
2526        int cur_state = 0;
2527        Parse_ValidContent(model_info->rootModel, cur_state);
2528        if (model_info->rootModel->transition_map[cur_state][0]==0) {
2529                Validity_Error(vErr_elementvalid);
2530        }
2531#endif
2532#if (VALIDATION_MODE == OFF)   
2533        Parse_WF_Element();
2534        ScanTo(NonWS);
2535        while(at_Comment_Start<B::Base>(cur()) || at_PI_Start<B::Base>(cur()) ){
2536                if (at_Comment_Start<B::Base>(cur()))
2537                        Parse_Comment();
2538                else 
2539                        Parse_PI();
2540                ScanTo(NonWS);
2541        }
2542        if (!at_EOF()) {
2543                Syntax_Error(NT_document);
2544        }       
2545#endif
2546}
2547
Note: See TracBrowser for help on using the repository browser.