source: proto/parabix2/pablo_template.c @ 838

Last change on this file since 838 was 838, checked in by lindanl, 9 years ago

Line/Column? number tracking

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