source: proto/parabix2/pablo_template.c @ 815

Last change on this file since 815 was 815, checked in by ksherdy, 9 years ago

Update templates to output specific post processing error messages prior to error_mask marked errors.

File size: 14.9 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#include "../lib/lib_simd.h"
7
8#define BLOCK_SIZE 128
9#define BUFFER_SIZE (BLOCK_SIZE * 26)
10#define OVERLAP_BUFSIZE 16
11
12typedef long ScanBlock;
13typedef SIMD_type BytePack;
14typedef SIMD_type BitBlock;
15
16
17#include "../lib/carryQ.h"
18
19
20       
21
22#include "xmldecl.h"
23#include "xml_error.c"
24#include "xmldecl.c"
25#include "namechars.h"
26
27#include "../lib/perflib/perfsec.h"
28#include "../lib/s2p.h"
29
30#include "tag_matcher.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;
50
51
52static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int)) {
53        int blk;
54        int block_pos = 0;
55
56        for (blk = 0; blk < blk_count; blk++) {
57                ScanBlock s = stream[blk];
58                while(s) {
59                        int code = (ProcessPos(cfzl(s) + block_pos));
60                        if (code) return code;
61                        s = s & (s-1);  // clear rightmost bit.
62                }
63                block_pos += 8 * sizeof(ScanBlock);
64        }
65        return 0;
66} 
67
68
69
70inline bool bit_test(unsigned char * bit_Map, int codepoint) {
71        return (bit_Map[codepoint/8] >> (7 - codepoint % 8)) & 1;
72}
73
74bool is_XML10_NameStrt_codepoint(int codepoint) {
75        switch (codepoint >> 12) {
76                case 0: return bit_test(NameStrt_XML10_0000_11FF, codepoint);
77                case 1: if (codepoint <= 0x11FF)
78                                return bit_test(NameStrt_XML10_0000_11FF, codepoint);
79                        else if (codepoint < 0x1E00) return false;
80                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
81                case 2: if (codepoint > 0x2182) return false;
82                        else return bit_test(NameStrt_XML10_2000_21FF, codepoint & 0x1FF);
83                case 3: if (codepoint > 0x312C) return false;
84                        else return bit_test(NameStrt_XML10_3000_31FF, codepoint & 0x1FF);
85                case 4: return codepoint >= 0x4E00;
86                case 5: case 6: case 7: case 8: return true;
87                case 9: return codepoint <= 0x9FA5;
88                case 0xA: return codepoint >= 0xAC00;
89                case 0xB: case 0xC: return true;
90                case 0xD: return codepoint <= 0xD7A3;
91                default: return false;
92        }
93}
94
95bool is_XML10_NameChar_codepoint(int codepoint) {
96        switch (codepoint >> 12) {
97                case 0: return bit_test(NameChar_XML10_0000_11FF, codepoint);
98                case 1: if (codepoint <= 0x11FF)
99                                return bit_test(NameChar_XML10_0000_11FF, codepoint);
100                        else if (codepoint < 0x1E00) return false;
101                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
102                case 2: if (codepoint > 0x2182) return false;
103                        else return bit_test(NameChar_XML10_2000_21FF, codepoint & 0x1FF);
104                case 3: if (codepoint > 0x312C) return false;
105                        else return bit_test(NameChar_XML10_3000_31FF, codepoint & 0x1FF);
106                case 4: return codepoint >= 0x4E00;
107                case 5: case 6: case 7: case 8: return true;
108                case 9: return codepoint <= 0x9FA5;
109                case 0xA:       return codepoint >= 0xAC00;
110                case 0xB: case 0xC: return true;
111                case 0xD: return codepoint <= 0xD7A3;
112                default: return false;
113        }
114}
115
116inline int XML_10_UTF8_NameStrt_bytes (unsigned char bytes[]) {
117        if (bytes[0] <= 0x7F) {
118                if (bit_test(NameStrt_XML10_0000_11FF, (int) bytes[0])) return 1;
119                else return 0;
120        }
121        else if (bytes[0] <= 0xDF) {
122                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
123                if (bit_test(NameStrt_XML10_0000_11FF, codepoint)) return 2;
124                else return 0;
125        }
126        else if (bytes[0] <= 0xEF) {
127                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
128                return is_XML10_NameStrt_codepoint(codepoint) ? 3 : 0;
129        }
130        else return 0;
131}
132
133inline int XML_10_UTF8_NameChar_bytes (unsigned char bytes[]) {
134        if (bytes[0] <= 0x7F) {
135                if (bit_test(NameChar_XML10_0000_11FF, (int) bytes[0])) return 1;
136                else return 0;
137        }
138        else if (bytes[0] <= 0xDF) {
139                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
140                if (bit_test(NameChar_XML10_0000_11FF, codepoint)) return 2;
141                else return 0;
142        }
143        else if (bytes[0] <= 0xEF) {
144                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
145                return is_XML10_NameChar_codepoint(codepoint) ? 3 : 0;
146        }
147        else return 0;
148}
149
150
151static inline int NameStrt_check(int pos) {
152        int block_pos = block_base + pos;
153        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
154              fprintf(stderr, "name start error found at position %i\n",block_pos+buffer_base);
155              exit(-1);
156        }
157        return 0;
158}
159
160static inline int Name_check(int pos) {
161        int block_pos = block_base + pos;
162        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
163              fprintf(stderr, "name error found at position %i\n",block_pos+buffer_base);
164              exit(-1);
165        }
166        return 0;
167}
168
169static inline int PIName_check(int pos) {
170        int block_pos = block_base + pos;
171        int file_pos = block_pos+buffer_base; 
172        if (at_XxMmLll<ASCII>((unsigned char*)&source[block_pos]) && (source[block_pos+3]=='?' || source[block_pos+3]<= ' ')) {
173              // "<?xml" legal at start of file.
174              if ((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0])) return 0;
175              fprintf(stderr, "[Xx][Mm][Ll] illegal as PI name at position %i\n",file_pos);
176              exit(-1);
177        }
178        return 0;
179}
180
181static inline int CD_check(int pos) {
182        int block_pos = block_base + pos;
183        if (!at_CDATA1<ASCII>((unsigned char*)&source[block_pos])){
184              fprintf(stderr, "CDATA error found at position %i\n",block_pos+buffer_base);
185              exit(-1);
186        }
187        return 0;
188}
189
190static inline int GenRef_check(int pos) {
191        int block_pos = block_base + pos;
192        unsigned char* s = (unsigned char*)&source[block_pos];
193        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))){
194              fprintf(stderr, "Undefined Reference found at position %i\n",block_pos+buffer_base);
195              exit(-1);
196        }
197        return 0;
198}
199
200static inline int HexRef_check(int pos) {
201        int block_pos = block_base + pos;
202        unsigned char* s = (unsigned char*)&source[block_pos];
203        int ch_val = 0;
204        while(at_HexDigit<ASCII>(s)){
205          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
206          if (ch_val> 0x10FFFF ){
207            fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
208            exit(-1);
209          }
210          s++;
211        }
212        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
213          fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
214          exit(-1);
215        }
216        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
217          fprintf(stderr, "Illegal XML 1.0 character reference found at position %i\n",block_pos+buffer_base);
218          exit(-1);
219        }
220        return 0;
221}
222
223static inline int DecRef_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 = DigitVal<ASCII>(s[0]) + ch_val*10;
229          if (ch_val> 0x10FFFF ){
230            fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
231            exit(-1);
232          }
233          s++;
234        }
235        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
236          fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
237          exit(-1);
238        }
239        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
240          fprintf(stderr, "Illegal XML 1.0 character reference found at position %i\n",block_pos+buffer_base);
241          exit(-1);
242        }
243        return 0;
244}
245
246static inline int AttRef_check(int pos) {
247        int block_pos = block_base + pos;
248        unsigned char* s = (unsigned char*)&source[block_pos];
249        int ch_val = 0;
250        if(s[0]=='#'){
251          s++;
252          if(s[0]=='x' || s[0]=='X'){
253            s++;
254            while(at_HexDigit<ASCII>(s)){
255              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
256              s++;
257            }
258          }
259          else{     
260            while(at_HexDigit<ASCII>(s)){
261              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
262              s++;
263            }
264          }
265          if (ch_val==60){
266            fprintf(stderr, "Attribute values contain '<' characters after reference expansion at position %i\n",block_pos+buffer_base);
267            exit(-1);
268          }       
269        }
270        else if(at_Ref_lt<ASCII>(s)){
271          fprintf(stderr, "Attribute values contain '<' characters after reference expansion at position %i\n",block_pos+buffer_base);
272          exit(-1);
273        }         
274        return 0;
275}
276
277
278void do_process(FILE *infile, FILE *outfile) {
279
280  @decl
281
282  BytePack U8[8];
283  BitBlock bit[8];
284  BitBlock EOF_mask = simd_const_1(1);
285  int buf_pos = 0;
286  int block_pos = 0;
287  int errpos = 0;
288  int chars_avail = 0;
289  int check_pos = 0;
290  int chars_read = 0;
291  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(SIMD_type)];
292 
293  char * srcbuf = ((char *) buf) + OVERLAP_BUFSIZE;
294  buffer_base = buf_pos;
295  source = srcbuf;
296 
297  chars_read = fread((void *)srcbuf, 1, BUFFER_SIZE + OVERLAP_BUFSIZE, infile);
298  chars_avail = min(chars_read,BUFFER_SIZE);
299 
300  if(chars_read<4){
301    fprintf(stderr,"File is too short. Not well formed.\n");
302    exit(-1);
303  }
304 
305  tag_matcher t(srcbuf);
306
307  Entity_Info * e = new Entity_Info;
308  e->AnalyzeSignature((unsigned char *)srcbuf);
309
310  if (e->code_unit_base == ASCII) {
311                       
312    XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
313
314    decl_parser.ReadXMLInfo(*e); 
315   
316    if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){
317        fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n");
318        exit(-1);
319    }
320  }
321  else {
322    fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n");
323        exit(-1);
324  }
325 
326  if (e->content_start != 0) {
327        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_read - e->content_start);
328        buf_pos = e->content_start;
329        if (chars_avail == BUFFER_SIZE) {
330                chars_read = chars_read - e->content_start + 
331                             fread(&srcbuf[chars_read-e->content_start], 1, e->content_start, infile);
332                chars_avail = min(chars_read,BUFFER_SIZE);
333        }
334        else {
335          chars_read -=e->content_start;
336          chars_avail -=e->content_start;
337        }
338  }
339 
340  @stream_stmts
341
342  while(1){
343
344    PERF_SEC_START(parser_timer);
345
346    block_pos = 0;
347
348    if(chars_avail < BUFFER_SIZE){
349     
350      while (block_pos <= chars_avail){
351
352        int bytes = chars_avail - block_pos;   
353        block_base = block_pos;
354         
355        if(bytes < BLOCK_SIZE){
356          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-bytes));
357        }
358        BytePack * U8 = (BytePack *) &srcbuf[block_pos];
359       
360        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
361        bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7]);
362
363        bit[0] = simd_and(bit[0], EOF_mask);
364        bit[1] = simd_and(bit[1], EOF_mask);
365        bit[2] = simd_and(bit[2], EOF_mask);
366        bit[3] = simd_and(bit[3], EOF_mask);
367        bit[4] = simd_and(bit[4], EOF_mask);
368        bit[5] = simd_and(bit[5], EOF_mask);
369        bit[6] = simd_and(bit[6], EOF_mask);
370        bit[7] = simd_and(bit[7], EOF_mask);
371
372        @block_stmts
373
374        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
375          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
376          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
377        }
378         
379        if (bitblock_has_bit(PI_namestarts)){
380          StreamScan((ScanBlock *) &PI_namestarts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
381        }
382       
383        if (bitblock_has_bit(CD_starts)){
384          StreamScan((ScanBlock *) &CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
385        }
386       
387        if (bitblock_has_bit(GenRef2)){
388          StreamScan((ScanBlock *) &GenRef2, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
389        }
390       
391        if (bitblock_has_bit(DecRef3)){
392          StreamScan((ScanBlock *) &DecRef3, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
393        }
394       
395        if (bitblock_has_bit(HexRef4)){
396          StreamScan((ScanBlock *) &HexRef4, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
397        }
398       
399        if (bitblock_has_bit(AttRef)){
400          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
401        }
402
403        if (bitblock_has_bit(error_mask)) {
404          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
405          fprintf(stderr, "error found at position %i\n",errpos);
406          exit(-1);
407        }
408
409        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
410       
411        block_pos += BLOCK_SIZE;
412      }
413    }
414    else{
415      while (block_pos < chars_avail){
416       
417        block_base = block_pos;
418         
419        BytePack * U8 = (BytePack *) &srcbuf[block_pos];
420       
421        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
422        bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7]);
423
424        @block_stmts
425               
426        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
427          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
428          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
429        }
430       
431        if (bitblock_has_bit(PI_namestarts)){
432          StreamScan((ScanBlock *) &PI_namestarts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
433        }
434       
435        if (bitblock_has_bit(CD_starts)){
436          StreamScan((ScanBlock *) &CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
437        }
438       
439        if (bitblock_has_bit(GenRef2)){
440          StreamScan((ScanBlock *) &GenRef2, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
441        }
442       
443        if (bitblock_has_bit(DecRef3)){
444          StreamScan((ScanBlock *) &DecRef3, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
445        }
446       
447        if (bitblock_has_bit(HexRef4)){
448          StreamScan((ScanBlock *) &HexRef4, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
449        }
450       
451        if (bitblock_has_bit(AttRef)){
452          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
453        }
454       
455        if (bitblock_has_bit(error_mask)) {
456          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
457          fprintf(stderr, "error found at position %i\n",errpos);
458          exit(-1);
459        }
460
461        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
462
463        block_pos += BLOCK_SIZE;
464      }
465    }
466
467
468    t.StreamScan(chars_avail);
469    t.Advance_buffer();
470
471
472    PERF_SEC_END(parser_timer, chars_avail);
473
474    buf_pos += chars_avail;
475    buffer_base = buf_pos;
476    if(chars_avail!=chars_read){
477      int bytes_left = chars_read-chars_avail;
478      memmove(srcbuf, &srcbuf[BUFFER_SIZE], bytes_left);
479      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE , infile)+bytes_left;
480      chars_avail = min(chars_read,BUFFER_SIZE);
481    }
482    else
483      break;   
484  }
485  if(t.depth!=0){
486    fprintf(stderr, "tag matching error (depth %i) at position %i\n", t.depth, buffer_base);
487    exit(-1);
488  }       
489   
490}
491
492
493
494int
495main(int argc, char * argv[]) {
496        char * infilename, * outfilename;       
497        FILE *infile, *outfile;
498        struct stat fileinfo;
499
500        if (argc < 2) {
501                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
502                exit(-1);
503        }
504
505        infilename = argv[1];
506        stat(infilename, &fileinfo);
507        infile = fopen(infilename, "rb");
508        if (!infile) {
509                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
510                exit(-1);
511        }
512       
513        if (argc < 3) outfile = stdout;
514        else {
515                outfilename = argv[2];
516                outfile = fopen(outfilename, "wb");
517                if (!outfile) {
518                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
519                        exit(-1);
520                }
521        }
522
523//      PERF_SEC_BIND(1);
524
525        PERF_SEC_INIT(parser_timer);
526
527        do_process(infile, outfile);
528       
529        PERF_SEC_DUMP(parser_timer);
530       
531        PERF_SEC_DESTROY(parser_timer);
532
533        fclose(infile);
534        fclose(outfile);
535        return(0);
536}
Note: See TracBrowser for help on using the repository browser.