| 1 | #include <stdio.h> |
|---|
| 2 | #include <stdlib.h> |
|---|
| 3 | #include <errno.h> |
|---|
| 4 | #include <sys/types.h> |
|---|
| 5 | #include <sys/stat.h> |
|---|
| 6 | |
|---|
| 7 | #define LocalCarryDeclare(name, count)\ |
|---|
| 8 | CarryArray<count> name;\ |
|---|
| 9 | |
|---|
| 10 | #include "../lib/bitblock.hpp" |
|---|
| 11 | #include "../lib/carryQ.hpp" |
|---|
| 12 | #include "../lib/bitstream_iterator.hpp" |
|---|
| 13 | #include "../lib/bitblock_iterator.hpp" |
|---|
| 14 | #include "../lib/s2p.hpp" |
|---|
| 15 | #include "../lib/perflib/perfsec.h" |
|---|
| 16 | |
|---|
| 17 | #include "xmldecl.h" |
|---|
| 18 | #include "namechars.h" |
|---|
| 19 | #include "TagMatcher.hpp" |
|---|
| 20 | #include "LineColTracker.hpp" |
|---|
| 21 | #include "ErrorUtil.h" |
|---|
| 22 | #include "ErrorTracker.h" |
|---|
| 23 | #include "XMLTestSuiteError.h" |
|---|
| 24 | |
|---|
| 25 | #ifdef BUFFER_PROFILING |
|---|
| 26 | BOM_Table * parser_timer; |
|---|
| 27 | #elif CODE_CLOCKER |
|---|
| 28 | //#define NUM_EVENTS 1 |
|---|
| 29 | //int Events[NUM_EVENTS] = {PAPI_TOT_CYC}; |
|---|
| 30 | //int Events[NUM_EVENTS] = {PAPI_L2_DCM}; |
|---|
| 31 | #define NUM_EVENTS 2 |
|---|
| 32 | int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP}; |
|---|
| 33 | int cal_size = 20; |
|---|
| 34 | CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size); |
|---|
| 35 | #else |
|---|
| 36 | void * parser_timer; |
|---|
| 37 | #endif |
|---|
| 38 | |
|---|
| 39 | ErrorTracker error_tracker; |
|---|
| 40 | BitBlock EOF_mask = simd<1>::constant<1>(); |
|---|
| 41 | |
|---|
| 42 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 43 | // Buffer Management |
|---|
| 44 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 45 | #include "../lib/buffer.hpp" |
|---|
| 46 | |
|---|
| 47 | #define OVERLAP_BUFSIZE PADDING_SIZE //sizeof(BitBlock) |
|---|
| 48 | |
|---|
| 49 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 50 | // @ global depends on 'error_tracker' and 'EOF_mask' definitions. |
|---|
| 51 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 52 | @global |
|---|
| 53 | |
|---|
| 54 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 55 | // Headers that depend @ global stream struct types. |
|---|
| 56 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 57 | #include "../lib/transpose.hpp" |
|---|
| 58 | #include "post_process.hpp" |
|---|
| 59 | |
|---|
| 60 | static void do_process(FILE *infile, FILE *outfile); |
|---|
| 61 | |
|---|
| 62 | int main(int argc, char * argv[]) { |
|---|
| 63 | |
|---|
| 64 | char * infilename, * outfilename; |
|---|
| 65 | FILE *infile, *outfile; |
|---|
| 66 | struct stat fileinfo; |
|---|
| 67 | |
|---|
| 68 | if (argc < 2) { |
|---|
| 69 | printf("Usage: %s <filename> [<outputfile>]\n", argv[0]); |
|---|
| 70 | exit(-1); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | infilename = argv[1]; |
|---|
| 74 | stat(infilename, &fileinfo); |
|---|
| 75 | infile = fopen(infilename, "rb"); |
|---|
| 76 | if (!infile) { |
|---|
| 77 | fprintf(stderr, "Error: cannot open %s for input.\n", infilename); |
|---|
| 78 | exit(-1); |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | if (argc < 3) outfile = stdout; |
|---|
| 82 | else { |
|---|
| 83 | outfilename = argv[2]; |
|---|
| 84 | outfile = fopen(outfilename, "wb"); |
|---|
| 85 | if (!outfile) { |
|---|
| 86 | fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename); |
|---|
| 87 | exit(-1); |
|---|
| 88 | } |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | PERF_SEC_BIND(1); |
|---|
| 92 | |
|---|
| 93 | PERF_SEC_INIT(parser_timer); |
|---|
| 94 | |
|---|
| 95 | do_process(infile, outfile); |
|---|
| 96 | |
|---|
| 97 | PERF_SEC_DUMP(parser_timer); |
|---|
| 98 | |
|---|
| 99 | PERF_SEC_DESTROY(parser_timer); |
|---|
| 100 | |
|---|
| 101 | fclose(infile); |
|---|
| 102 | fclose(outfile); |
|---|
| 103 | |
|---|
| 104 | return(0); |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | void do_process(FILE *infile, FILE *outfile) { |
|---|
| 108 | |
|---|
| 109 | @decl |
|---|
| 110 | |
|---|
| 111 | LineColTracker tracker; |
|---|
| 112 | TagMatcher<SEGMENT_SIZE,OVERLAP_BUFSIZE> matcher; |
|---|
| 113 | |
|---|
| 114 | uint8_t * src_buf; |
|---|
| 115 | int block_base=0; |
|---|
| 116 | int buffer_base=0; |
|---|
| 117 | int buffer_pos = 0; |
|---|
| 118 | int block_pos = 0; |
|---|
| 119 | int chars_avail = 0; |
|---|
| 120 | int check_pos = 0; |
|---|
| 121 | int chars_read = 0; |
|---|
| 122 | |
|---|
| 123 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 124 | // Buffer Management |
|---|
| 125 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 126 | BitBlock buf[(PADDING_SIZE + SEGMENT_SIZE + PADDING_SIZE)/sizeof(BitBlock)]; |
|---|
| 127 | src_buf = (uint8_t *)buf + PADDING_SIZE; |
|---|
| 128 | |
|---|
| 129 | //ALLOC_STATIC_ALIGNED_BYTE_BUFFER(src_buf, (PADDING_SIZE + SEGMENT_SIZE + PADDING_SIZE)); |
|---|
| 130 | |
|---|
| 131 | buffer_base = buffer_pos; |
|---|
| 132 | chars_read = fread((void *)src_buf, 1, BUFFER_SIZE, infile); |
|---|
| 133 | chars_avail = chars_read; |
|---|
| 134 | if (chars_avail > SEGMENT_SIZE) chars_avail = SEGMENT_SIZE; |
|---|
| 135 | |
|---|
| 136 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 137 | // XML Validation / Content Model |
|---|
| 138 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 139 | if(chars_read<4){ |
|---|
| 140 | fprintf(stderr,"File is too short. Not well formed.\n"); |
|---|
| 141 | exit(-1); |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | Entity_Info * e = new Entity_Info; |
|---|
| 145 | e->AnalyzeSignature((unsigned char *)src_buf); |
|---|
| 146 | |
|---|
| 147 | if (e->code_unit_base == ASCII) { |
|---|
| 148 | |
|---|
| 149 | XML_Decl_Parser<ASCII> decl_parser((unsigned char *)src_buf); |
|---|
| 150 | |
|---|
| 151 | decl_parser.ReadXMLInfo(*e); |
|---|
| 152 | |
|---|
| 153 | if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){ |
|---|
| 154 | fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n"); |
|---|
| 155 | exit(-1); |
|---|
| 156 | } |
|---|
| 157 | } |
|---|
| 158 | else { |
|---|
| 159 | fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n"); |
|---|
| 160 | exit(-1); |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | if (e->content_start != 0) { |
|---|
| 164 | memmove(&src_buf[0], &src_buf[e->content_start], chars_read - e->content_start); |
|---|
| 165 | buffer_pos = e->content_start; |
|---|
| 166 | if (chars_avail == SEGMENT_SIZE) { |
|---|
| 167 | chars_read = chars_read - e->content_start + fread(&src_buf[chars_read-e->content_start], 1, e->content_start, infile); |
|---|
| 168 | chars_avail = chars_read; |
|---|
| 169 | if (chars_avail > SEGMENT_SIZE) chars_avail = SEGMENT_SIZE; |
|---|
| 170 | } |
|---|
| 171 | else { |
|---|
| 172 | chars_read -=e->content_start; |
|---|
| 173 | chars_avail -=e->content_start; |
|---|
| 174 | } |
|---|
| 175 | } |
|---|
| 176 | |
|---|
| 177 | @stream_stmts |
|---|
| 178 | |
|---|
| 179 | |
|---|
| 180 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 181 | // Full Segments |
|---|
| 182 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 183 | matcher.setSrc((char *)src_buf); |
|---|
| 184 | while (chars_avail == SEGMENT_SIZE) { |
|---|
| 185 | PERF_SEC_START(parser_timer); |
|---|
| 186 | for (int blk = 0; blk < SEGMENT_BLOCKS; blk++) { |
|---|
| 187 | block_base = blk*BLOCK_SIZE; |
|---|
| 188 | s2p_do_block((BytePack *) &src_buf[block_base], basis_bits); |
|---|
| 189 | |
|---|
| 190 | @block_stmts |
|---|
| 191 | |
|---|
| 192 | tracker.StoreNewlines(lex.LF); |
|---|
| 193 | postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, (char *)src_buf, buffer_base, block_base, chars_avail, tracker); |
|---|
| 194 | matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail); |
|---|
| 195 | tracker.AdvanceBlock(); |
|---|
| 196 | } |
|---|
| 197 | matcher.StreamScan(chars_avail); |
|---|
| 198 | matcher.Advance_buffer(); |
|---|
| 199 | PERF_SEC_END(parser_timer, chars_avail); |
|---|
| 200 | |
|---|
| 201 | int bytes_left = chars_read - chars_avail; |
|---|
| 202 | memmove(src_buf, &src_buf[SEGMENT_SIZE], bytes_left); |
|---|
| 203 | chars_read = fread(&src_buf[bytes_left], 1, BUFFER_SIZE - bytes_left, infile) + bytes_left; |
|---|
| 204 | chars_avail = chars_read; |
|---|
| 205 | if (chars_avail > SEGMENT_SIZE) chars_avail = SEGMENT_SIZE; |
|---|
| 206 | buffer_pos += chars_avail; |
|---|
| 207 | buffer_base = buffer_pos; |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 211 | // Final Partial Segment |
|---|
| 212 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 213 | PERF_SEC_START(parser_timer); |
|---|
| 214 | |
|---|
| 215 | block_pos = 0; |
|---|
| 216 | int remaining = chars_avail; |
|---|
| 217 | |
|---|
| 218 | /* Full Blocks */ |
|---|
| 219 | while (remaining >= BLOCK_SIZE) { |
|---|
| 220 | block_base = block_pos; |
|---|
| 221 | s2p_do_block((BytePack *) &src_buf[block_pos], basis_bits); |
|---|
| 222 | @block_stmts |
|---|
| 223 | tracker.StoreNewlines(lex.LF); |
|---|
| 224 | postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, (char *)src_buf, buffer_base, block_base, chars_avail, tracker); |
|---|
| 225 | matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail); |
|---|
| 226 | tracker.AdvanceBlock(); |
|---|
| 227 | block_pos += BLOCK_SIZE; |
|---|
| 228 | remaining -= BLOCK_SIZE; |
|---|
| 229 | } |
|---|
| 230 | block_base = block_pos; |
|---|
| 231 | |
|---|
| 232 | /* Partial Block or Any Carry */ |
|---|
| 233 | if (remaining > 0 || @any_carry) { |
|---|
| 234 | EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-remaining)); |
|---|
| 235 | s2p_do_final_block((BytePack *) &src_buf[block_pos], basis_bits, EOF_mask); |
|---|
| 236 | @final_block_stmts |
|---|
| 237 | tracker.StoreNewlines(lex.LF); |
|---|
| 238 | postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, (char *)src_buf, buffer_base, block_base, chars_avail, tracker); |
|---|
| 239 | matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail); |
|---|
| 240 | tracker.AdvanceBlock(); |
|---|
| 241 | |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | buffer_pos += chars_avail; |
|---|
| 245 | buffer_base = buffer_pos; |
|---|
| 246 | |
|---|
| 247 | matcher.StreamScan(chars_avail); |
|---|
| 248 | matcher.Advance_buffer(); |
|---|
| 249 | |
|---|
| 250 | PERF_SEC_END(parser_timer, chars_avail); |
|---|
| 251 | if (matcher.depth != 0) { |
|---|
| 252 | fprintf(stderr, "tag matching error (depth %i) at position %i\n", matcher.depth, buffer_base); |
|---|
| 253 | exit(-1); |
|---|
| 254 | } |
|---|
| 255 | } |
|---|
| 256 | |
|---|