source: proto/parabix2/pablo_template.c @ 861

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

Organize call outs from Reference processing.

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
205void do_process(FILE *infile, FILE *outfile) {
206
207  @decl
208
209
210
211  BytePack U8[8];
212  BitBlock bit[8];
213  BitBlock EOF_mask = simd_const_1(1);
214  int buf_pos = 0;
215  int block_pos = 0;
216  int errpos = 0;
217  int chars_avail = 0;
218  int check_pos = 0;
219  int chars_read = 0;
220  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(SIMD_type)];
221 
222  char * srcbuf = ((char *) buf) + OVERLAP_BUFSIZE;
223  buffer_base = buf_pos;
224  source = srcbuf;
225 
226  chars_read = fread((void *)srcbuf, 1, BUFFER_SIZE + OVERLAP_BUFSIZE, infile);
227  chars_avail = min(chars_read,BUFFER_SIZE); 
228   
229  tag_matcher t(srcbuf);
230 
231  if(chars_read<4){
232    fprintf(stderr,"File is too short. Not well formed.\n");
233    exit(-1);
234  }
235
236  Entity_Info * e = new Entity_Info;
237  e->AnalyzeSignature((unsigned char *)srcbuf);
238
239  if (e->code_unit_base == ASCII) {
240                       
241    XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
242
243    decl_parser.ReadXMLInfo(*e); 
244   
245    if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){
246        fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n");
247        exit(-1);
248    }
249  }
250  else {
251    fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n");
252        exit(-1);
253  }
254 
255  if (e->content_start != 0) {
256        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_read - e->content_start);
257        buf_pos = e->content_start;
258        if (chars_avail == BUFFER_SIZE) {
259                chars_read = chars_read - e->content_start + 
260                             fread(&srcbuf[chars_read-e->content_start], 1, e->content_start, infile);
261                chars_avail = min(chars_read,BUFFER_SIZE);
262        }
263        else {
264          chars_read -=e->content_start;
265          chars_avail -=e->content_start;
266        }
267  }
268 
269  @stream_stmts
270
271  while(1){
272
273    PERF_SEC_START(parser_timer);
274
275    block_pos = 0;
276
277    if(chars_avail < BUFFER_SIZE){
278     
279      while (block_pos <= chars_avail){
280
281        int bytes = chars_avail - block_pos;   
282        block_base = block_pos;
283         
284        if(bytes < BLOCK_SIZE){
285          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-bytes));
286        }
287        BytePack * U8 = (BytePack *) &srcbuf[block_pos];
288       
289        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
290        bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7]);
291
292        bit[0] = simd_and(bit[0], EOF_mask);
293        bit[1] = simd_and(bit[1], EOF_mask);
294        bit[2] = simd_and(bit[2], EOF_mask);
295        bit[3] = simd_and(bit[3], EOF_mask);
296        bit[4] = simd_and(bit[4], EOF_mask);
297        bit[5] = simd_and(bit[5], EOF_mask);
298        bit[6] = simd_and(bit[6], EOF_mask);
299        bit[7] = simd_and(bit[7], EOF_mask);
300
301        @block_stmts
302               
303        tracker.StoreNewlines(lex.LF); 
304
305        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
306          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
307          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
308        }
309         
310        if (bitblock_has_bit(ctCDPI_Callouts.PI_name_starts)){
311          StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
312        }
313       
314        if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
315          StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
316        }
317       
318        if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
319          StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
320        }
321       
322        if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
323          StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
324        }
325       
326        if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
327          StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
328        }
329       
330        if (bitblock_has_bit(AttRef)){
331          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
332        }
333
334        if (bitblock_has_bit(error_mask)) {
335          int errpos = count_forward_zeroes(error_mask);
336          ReportError("error found", errpos);
337          exit(-1);
338        }
339
340        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
341        tracker.AdvanceBlock(); 
342        block_pos += BLOCK_SIZE;
343      }
344    }
345    else{
346      while (block_pos < chars_avail){
347       
348        block_base = block_pos;
349         
350        BytePack * U8 = (BytePack *) &srcbuf[block_pos];
351       
352        s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
353        bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7]);
354
355        @block_stmts   
356       
357        tracker.StoreNewlines(lex.LF); 
358               
359        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
360          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
361          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
362        }
363       
364        if (bitblock_has_bit(ctCDPI_Callouts.PI_name_starts)){
365          StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
366        }
367       
368        if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
369          StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
370        }
371       
372        if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
373          StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
374        }
375       
376        if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
377          StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
378        }
379       
380        if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
381          StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
382        }
383       
384        if (bitblock_has_bit(AttRef)){
385          StreamScan((ScanBlock *) &AttRef, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
386        }
387       
388        if (bitblock_has_bit(error_mask)) {
389          int errpos = count_forward_zeroes(error_mask);
390          ReportError("error found", errpos);
391          exit(-1);
392        }
393
394        t.store_streams(tag_marks, NameFollows, Misc_mask, chars_avail);
395        tracker.AdvanceBlock();
396        block_pos += BLOCK_SIZE;
397      }
398    }
399
400
401    t.StreamScan(chars_avail);
402    t.Advance_buffer();
403    tracker.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.