source: proto/parabix2/template.c @ 630

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