source: proto/parabix2/pablo_template.c @ 866

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

Update for @global struct type declarations.

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;
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 * error_msg, int error_pos_in_block) {
72  int error_line, error_column;
73  tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
74  fprintf(stderr, "%s at line %i, column %i\n", error_msg, error_line, error_column);
75}
76
77
78static inline int NameStrt_check(int pos) {
79        int block_pos = block_base + pos;
80        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
81              ReportError("name start error", pos);
82              exit(-1);
83        }
84        return 0;
85}
86
87static inline int Name_check(int pos) {
88        int block_pos = block_base + pos;
89        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
90              ReportError("name error", pos);
91              exit(-1);
92        }
93        return 0;
94}
95
96static inline int PIName_check(int pos) {
97        int block_pos = block_base + pos;
98        int file_pos = block_pos+buffer_base; 
99        if (at_XxMmLll<ASCII>((unsigned char*)&source[block_pos]) && (source[block_pos+3]=='?' || source[block_pos+3]<= ' ')) {
100              // "<?xml" legal at start of file.
101              if ((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0])) return 0;
102              ReportError("[Xx][Mm][Ll] illegal as PI name", pos);
103              exit(-1);
104        }
105        return 0;
106}
107
108static inline int CD_check(int pos) {
109        int block_pos = block_base + pos;
110        if (!at_CDATA1<ASCII>((unsigned char*)&source[block_pos])){
111              ReportError("CDATA error", pos);
112              exit(-1);
113        }
114        return 0;
115}
116
117static inline int GenRef_check(int pos) {
118        int block_pos = block_base + pos;
119        unsigned char* s = (unsigned char*)&source[block_pos];
120        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))){
121              ReportError("Undefined reference", pos);
122              exit(-1);
123        }
124        return 0;
125}
126
127static inline int HexRef_check(int pos) {
128        int block_pos = block_base + pos;
129        unsigned char* s = (unsigned char*)&source[block_pos];
130        int ch_val = 0;
131        while(at_HexDigit<ASCII>(s)){
132          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
133          if (ch_val> 0x10FFFF ){
134            ReportError("Illegal character reference", pos);
135            exit(-1);
136          }
137          s++;
138        }
139        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
140          ReportError("Illegal character reference", pos);
141          exit(-1);
142        }
143        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
144          ReportError("Illegal XML 1.0 character reference", pos);
145          exit(-1);
146        }
147        return 0;
148}
149
150static inline int DecRef_check(int pos) {
151        int block_pos = block_base + pos;
152        unsigned char* s = (unsigned char*)&source[block_pos];
153        int ch_val = 0;
154        while(at_HexDigit<ASCII>(s)){
155          ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
156          if (ch_val> 0x10FFFF ){
157            ReportError("Illegal character reference", pos);
158            exit(-1);
159          }
160          s++;
161        }
162        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
163          ReportError("Illegal character reference", pos);
164          exit(-1);
165        }
166        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
167          ReportError("Illegal XML 1.0 character reference", pos);
168          exit(-1);
169        }
170        return 0;
171}
172
173static inline int AttRef_check(int pos) {
174        int block_pos = block_base + pos;
175        unsigned char* s = (unsigned char*)&source[block_pos];
176        int ch_val = 0;
177        if(s[0]=='#'){
178          s++;
179          if(s[0]=='x' || s[0]=='X'){
180            s++;
181            while(at_HexDigit<ASCII>(s)){
182              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
183              s++;
184            }
185          }
186          else{     
187            while(at_HexDigit<ASCII>(s)){
188              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
189              s++;
190            }
191          }
192          if (ch_val==60){
193            ReportError("Attribute values contain '<' characters after reference expansion", pos);
194            exit(-1);
195          }       
196        }
197        else if(at_Ref_lt<ASCII>(s)){
198          ReportError("Attribute values contain '<' characters after reference expansion", pos);
199          exit(-1);
200        }         
201        return 0;
202}
203
204@global
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(lex.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(ctCDPI_Callouts.PI_name_starts)){
312          StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
313        }
314       
315        if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
316          StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
317        }
318       
319        if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
320          StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
321        }
322       
323        if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
324          StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
325        }
326       
327        if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
328          StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, 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(lex.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(ctCDPI_Callouts.PI_name_starts)){
366          StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
367        }
368       
369        if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
370          StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
371        }
372       
373        if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
374          StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
375        }
376       
377        if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
378          StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
379        }
380       
381        if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
382          StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, 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    tracker.Advance_buffer();
405
406
407    PERF_SEC_END(parser_timer, chars_avail);
408
409    buf_pos += chars_avail;
410    buffer_base = buf_pos;
411    if(chars_avail!=chars_read){
412      int bytes_left = chars_read-chars_avail;
413      memmove(srcbuf, &srcbuf[BUFFER_SIZE], bytes_left);
414      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE , infile)+bytes_left;
415      chars_avail = min(chars_read,BUFFER_SIZE);
416    }
417    else
418      break;   
419  }
420  if(t.depth!=0){
421    fprintf(stderr, "tag matching error (depth %i) at position %i\n", t.depth, buffer_base);
422    exit(-1);
423  }       
424   
425}
426
427
428
429int
430main(int argc, char * argv[]) {
431        char * infilename, * outfilename;       
432        FILE *infile, *outfile;
433        struct stat fileinfo;
434
435        if (argc < 2) {
436                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
437                exit(-1);
438        }
439
440        infilename = argv[1];
441        stat(infilename, &fileinfo);
442        infile = fopen(infilename, "rb");
443        if (!infile) {
444                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
445                exit(-1);
446        }
447       
448        if (argc < 3) outfile = stdout;
449        else {
450                outfilename = argv[2];
451                outfile = fopen(outfilename, "wb");
452                if (!outfile) {
453                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
454                        exit(-1);
455                }
456        }
457
458//      PERF_SEC_BIND(1);
459
460        PERF_SEC_INIT(parser_timer);
461
462        do_process(infile, outfile);
463       
464        PERF_SEC_DUMP(parser_timer);
465       
466        PERF_SEC_DESTROY(parser_timer);
467
468        fclose(infile);
469        fclose(outfile);
470        return(0);
471}
Note: See TracBrowser for help on using the repository browser.