source: proto/parabix2/pablo_template.c @ 827

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

Move bitmap base NameStart/NameChar? tests into namechars.h

File size: 12.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
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
69static inline int NameStrt_check(int pos) {
70        int block_pos = block_base + pos;
71        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
72              fprintf(stderr, "name start error found at position %i\n",block_pos+buffer_base);
73              exit(-1);
74        }
75        return 0;
76}
77
78static inline int Name_check(int pos) {
79        int block_pos = block_base + pos;
80        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
81              fprintf(stderr, "name error found at position %i\n",block_pos+buffer_base);
82              exit(-1);
83        }
84        return 0;
85}
86
87static inline int PIName_check(int pos) {
88        int block_pos = block_base + pos;
89        int file_pos = block_pos+buffer_base; 
90        if (at_XxMmLll<ASCII>((unsigned char*)&source[block_pos]) && (source[block_pos+3]=='?' || source[block_pos+3]<= ' ')) {
91              // "<?xml" legal at start of file.
92              if ((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0])) return 0;
93              fprintf(stderr, "[Xx][Mm][Ll] illegal as PI name at position %i\n",file_pos);
94              exit(-1);
95        }
96        return 0;
97}
98
99static inline int CD_check(int pos) {
100        int block_pos = block_base + pos;
101        if (!at_CDATA1<ASCII>((unsigned char*)&source[block_pos])){
102              fprintf(stderr, "CDATA error found at position %i\n",block_pos+buffer_base);
103              exit(-1);
104        }
105        return 0;
106}
107
108static inline int GenRef_check(int pos) {
109        int block_pos = block_base + pos;
110        unsigned char* s = (unsigned char*)&source[block_pos];
111        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))){
112              fprintf(stderr, "Undefined Reference found at position %i\n",block_pos+buffer_base);
113              exit(-1);
114        }
115        return 0;
116}
117
118static inline int HexRef_check(int pos) {
119        int block_pos = block_base + pos;
120        unsigned char* s = (unsigned char*)&source[block_pos];
121        int ch_val = 0;
122        while(at_HexDigit<ASCII>(s)){
123          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
124          if (ch_val> 0x10FFFF ){
125            fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
126            exit(-1);
127          }
128          s++;
129        }
130        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
131          fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
132          exit(-1);
133        }
134        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
135          fprintf(stderr, "Illegal XML 1.0 character reference found at position %i\n",block_pos+buffer_base);
136          exit(-1);
137        }
138        return 0;
139}
140
141static inline int DecRef_check(int pos) {
142        int block_pos = block_base + pos;
143        unsigned char* s = (unsigned char*)&source[block_pos];
144        int ch_val = 0;
145        while(at_HexDigit<ASCII>(s)){
146          ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
147          if (ch_val> 0x10FFFF ){
148            fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
149            exit(-1);
150          }
151          s++;
152        }
153        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
154          fprintf(stderr, "Illegal character reference found at position %i\n",block_pos+buffer_base);
155          exit(-1);
156        }
157        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
158          fprintf(stderr, "Illegal XML 1.0 character reference found at position %i\n",block_pos+buffer_base);
159          exit(-1);
160        }
161        return 0;
162}
163
164static inline int AttRef_check(int pos) {
165        int block_pos = block_base + pos;
166        unsigned char* s = (unsigned char*)&source[block_pos];
167        int ch_val = 0;
168        if(s[0]=='#'){
169          s++;
170          if(s[0]=='x' || s[0]=='X'){
171            s++;
172            while(at_HexDigit<ASCII>(s)){
173              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
174              s++;
175            }
176          }
177          else{     
178            while(at_HexDigit<ASCII>(s)){
179              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
180              s++;
181            }
182          }
183          if (ch_val==60){
184            fprintf(stderr, "Attribute values contain '<' characters after reference expansion at position %i\n",block_pos+buffer_base);
185            exit(-1);
186          }       
187        }
188        else if(at_Ref_lt<ASCII>(s)){
189          fprintf(stderr, "Attribute values contain '<' characters after reference expansion at position %i\n",block_pos+buffer_base);
190          exit(-1);
191        }         
192        return 0;
193}
194
195
196void do_process(FILE *infile, FILE *outfile) {
197
198  @decl
199
200  BytePack U8[8];
201  BitBlock bit[8];
202  BitBlock EOF_mask = simd_const_1(1);
203  int buf_pos = 0;
204  int block_pos = 0;
205  int errpos = 0;
206  int chars_avail = 0;
207  int check_pos = 0;
208  int chars_read = 0;
209  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(SIMD_type)];
210 
211  char * srcbuf = ((char *) buf) + OVERLAP_BUFSIZE;
212  buffer_base = buf_pos;
213  source = srcbuf;
214 
215  chars_read = fread((void *)srcbuf, 1, BUFFER_SIZE + OVERLAP_BUFSIZE, infile);
216  chars_avail = min(chars_read,BUFFER_SIZE);
217 
218  if(chars_read<4){
219    fprintf(stderr,"File is too short. Not well formed.\n");
220    exit(-1);
221  }
222 
223  tag_matcher t(srcbuf);
224
225  Entity_Info * e = new Entity_Info;
226  e->AnalyzeSignature((unsigned char *)srcbuf);
227
228  if (e->code_unit_base == ASCII) {
229                       
230    XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
231
232    decl_parser.ReadXMLInfo(*e); 
233   
234    if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){
235        fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n");
236        exit(-1);
237    }
238  }
239  else {
240    fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n");
241        exit(-1);
242  }
243 
244  if (e->content_start != 0) {
245        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_read - e->content_start);
246        buf_pos = e->content_start;
247        if (chars_avail == BUFFER_SIZE) {
248                chars_read = chars_read - e->content_start + 
249                             fread(&srcbuf[chars_read-e->content_start], 1, e->content_start, infile);
250                chars_avail = min(chars_read,BUFFER_SIZE);
251        }
252        else {
253          chars_read -=e->content_start;
254          chars_avail -=e->content_start;
255        }
256  }
257 
258  @stream_stmts
259
260  while(1){
261
262    PERF_SEC_START(parser_timer);
263
264    block_pos = 0;
265
266    if(chars_avail < BUFFER_SIZE){
267     
268      while (block_pos <= chars_avail){
269
270        int bytes = chars_avail - block_pos;   
271        block_base = block_pos;
272         
273        if(bytes < BLOCK_SIZE){
274          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-bytes));
275        }
276        BytePack * U8 = (BytePack *) &srcbuf[block_pos];
277       
278        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
279        bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7]);
280
281        bit[0] = simd_and(bit[0], EOF_mask);
282        bit[1] = simd_and(bit[1], EOF_mask);
283        bit[2] = simd_and(bit[2], EOF_mask);
284        bit[3] = simd_and(bit[3], EOF_mask);
285        bit[4] = simd_and(bit[4], EOF_mask);
286        bit[5] = simd_and(bit[5], EOF_mask);
287        bit[6] = simd_and(bit[6], EOF_mask);
288        bit[7] = simd_and(bit[7], EOF_mask);
289
290        @block_stmts
291
292        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
293          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
294          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
295        }
296         
297        if (bitblock_has_bit(PI_namestarts)){
298          StreamScan((ScanBlock *) &PI_namestarts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
299        }
300       
301        if (bitblock_has_bit(CD_starts)){
302          StreamScan((ScanBlock *) &CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
303        }
304       
305        if (bitblock_has_bit(GenRef2)){
306          StreamScan((ScanBlock *) &GenRef2, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
307        }
308       
309        if (bitblock_has_bit(DecRef3)){
310          StreamScan((ScanBlock *) &DecRef3, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
311        }
312       
313        if (bitblock_has_bit(HexRef4)){
314          StreamScan((ScanBlock *) &HexRef4, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
315        }
316       
317        if (bitblock_has_bit(AttRef)){
318          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
319        }
320
321        if (bitblock_has_bit(error_mask)) {
322          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
323          fprintf(stderr, "error found at position %i\n",errpos);
324          exit(-1);
325        }
326
327        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
328       
329        block_pos += BLOCK_SIZE;
330      }
331    }
332    else{
333      while (block_pos < chars_avail){
334       
335        block_base = block_pos;
336         
337        BytePack * U8 = (BytePack *) &srcbuf[block_pos];
338       
339        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
340        bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7]);
341
342        @block_stmts
343               
344        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
345          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
346          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
347        }
348       
349        if (bitblock_has_bit(PI_namestarts)){
350          StreamScan((ScanBlock *) &PI_namestarts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
351        }
352       
353        if (bitblock_has_bit(CD_starts)){
354          StreamScan((ScanBlock *) &CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
355        }
356       
357        if (bitblock_has_bit(GenRef2)){
358          StreamScan((ScanBlock *) &GenRef2, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
359        }
360       
361        if (bitblock_has_bit(DecRef3)){
362          StreamScan((ScanBlock *) &DecRef3, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
363        }
364       
365        if (bitblock_has_bit(HexRef4)){
366          StreamScan((ScanBlock *) &HexRef4, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
367        }
368       
369        if (bitblock_has_bit(AttRef)){
370          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
371        }
372       
373        if (bitblock_has_bit(error_mask)) {
374          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
375          fprintf(stderr, "error found at position %i\n",errpos);
376          exit(-1);
377        }
378
379        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
380
381        block_pos += BLOCK_SIZE;
382      }
383    }
384
385
386    t.StreamScan(chars_avail);
387    t.Advance_buffer();
388
389
390    PERF_SEC_END(parser_timer, chars_avail);
391
392    buf_pos += chars_avail;
393    buffer_base = buf_pos;
394    if(chars_avail!=chars_read){
395      int bytes_left = chars_read-chars_avail;
396      memmove(srcbuf, &srcbuf[BUFFER_SIZE], bytes_left);
397      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE , infile)+bytes_left;
398      chars_avail = min(chars_read,BUFFER_SIZE);
399    }
400    else
401      break;   
402  }
403  if(t.depth!=0){
404    fprintf(stderr, "tag matching error (depth %i) at position %i\n", t.depth, buffer_base);
405    exit(-1);
406  }       
407   
408}
409
410
411
412int
413main(int argc, char * argv[]) {
414        char * infilename, * outfilename;       
415        FILE *infile, *outfile;
416        struct stat fileinfo;
417
418        if (argc < 2) {
419                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
420                exit(-1);
421        }
422
423        infilename = argv[1];
424        stat(infilename, &fileinfo);
425        infile = fopen(infilename, "rb");
426        if (!infile) {
427                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
428                exit(-1);
429        }
430       
431        if (argc < 3) outfile = stdout;
432        else {
433                outfilename = argv[2];
434                outfile = fopen(outfilename, "wb");
435                if (!outfile) {
436                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
437                        exit(-1);
438                }
439        }
440
441//      PERF_SEC_BIND(1);
442
443        PERF_SEC_INIT(parser_timer);
444
445        do_process(infile, outfile);
446       
447        PERF_SEC_DUMP(parser_timer);
448       
449        PERF_SEC_DESTROY(parser_timer);
450
451        fclose(infile);
452        fclose(outfile);
453        return(0);
454}
Note: See TracBrowser for help on using the repository browser.