source: proto/parabix2/template.c @ 951

Last change on this file since 951 was 951, checked in by cameron, 8 years ago

Parameterize OVERLAP_BUFSIZE

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