source: proto/parabix2/template.c @ 761

Last change on this file since 761 was 632, checked in by cameron, 9 years ago

Messages

File size: 15.0 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  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(SIMD_type)];
286 
287  char * srcbuf = ((char *) 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, this xmlwf demo only works for UTF-8.\n");
313        exit(-1);
314    }
315  }
316  else {
317    fprintf(stderr,"Sorry, this xmlwf demo does not 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 * U8 = (BytePack *) &srcbuf[block_pos];
354       
355        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
356        array_bit__0_,array_bit__1_,array_bit__2_,array_bit__3_,array_bit__4_,array_bit__5_,array_bit__6_,array_bit__7_);
357
358        array_bit__0_ = simd_and(array_bit__0_, EOF_mask);
359        array_bit__1_ = simd_and(array_bit__1_, EOF_mask);
360        array_bit__2_ = simd_and(array_bit__2_, EOF_mask);
361        array_bit__3_ = simd_and(array_bit__3_, EOF_mask);
362        array_bit__4_ = simd_and(array_bit__4_, EOF_mask);
363        array_bit__5_ = simd_and(array_bit__5_, EOF_mask);
364        array_bit__6_ = simd_and(array_bit__6_, EOF_mask);
365        array_bit__7_ = simd_and(array_bit__7_, EOF_mask);
366
367        @block_stmts
368
369
370        if (bitblock_has_bit(error_mask)) {
371          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
372          fprintf(stderr, "error found at position %i\n",errpos);
373          exit(-1);
374        }
375       
376        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
377          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
378          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
379        }
380         
381        if (bitblock_has_bit(PI_namestarts)){
382          StreamScan((ScanBlock *) &PI_namestarts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
383        }
384       
385        if (bitblock_has_bit(CD_starts)){
386          StreamScan((ScanBlock *) &CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
387        }
388       
389        if (bitblock_has_bit(GenRef2)){
390          StreamScan((ScanBlock *) &GenRef2, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
391        }
392       
393        if (bitblock_has_bit(DecRef3)){
394          StreamScan((ScanBlock *) &DecRef3, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
395        }
396       
397        if (bitblock_has_bit(HexRef4)){
398          StreamScan((ScanBlock *) &HexRef4, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
399        }
400       
401        if (bitblock_has_bit(AttRef)){
402          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
403        }
404
405        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
406       
407        block_pos += BLOCK_SIZE;
408      }
409    }
410    else{
411      while (block_pos < chars_avail){
412       
413        block_base = block_pos;
414         
415        BytePack * U8 = (BytePack *) &srcbuf[block_pos];
416       
417        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
418        array_bit__0_,array_bit__1_,array_bit__2_,array_bit__3_,array_bit__4_,array_bit__5_,array_bit__6_,array_bit__7_);
419
420        @block_stmts
421       
422        if (bitblock_has_bit(error_mask)) {
423          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
424          fprintf(stderr, "error found at position %i\n",errpos);
425          exit(-1);
426        }
427       
428        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
429          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
430          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
431        }
432       
433        if (bitblock_has_bit(PI_namestarts)){
434          StreamScan((ScanBlock *) &PI_namestarts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
435        }
436       
437        if (bitblock_has_bit(CD_starts)){
438          StreamScan((ScanBlock *) &CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
439        }
440       
441        if (bitblock_has_bit(GenRef2)){
442          StreamScan((ScanBlock *) &GenRef2, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
443        }
444       
445        if (bitblock_has_bit(DecRef3)){
446          StreamScan((ScanBlock *) &DecRef3, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
447        }
448       
449        if (bitblock_has_bit(HexRef4)){
450          StreamScan((ScanBlock *) &HexRef4, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
451        }
452       
453        if (bitblock_has_bit(AttRef)){
454          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
455        }
456       
457        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
458
459        block_pos += BLOCK_SIZE;
460      }
461    }
462
463    t.StreamScan(chars_avail);
464    t.Advance_buffer();
465
466    PERF_SEC_END(parser_timer, chars_avail);
467
468    buf_pos += chars_avail;
469    buffer_base = buf_pos;
470    if(chars_avail!=chars_read){
471      int bytes_left = chars_read-chars_avail;
472      memmove(srcbuf, &srcbuf[BUFFER_SIZE], bytes_left);
473      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE , infile)+bytes_left;
474      chars_avail = min(chars_read,BUFFER_SIZE);
475    }
476    else
477      break;   
478  }
479  if(t.depth!=0){
480    fprintf(stderr, "tag matching error (depth %i) at position %i\n", t.depth, buffer_base);
481    exit(-1);
482  }       
483   
484}
485
486
487
488int
489main(int argc, char * argv[]) {
490        char * infilename, * outfilename;       
491        FILE *infile, *outfile;
492        struct stat fileinfo;
493
494        if (argc < 2) {
495                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
496                exit(-1);
497        }
498
499        infilename = argv[1];
500        stat(infilename, &fileinfo);
501        infile = fopen(infilename, "rb");
502        if (!infile) {
503                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
504                exit(-1);
505        }
506       
507        if (argc < 3) outfile = stdout;
508        else {
509                outfilename = argv[2];
510                outfile = fopen(outfilename, "wb");
511                if (!outfile) {
512                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
513                        exit(-1);
514                }
515        }
516
517//      PERF_SEC_BIND(1);
518
519        PERF_SEC_INIT(parser_timer);
520
521        do_process(infile, outfile);
522       
523        PERF_SEC_DUMP(parser_timer);
524       
525        PERF_SEC_DESTROY(parser_timer);
526
527        fclose(infile);
528        fclose(outfile);
529        return(0);
530}
Note: See TracBrowser for help on using the repository browser.