source: proto/parabix2/pablo_template.c @ 889

Last change on this file since 889 was 889, checked in by ksherdy, 9 years ago

Add Carry_Adjust. Fix @any_carry in template. Add 'add_dump_stmts' support.

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