source: proto/parabix2/pablo_template_stl.cpp @ 1597

Last change on this file since 1597 was 1591, checked in by cameron, 8 years ago

Remove dependency on ../lib/types.h

File size: 14.4 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6
7#define LocalCarryDeclare(name, count)\
8CarryArray<count> name;\
9
10//#include "../lib/types.h"
11typedef long ScanBlock;
12#include "../lib/carryQ.hpp"
13
14#define BLOCK_SIZE (sizeof(BitBlock) * 8)
15#define SEGMENT_BLOCKS 12
16#define BUFFER_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
17#define OVERLAP_BUFSIZE (sizeof(BitBlock))
18
19#include "xmldecl.h"
20#include "namechars.h"
21#include "../lib/perflib/perfsec.h"
22#include "../lib/s2p.hpp"
23
24#define sisd_load_unaligned(addr) _mm_loadu_si128(addr)
25#include "TagMatcher.hpp"
26#include "LineColTracker.hpp"
27#include "ErrorUtil.h"
28#include "ErrorTracker.h"
29#include "XMLTestSuiteError.h"
30
31#include "BitStreamIterator.h"
32
33#ifdef BUFFER_PROFILING
34        BOM_Table * parser_timer;
35
36#elif CODE_CLOCKER
37        #define NUM_EVENTS 1
38        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
39        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
40        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
41        int cal_size = 20;
42        CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
43#else
44        void * parser_timer;
45#endif
46
47int block_base=0;
48int buffer_base=0;
49char * source;
50
51LineColTracker tracker;
52TagMatcher matcher;
53ErrorTracker error_tracker;
54BitBlock EOF_mask = simd<1>::constant<1>();
55
56/* StreamScan & Post Process Declarations */
57//      static inline int StreamScanToFirst(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block)
58static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block);
59
60static inline int NameStrt_check(int pos);
61static inline int Name_check(int pos);
62static inline int PIName_check(int pos);
63static inline int CD_check(int pos);
64static inline int GenRef_check(int pos);
65static inline int HexRef_check(int pos);
66static inline int DecRef_check(int pos);
67static inline int AttRef_check(int pos);
68
69@global
70
71static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits);
72static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask);
73static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, int chars_avail);
74
75void do_process(FILE *infile, FILE *outfile);
76
77static inline void validate_block(BitStreamIterator & start, int block_base, int is_valid(int));
78static inline void validate_block(BitStreamIterator & start, int block_base, int is_valid(int,int));
79
80int main(int argc, char * argv[]) {
81
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
144/* StreamScan & Post Process Definitions */
145static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block) {
146
147        int blk;
148        int block_pos = 0;
149        int pos;
150
151        for (blk = 0; blk < blk_count; blk++) {
152                ScanBlock s = stream[blk];
153                while(s) {
154                        pos = (cfzl(s) + block_pos);
155                        int code = (ProcessPos(pos));
156                        if (code) {
157                                *error_pos_in_block = pos;
158                                return code; // error code
159                        }
160                        s = s & (s-1);  // clear rightmost bit.
161                }
162                block_pos += 8 * sizeof(ScanBlock);
163        }
164        return 0;
165}
166
167static inline int NameStrt_check(int pos) {
168        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[pos]) == 0){
169              return XMLTestSuiteError::NAME_START;
170        }
171        return 0;
172}
173
174static inline int Name_check(int pos) {
175        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[pos]) == 0){
176                  return XMLTestSuiteError::NAME;
177        }
178        return 0;
179}
180
181static inline int PIName_check(int pos, int file_pos) {
182        if (at_XxMmLll<ASCII>((unsigned char*)&source[pos]) && (source[pos+3]=='?' || source[pos+3]<= ' ')) {
183              // "<?xml" legal at start of file.
184              if (!((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0]))) {
185                  return XMLTestSuiteError::XMLPINAME;
186              }
187        }
188        return 0;
189}
190
191static inline int CD_check(int pos) {
192        if (!at_CDATA1<ASCII>((unsigned char*)&source[pos])){
193                  return XMLTestSuiteError::CDATA;
194        }
195        return 0;
196}
197
198static inline int GenRef_check(int pos) {
199        unsigned char* s = (unsigned char*)&source[pos];
200        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))){
201              return XMLTestSuiteError::UNDEFREF;
202        }
203        return 0;
204}
205
206static inline int HexRef_check(int pos) {
207        unsigned char* s = (unsigned char*)&source[pos];
208        int ch_val = 0;
209        while(at_HexDigit<ASCII>(s)){
210          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
211          if (ch_val> 0x10FFFF ){
212                return XMLTestSuiteError::CHARREF;
213          }
214          s++;
215        }
216        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
217          return XMLTestSuiteError::CHARREF;
218        }
219        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
220          return XMLTestSuiteError::XML10CHARREF;
221        }
222        return 0;
223}
224
225static inline int DecRef_check(int pos) {
226        unsigned char* s = (unsigned char*)&source[pos];
227        int ch_val = 0;
228        while(at_HexDigit<ASCII>(s)){
229          ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
230          if (ch_val> 0x10FFFF ){
231                        return XMLTestSuiteError::CHARREF;
232          }
233          s++;
234        }
235        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
236                  return XMLTestSuiteError::CHARREF;
237        }
238        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
239                  return XMLTestSuiteError::XML10CHARREF;
240        }
241        return 0;
242}
243
244static inline int AttRef_check(int pos) {
245        unsigned char* s = (unsigned char*)&source[pos];
246        int ch_val = 0;
247        if(s[0]=='#'){
248          s++;
249          if(s[0]=='x' || s[0]=='X'){
250            s++;
251            while(at_HexDigit<ASCII>(s)){
252              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
253              s++;
254            }
255          }
256          else{
257            while(at_HexDigit<ASCII>(s)){
258              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
259              s++;
260            }
261          }
262          if (ch_val==60){
263            return XMLTestSuiteError::ATTREF;
264          }
265        }
266        else if(at_Ref_lt<ASCII>(s)){
267          return XMLTestSuiteError::ATTREF;
268        }
269        return 0;
270}
271
272static inline void validate_block(BitStreamIterator & start, int block_base, int is_valid(int)) {
273
274        BitStreamIterator end;
275        int pos, block_pos;
276
277        while(start != end) {
278
279                block_pos = block_base + *start;
280                int rv = is_valid(block_pos);
281
282                if (rv) {
283                        int error_line, error_column;
284                        tracker.get_Line_and_Column(block_pos, error_line, error_column);
285                        ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
286                        exit(-1);
287                }
288                start++;
289        }
290}
291
292static inline void validate_block(BitStreamIterator & start, int block_base, int buffer_base, int is_valid(int,int)) {
293
294        BitStreamIterator end;
295        int pos, block_pos, file_pos;
296
297        while(start != end) {
298
299                block_pos = block_base + *start;
300                file_pos = block_pos+buffer_base;
301
302
303                int rv = is_valid(block_pos, file_pos);
304
305                if (rv) {
306                        int error_line, error_column;
307                        tracker.get_Line_and_Column(block_pos, error_line, error_column);
308                        ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
309                        exit(-1);
310                }
311                start++;
312        }
313}
314
315static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, int chars_avail){
316            tracker.StoreNewlines(lex.LF);
317
318                if (bitblock_has_bit(simd_or(check_streams.non_ascii_name_starts, check_streams.non_ascii_names))) {
319                    BitStreamIterator iter_NameStrt_check(&check_streams.non_ascii_name_starts, sizeof(BitBlock)/sizeof(ScanBlock));
320                        validate_block(iter_NameStrt_check, block_base, NameStrt_check);
321                        BitStreamIterator iter_Name_check(&check_streams.non_ascii_names, sizeof(BitBlock)/sizeof(ScanBlock));
322                        validate_block(iter_Name_check, block_base, Name_check);
323                }
324            if (bitblock_has_bit(ctCDPI_Callouts.PI_name_starts)){
325                BitStreamIterator iter_PI_name_starts(&(ctCDPI_Callouts.PI_name_starts), sizeof(BitBlock)/sizeof(ScanBlock));
326                validate_block(iter_PI_name_starts, block_base, buffer_base, PIName_check);
327            }
328            if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
329                BitStreamIterator iter_CD_check(&ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock));
330                validate_block(iter_CD_check, block_base, CD_check);
331            }
332            if(bitblock_has_bit(ref_Callouts.GenRef_starts)){
333                BitStreamIterator iter_GenRef_check(&ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock));
334                validate_block(iter_GenRef_check, block_base, GenRef_check);
335            }
336            if(bitblock_has_bit(ref_Callouts.DecRef_starts)){
337                BitStreamIterator iter_DecRef_check(&ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock));
338                validate_block(iter_DecRef_check, block_base, DecRef_check);
339            }
340            if(bitblock_has_bit(ref_Callouts.HexRef_starts)){
341                BitStreamIterator iter_HexRef_check(&ref_Callouts.HexRef_starts, sizeof(BitBlock)/sizeof(ScanBlock));
342                validate_block(iter_HexRef_check, block_base, HexRef_check);
343            }
344            if(bitblock_has_bit(check_streams.att_refs)){
345                BitStreamIterator iter_AttRef_check(&check_streams.att_refs, sizeof(BitBlock)/sizeof(ScanBlock));
346                validate_block(iter_AttRef_check, block_base, AttRef_check);
347            }
348
349                if(error_tracker.Has_Noted_Error()){
350                        int error_line, error_column;
351                        tracker.get_Line_and_Column(error_tracker.Noted_Pos_In_Block(), error_line, error_column);
352                        ReportError(error_tracker.Noted_Error_Msg(), error_line, error_column);
353                        exit(-1);
354                }
355
356                matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail);
357                tracker.AdvanceBlock();
358
359}
360
361void do_process(FILE *infile, FILE *outfile) {
362
363@decl
364
365  int buf_pos = 0;
366  int block_pos = 0;
367  int chars_avail = 0;
368  int check_pos = 0;
369  int chars_read = 0;
370  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(BitBlock)];
371
372  char * srcbuf = ((char *) buf) + OVERLAP_BUFSIZE;
373  buffer_base = buf_pos;
374  source = srcbuf;
375
376  chars_read = fread((void *)srcbuf, 1, BUFFER_SIZE + OVERLAP_BUFSIZE, infile);
377  chars_avail = chars_read;
378  if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
379
380  matcher.setSrc(srcbuf);
381
382  if(chars_read<4){
383    fprintf(stderr,"File is too short. Not well formed.\n");
384    exit(-1);
385  }
386
387  Entity_Info * e = new Entity_Info;
388  e->AnalyzeSignature((unsigned char *)srcbuf);
389
390  if (e->code_unit_base == ASCII) {
391
392    XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
393
394    decl_parser.ReadXMLInfo(*e);
395
396    if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){
397        fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n");
398        exit(-1);
399    }
400  }
401  else {
402    fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n");
403        exit(-1);
404  }
405
406  if (e->content_start != 0) {
407        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_read - e->content_start);
408        buf_pos = e->content_start;
409        if (chars_avail == BUFFER_SIZE) {
410                chars_read = chars_read - e->content_start +
411                             fread(&srcbuf[chars_read-e->content_start], 1, e->content_start, infile);
412                chars_avail = chars_read;
413                if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
414        }
415        else {
416          chars_read -=e->content_start;
417          chars_avail -=e->content_start;
418        }
419  }
420
421@stream_stmts
422
423/* Full Buffers */
424
425    while (chars_avail == BUFFER_SIZE) {
426      PERF_SEC_START(parser_timer);
427      for (int blk = 0; blk < SEGMENT_BLOCKS; blk++) {
428          block_base = blk*BLOCK_SIZE;
429          s2p_do_block((BytePack *) &srcbuf[block_base], basis_bits);
430          @block_stmts
431          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, chars_avail);
432      }
433      matcher.StreamScan(chars_avail);
434      matcher.Advance_buffer();
435      tracker.Advance_buffer();
436      PERF_SEC_END(parser_timer, chars_avail);
437
438      int bytes_left = chars_read - chars_avail;
439      memmove(srcbuf, &srcbuf[BUFFER_SIZE], bytes_left);
440      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE + OVERLAP_BUFSIZE - bytes_left, infile) + bytes_left;
441      chars_avail = chars_read;
442      if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
443      buf_pos += chars_avail;
444      buffer_base = buf_pos;
445    }
446/* Final Partial Buffer */
447    PERF_SEC_START(parser_timer);
448
449    block_pos = 0;
450    int remaining = chars_avail;
451/* Full Blocks */
452    while (remaining >= BLOCK_SIZE) {
453          block_base = block_pos;
454          s2p_do_block((BytePack *) &srcbuf[block_pos], basis_bits);
455          @block_stmts
456          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, chars_avail);
457          block_pos += BLOCK_SIZE;
458          remaining -= BLOCK_SIZE;
459    }
460    block_base = block_pos;
461    if (remaining > 0 || @any_carry) {
462          EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-remaining));
463          s2p_do_final_block((BytePack *) &srcbuf[block_pos], basis_bits, EOF_mask);
464          @final_block_stmts
465          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, chars_avail);
466    }
467    buf_pos += chars_avail;
468    buffer_base = buf_pos;
469
470    matcher.StreamScan(chars_avail);
471    matcher.Advance_buffer();
472    tracker.Advance_buffer();
473
474
475    PERF_SEC_END(parser_timer, chars_avail);
476    if (matcher.depth != 0) {
477      fprintf(stderr, "tag matching error (depth %i) at position %i\n", matcher.depth, buffer_base);
478      exit(-1);
479    }
480}
481
Note: See TracBrowser for help on using the repository browser.