source: proto/parabix2/pablo_template.c @ 757

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

Pablo versions of parabix2 files

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