source: proto/parabix2/pablo_template.c @ 842

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

Report error positions with line/column

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