source: proto/SymbolTable/symtab_ls_template.cpp @ 1491

Last change on this file since 1491 was 1491, checked in by ksherdy, 8 years ago

Removed direct .cpp #include.

File size: 16.6 KB
Line 
1#define TEMPLATED_SIMD_LIB
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <errno.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <../lib_simd.h>
9#include <ls_symbol_table.h>
10#include <queue>
11#include <string>
12using namespace std;
13
14#define DEBUG 0
15#define BLOCK_SIZE (sizeof(SIMD_type) * 8)
16#define SEGMENT_BLOCKS 12
17#define BUFFER_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
18#define OVERLAP_BUFSIZE 2*(sizeof(SIMD_type))
19
20#include <../carryQ.h>
21#include <xmldecl.h>
22#include <namechars.h>
23#include <../perflib/perfsec.h>
24#include <../s2p.h>
25
26#include <TagMatcher.h>
27#include <LineColTracker.h>
28#include <ErrorUtil.h>
29#include <ErrorTracker.h>
30#include <XMLTestSuiteError.h>
31
32#ifdef BUFFER_PROFILING
33        BOM_Table * parser_timer;
34
35#elif CODE_CLOCKER
36        #define NUM_EVENTS 1
37        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
38        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
39        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
40        int cal_size = 20;
41        CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
42#else
43        void * parser_timer;
44#endif
45
46int block_base=0;
47int buffer_base=0;
48int buffer_last;
49char * source;
50LineColTracker tracker;
51TagMatcher matcher;
52ErrorTracker error_tracker;
53BitBlock EOF_mask = simd_const_1(1);
54
55queue <size_t> elem_starts_buf;
56queue <size_t> elem_ends_buf;
57LSSymbolTable ls_symbol_table;
58
59/* StreamScan & Post Process Declarations */
60//      static inline int StreamScanToFirst(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block)
61static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block);
62
63static inline int NameStrt_check(int pos);
64static inline int Name_check(int pos);
65static inline int PIName_check(int pos);
66static inline int CD_check(int pos);
67static inline int GenRef_check(int pos);
68static inline int HexRef_check(int pos);
69static inline int DecRef_check(int pos);
70static inline int AttRef_check(int pos);
71
72@global
73
74static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits);
75static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask);
76static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, Tag_Callouts & tag_Callouts, int chars_avail);
77static inline void do_symbol_table_lookup();
78
79void do_process(FILE *infile, FILE *outfile);
80
81int main(int argc, char * argv[]) {
82        char * infilename, * outfilename;
83        FILE *infile, *outfile;
84        struct stat fileinfo;
85
86        if (argc < 2) {
87                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
88                exit(-1);
89        }
90
91        infilename = argv[1];
92        stat(infilename, &fileinfo);
93        infile = fopen(infilename, "rb");
94        if (!infile) {
95                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
96                exit(-1);
97        }
98
99        if (argc < 3) outfile = stdout;
100        else {
101                outfilename = argv[2];
102                outfile = fopen(outfilename, "wb");
103                if (!outfile) {
104                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
105                        exit(-1);
106                }
107        }
108
109//      PERF_SEC_BIND(1);
110
111        PERF_SEC_INIT(parser_timer);
112
113        do_process(infile, outfile);
114
115        PERF_SEC_DUMP(parser_timer);
116
117        PERF_SEC_DESTROY(parser_timer);
118
119        fclose(infile);
120        fclose(outfile);
121
122        return(0);
123}
124
125/* s2p Definitions */
126static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits) {
127  s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
128        basis_bits.bit_0, basis_bits.bit_1, basis_bits.bit_2, basis_bits.bit_3, basis_bits.bit_4, basis_bits.bit_5, basis_bits.bit_6, basis_bits.bit_7);
129}
130
131static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask) {
132  s2p_do_block(U8, basis_bits);
133  basis_bits.bit_0 = simd_and(basis_bits.bit_0, EOF_mask);
134  basis_bits.bit_1 = simd_and(basis_bits.bit_1, EOF_mask);
135  basis_bits.bit_2 = simd_and(basis_bits.bit_2, EOF_mask);
136  basis_bits.bit_3 = simd_and(basis_bits.bit_3, EOF_mask);
137  basis_bits.bit_4 = simd_and(basis_bits.bit_4, EOF_mask);
138  basis_bits.bit_5 = simd_and(basis_bits.bit_5, EOF_mask);
139  basis_bits.bit_6 = simd_and(basis_bits.bit_6, EOF_mask);
140  basis_bits.bit_7 = simd_and(basis_bits.bit_7, EOF_mask);
141}
142
143/* StreamScan & Post Process Definitions */
144static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block) {
145
146        int blk;
147        int block_pos = 0;
148        int pos;
149
150        for (blk = 0; blk < blk_count; blk++) {
151                ScanBlock s = stream[blk];
152                while(s) {
153                        pos = (cfzl(s) + block_pos);
154                        int code = (ProcessPos(pos));
155                        if (code) {
156                                *error_pos_in_block = pos;
157                                return code; // error code
158                        }
159                        s = s & (s-1);  // clear rightmost bit.
160                }
161                block_pos += 8 * sizeof(ScanBlock);
162        }
163        return 0;
164}
165
166static inline int ElemStrt_check(int pos) {
167        int block_pos = block_base + pos;
168        elem_starts_buf.push(buffer_base + block_pos);
169        return 0;
170}
171
172static inline int ElemEnd_check(int pos) {
173        int block_pos = block_base + pos;
174        elem_ends_buf.push(buffer_base + block_pos);
175        return 0;
176}
177
178static inline int NameStrt_check(int pos) {
179        int block_pos = block_base + pos;
180        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
181              return XMLTestSuiteError::NAME_START;
182        }
183        return 0;
184}
185
186static inline int Name_check(int pos) {
187        int block_pos = block_base + pos;
188        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
189                  return XMLTestSuiteError::NAME;
190        }
191        return 0;
192}
193
194static inline int PIName_check(int pos) {
195        int block_pos = block_base + pos;
196        int file_pos = block_pos+buffer_base;
197        if (at_XxMmLll<ASCII>((unsigned char*)&source[block_pos]) && (source[block_pos+3]=='?' || source[block_pos+3]<= ' ')) {
198              // "<?xml" legal at start of file.
199              if (!((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0]))) {
200                  return XMLTestSuiteError::XMLPINAME;
201              }
202        }
203        return 0;
204}
205
206static inline int CD_check(int pos) {
207        int block_pos = block_base + pos;
208        if (!at_CDATA1<ASCII>((unsigned char*)&source[block_pos])){
209                  return XMLTestSuiteError::CDATA;
210        }
211        return 0;
212}
213
214static inline int GenRef_check(int pos) {
215        int block_pos = block_base + pos;
216        unsigned char* s = (unsigned char*)&source[block_pos];
217        if (!(at_Ref_gt<ASCII>(s)||at_Ref_lt<ASCII>(s)||at_Ref_amp<ASCII>(s)||at_Ref_quot<ASCII>(s)||at_Ref_apos<ASCII>(s))){
218              return XMLTestSuiteError::UNDEFREF;
219        }
220        return 0;
221}
222
223static inline int HexRef_check(int pos) {
224        int block_pos = block_base + pos;
225        unsigned char* s = (unsigned char*)&source[block_pos];
226        int ch_val = 0;
227        while(at_HexDigit<ASCII>(s)){
228          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
229          if (ch_val> 0x10FFFF ){
230                return XMLTestSuiteError::CHARREF;
231          }
232          s++;
233        }
234        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
235          return XMLTestSuiteError::CHARREF;
236        }
237        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
238          return XMLTestSuiteError::XML10CHARREF;
239        }
240        return 0;
241}
242
243static inline int DecRef_check(int pos) {
244        int block_pos = block_base + pos;
245        unsigned char* s = (unsigned char*)&source[block_pos];
246        int ch_val = 0;
247        while(at_HexDigit<ASCII>(s)){
248          ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
249          if (ch_val> 0x10FFFF ){
250                        return XMLTestSuiteError::CHARREF;
251          }
252          s++;
253        }
254        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
255                  return XMLTestSuiteError::CHARREF;
256        }
257        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
258                  return XMLTestSuiteError::XML10CHARREF;
259        }
260        return 0;
261}
262
263static inline int AttRef_check(int pos) {
264        int block_pos = block_base + pos;
265        unsigned char* s = (unsigned char*)&source[block_pos];
266        int ch_val = 0;
267        if(s[0]=='#'){
268          s++;
269          if(s[0]=='x' || s[0]=='X'){
270            s++;
271            while(at_HexDigit<ASCII>(s)){
272              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
273              s++;
274            }
275          }
276          else{
277            while(at_HexDigit<ASCII>(s)){
278              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
279              s++;
280            }
281          }
282          if (ch_val==60){
283            return XMLTestSuiteError::ATTREF;
284          }
285        }
286        else if(at_Ref_lt<ASCII>(s)){
287          return XMLTestSuiteError::ATTREF;
288        }
289        return 0;
290}
291
292static inline void do_symbol_table_lookup()
293{
294    while( !elem_starts_buf.empty() && !elem_ends_buf.empty() )
295    {
296        int start = elem_starts_buf.front();
297        int end = elem_ends_buf.front();
298        elem_starts_buf.pop();
299        elem_ends_buf.pop();
300        int length = end - start;
301
302        //lookup or insert to symbol table
303#if DEBUG
304        char* symbol = new char[length+1];
305        strncpy ( symbol, source + start - buffer_base, length );
306        symbol[length] ='\0';
307        printf ("start: %i[%i] | end: %i[%i] | length: %i | symbol: %s\n", start, start-buffer_base, end, end-buffer_base, length, symbol );
308
309        delete symbol; symbol = 0;
310#endif
311
312        ls_symbol_table.put((unsigned char*)source + start - buffer_base, length);
313
314    }
315}
316
317static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, Tag_Callouts & tag_Callouts, int chars_avail){
318
319    tracker.StoreNewlines(lex.LF);
320    int rv, error_pos_in_block, error_line, error_column;
321
322    if ( bitblock_has_bit(tag_Callouts.ElemName_starts))
323    {
324        StreamScan((ScanBlock *) &tag_Callouts.ElemName_starts, sizeof(BitBlock)/sizeof(ScanBlock), ElemStrt_check, &error_pos_in_block);
325    }
326
327    if ( bitblock_has_bit(tag_Callouts.ElemName_ends) )
328    {
329        StreamScan((ScanBlock *) &tag_Callouts.ElemName_ends, sizeof(BitBlock)/sizeof(ScanBlock), ElemEnd_check, &error_pos_in_block);
330    }
331
332    do_symbol_table_lookup();
333
334    if (bitblock_has_bit(simd_or(check_streams.non_ascii_name_starts, check_streams.non_ascii_names))) {
335      rv = StreamScan((ScanBlock *) &check_streams.non_ascii_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check, &error_pos_in_block);
336      if (rv) {
337              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
338              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
339              exit(-1);
340      }
341
342      rv = StreamScan((ScanBlock *) &check_streams.non_ascii_names, sizeof(BitBlock)/sizeof(ScanBlock), Name_check, &error_pos_in_block);
343      if (rv) {
344              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
345              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
346              exit(-1);
347      }
348    }
349
350    if (bitblock_has_bit(ctCDPI_Callouts.PI_name_starts)){
351      rv = StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check, &error_pos_in_block);
352      if (rv) {
353              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
354              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
355              exit(-1);
356      }
357    }
358
359    if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
360      rv = StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check, &error_pos_in_block);
361      if (rv) {
362              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
363              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
364              exit(-1);
365      }
366    }
367
368    if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
369      rv = StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check, &error_pos_in_block);
370      if (rv) {
371              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
372              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
373              exit(-1);
374      }
375    }
376
377    if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
378      rv = StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check, &error_pos_in_block);
379      if (rv) {
380              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
381              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
382              exit(-1);
383      }
384    }
385
386    if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
387      rv = StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check, &error_pos_in_block);
388      if (rv) {
389              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
390              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
391              exit(-1);
392      }
393    }
394
395    if (bitblock_has_bit(check_streams.att_refs)){
396      rv = StreamScan((ScanBlock *) &check_streams.att_refs, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check, &error_pos_in_block);
397      if (rv) {
398              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
399              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
400              exit(-1);
401      }
402    }
403
404    if(error_tracker.Has_Noted_Error()){
405            tracker.get_Line_and_Column(error_tracker.Noted_Pos_In_Block(), error_line, error_column);
406            ReportError(error_tracker.Noted_Error_Msg(), error_line, error_column);
407            exit(-1);
408    }
409
410    matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail);
411    tracker.AdvanceBlock();
412}
413
414static inline void print_GIDS()
415{
416    ls_symbol_table.display_flattened_symbol_values();
417    ls_symbol_table.display_flattened_gids();
418}
419
420void do_process(FILE *infile, FILE *outfile) {
421
422@decl
423
424  int buf_pos = 0;
425  int block_pos = 0;
426  int errpos = 0;
427  int chars_avail = 0;
428  int check_pos = 0;
429  int chars_read = 0;
430  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(SIMD_type)];
431
432  char * srcbuf = ((char *) buf) + OVERLAP_BUFSIZE;
433  buffer_base = buf_pos;
434  source = srcbuf;
435  chars_read = fread((void *)srcbuf, 1, BUFFER_SIZE + OVERLAP_BUFSIZE, infile);
436  chars_avail = chars_read;
437  if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
438
439  matcher.setSrc(srcbuf);
440
441  if(chars_read<4){
442    fprintf(stderr,"File is too short. Not well formed.\n");
443    exit(-1);
444  }
445
446  Entity_Info * e = new Entity_Info;
447  e->AnalyzeSignature((unsigned char *)srcbuf);
448
449  if (e->code_unit_base == ASCII) {
450
451    XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
452
453    decl_parser.ReadXMLInfo(*e);
454
455    if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){
456        fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n");
457        exit(-1);
458    }
459  }
460  else {
461    fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n");
462        exit(-1);
463  }
464
465  if (e->content_start != 0) {
466        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_read - e->content_start);
467        buf_pos = e->content_start;
468        buffer_base = buf_pos;
469        if (chars_avail == BUFFER_SIZE) {
470                chars_read = chars_read - e->content_start +
471                             fread(&srcbuf[chars_read-e->content_start], 1, e->content_start, infile);
472                chars_avail = chars_read;
473                if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
474        }
475        else {
476          chars_read -=e->content_start;
477          chars_avail -=e->content_start;
478        }
479  }
480
481@stream_stmts
482
483/* Full Buffers */
484    while (chars_avail == BUFFER_SIZE) {
485      PERF_SEC_START(parser_timer);
486      for (int blk = 0; blk < SEGMENT_BLOCKS; blk++) {
487          block_base = blk*BLOCK_SIZE;
488          s2p_do_block((BytePack *) &srcbuf[block_base], basis_bits);
489          @block_stmts
490          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, tag_Callouts, chars_avail);
491      }
492      matcher.StreamScan(chars_avail);
493      matcher.Advance_buffer();
494      tracker.Advance_buffer();
495      PERF_SEC_END(parser_timer, chars_avail);
496
497      int bytes_left = chars_read - chars_avail;
498      memmove(buf, &srcbuf[BUFFER_SIZE - OVERLAP_BUFSIZE], bytes_left + OVERLAP_BUFSIZE);
499      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE + OVERLAP_BUFSIZE - bytes_left, infile) + bytes_left;
500      chars_avail = chars_read;
501      if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
502      buf_pos += chars_avail;
503      buffer_base = buf_pos;
504    }
505/* Final Partial Buffer */
506    PERF_SEC_START(parser_timer);
507
508    block_pos = 0;
509    int remaining = chars_avail;
510/* Full Blocks */
511    while (remaining >= BLOCK_SIZE) {
512          block_base = block_pos;
513          s2p_do_block((BytePack *) &srcbuf[block_pos], basis_bits);
514          @block_stmts
515          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, tag_Callouts, chars_avail);
516          block_pos += BLOCK_SIZE;
517          remaining -= BLOCK_SIZE;
518    }
519    block_base = block_pos;
520    if (remaining > 0 || @any_carry) {
521          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-remaining));
522          s2p_do_final_block((BytePack *) &srcbuf[block_pos], basis_bits, EOF_mask);
523          @final_block_stmts
524          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, tag_Callouts, chars_avail);
525    }
526    buf_pos += chars_avail;
527    buffer_base = buf_pos;
528
529    matcher.StreamScan(chars_avail);
530    matcher.Advance_buffer();
531    tracker.Advance_buffer();
532
533    ls_symbol_table.bind();
534    ls_symbol_table.finalize();
535
536    PERF_SEC_END(parser_timer, chars_avail);
537    if (matcher.depth != 0) {
538      fprintf(stderr, "tag matching error (depth %i) at position %i\n", matcher.depth, buffer_base);
539      exit(-1);
540    }
541
542#if DEBUG
543    print_GIDS();
544#endif
545    ls_symbol_table.clear();
546}
Note: See TracBrowser for help on using the repository browser.