1 | /* |
---|
2 | * \s2k{} push model template. |
---|
3 | * |
---|
4 | * grep exact-string search C++ in \s2k{}. |
---|
5 | * |
---|
6 | * Usage: grep [OPTIONS] <infile> [outfile] |
---|
7 | * |
---|
8 | * Warning: |
---|
9 | * |
---|
10 | * Template implementation limits line length to SEGMENT_SIZE bytes, i.e., |
---|
11 | * 1K on 32-bit architecture with 128-bit SIMD registers, and |
---|
12 | * 4K on 64-bit with 128-bit SIMD registers. |
---|
13 | * |
---|
14 | * Program Description: |
---|
15 | * |
---|
16 | * The \s2k{} demo grep program searches a file for lines containing matches |
---|
17 | * to the fixed target pattern, `apple'. |
---|
18 | * The default behaviour of \s2k{} grep is to print all matching lines. |
---|
19 | * |
---|
20 | * The flag -o specifies that only |
---|
21 | * the matched parts of a matching line are produced, with each |
---|
22 | * such part on a separate output line. |
---|
23 | * |
---|
24 | * The flag -b, specifies that the 0-based byte offset within |
---|
25 | * the input file before each line of output. |
---|
26 | |
---|
27 | * If -b is specified with -o, \s2k{} grep prints the offset of |
---|
28 | * each match, formatted as `offset:apple', where `apple' is the target |
---|
29 | * pattern read from memory and offset is the zero-index offset |
---|
30 | * of the first character the match. |
---|
31 | * |
---|
32 | * For example, given an input file containing three occurrences of `apple' |
---|
33 | * at zero-indexed offsets 47,107, and 189, the \s2k{} grep |
---|
34 | * application writes the following results to standard output. |
---|
35 | * |
---|
36 | * 47:apple |
---|
37 | * 107:apple |
---|
38 | * 189:apple |
---|
39 | * |
---|
40 | * This behaviour is equivalent to the following GNU grep utility command. |
---|
41 | * |
---|
42 | * grep needle filename --only-matching --byte-offset |
---|
43 | * |
---|
44 | */ |
---|
45 | /* |
---|
46 | * Template Attributes: |
---|
47 | * |
---|
48 | * The \s2k{} compiler and substitutes generated code fragments for |
---|
49 | * the following predefined template attributes bracked with |
---|
50 | * hashhashhashamp and hashhashash. |
---|
51 | * |
---|
52 | * @global - Stream structure and filter definitions. |
---|
53 | * |
---|
54 | * @struct_decls - Stream structure declarations. |
---|
55 | * |
---|
56 | * @filter_decls - Stream filter declarations. |
---|
57 | * |
---|
58 | * @filter_do_block - Stream filter `do_block()' calls. |
---|
59 | * |
---|
60 | * @filter_do_final_block - Stream filter `do_final_block()' calls. |
---|
61 | * |
---|
62 | * @filter_clear - Stream filter `clear()' calls. |
---|
63 | */ |
---|
64 | |
---|
65 | /* |
---|
66 | * GENERATED CODE. DO NOT MODIFY. |
---|
67 | */ |
---|
68 | |
---|
69 | #define DEBUG 0 |
---|
70 | |
---|
71 | // Runtime directives |
---|
72 | #define BASIS_BITS |
---|
73 | |
---|
74 | // Runtime libraries |
---|
75 | #include <simd-lib/bitblock.hpp> |
---|
76 | #include <simd-lib/bitblock_iterator.hpp> |
---|
77 | #include <simd-lib/runtime.hpp> |
---|
78 | #include <simd-lib/pabloSupport.hpp> |
---|
79 | #include <simd-lib/transpose.hpp> |
---|
80 | #include <simd-lib/mmalloc.hpp> |
---|
81 | |
---|
82 | // C/C++ libraries |
---|
83 | #include <stdio.h> |
---|
84 | #include <stdlib.h> |
---|
85 | #include <string> |
---|
86 | #include <iostream> |
---|
87 | #include <sys/stat.h> |
---|
88 | #include <sys/mman.h> |
---|
89 | #include <fcntl.h> |
---|
90 | using namespace std; |
---|
91 | |
---|
92 | // S2K Generated |
---|
93 | struct Lex |
---|
94 | { |
---|
95 | BitBlock a; |
---|
96 | BitBlock p; |
---|
97 | BitBlock l; |
---|
98 | BitBlock e; |
---|
99 | BitBlock LF; |
---|
100 | }; |
---|
101 | |
---|
102 | struct Output |
---|
103 | { |
---|
104 | BitBlock match_follows; |
---|
105 | BitBlock lines; |
---|
106 | BitBlock line_starts; |
---|
107 | BitBlock line_ends; |
---|
108 | }; |
---|
109 | |
---|
110 | struct ClassifyBytes |
---|
111 | { |
---|
112 | ClassifyBytes() |
---|
113 | { |
---|
114 | } |
---|
115 | |
---|
116 | IDISA_INLINE void do_block(struct Basis_bits & basis_bits, struct Lex & lex) |
---|
117 | { |
---|
118 | BitBlock temp1; |
---|
119 | temp1 = simd_andc(basis_bits.bit_1,basis_bits.bit_0); |
---|
120 | BitBlock temp2; |
---|
121 | temp2 = simd_andc(basis_bits.bit_2,basis_bits.bit_3); |
---|
122 | BitBlock temp3; |
---|
123 | temp3 = simd_and(temp1,temp2); |
---|
124 | BitBlock temp4; |
---|
125 | temp4 = simd_or(basis_bits.bit_4,basis_bits.bit_5); |
---|
126 | BitBlock temp5; |
---|
127 | temp5 = simd_andc(basis_bits.bit_7,basis_bits.bit_6); |
---|
128 | BitBlock temp6; |
---|
129 | temp6 = simd_andc(temp5,temp4); |
---|
130 | lex.a = simd_and(temp3,temp6); |
---|
131 | BitBlock temp7; |
---|
132 | temp7 = simd_and(basis_bits.bit_2,basis_bits.bit_3); |
---|
133 | BitBlock temp8; |
---|
134 | temp8 = simd_and(temp1,temp7); |
---|
135 | BitBlock temp9; |
---|
136 | temp9 = simd_or(basis_bits.bit_6,basis_bits.bit_7); |
---|
137 | BitBlock temp10; |
---|
138 | temp10 = simd_or(temp4,temp9); |
---|
139 | lex.p = simd_andc(temp8,temp10); |
---|
140 | BitBlock temp11; |
---|
141 | temp11 = simd_and(basis_bits.bit_4,basis_bits.bit_5); |
---|
142 | BitBlock temp12; |
---|
143 | temp12 = simd_andc(temp11,temp9); |
---|
144 | lex.l = simd_and(temp3,temp12); |
---|
145 | BitBlock temp13; |
---|
146 | temp13 = simd_andc(basis_bits.bit_5,basis_bits.bit_4); |
---|
147 | BitBlock temp14; |
---|
148 | temp14 = simd_and(temp13,temp5); |
---|
149 | lex.e = simd_and(temp3,temp14); |
---|
150 | BitBlock temp15; |
---|
151 | temp15 = simd_or(basis_bits.bit_0,basis_bits.bit_1); |
---|
152 | BitBlock temp16; |
---|
153 | temp16 = simd_or(basis_bits.bit_2,basis_bits.bit_3); |
---|
154 | BitBlock temp17; |
---|
155 | temp17 = simd_or(temp15,temp16); |
---|
156 | BitBlock temp18; |
---|
157 | temp18 = simd_andc(basis_bits.bit_4,basis_bits.bit_5); |
---|
158 | BitBlock temp19; |
---|
159 | temp19 = simd_andc(basis_bits.bit_6,basis_bits.bit_7); |
---|
160 | BitBlock temp20; |
---|
161 | temp20 = simd_and(temp18,temp19); |
---|
162 | lex.LF = simd_andc(temp20,temp17); |
---|
163 | carry_set_0.carryAdjust(0); |
---|
164 | } |
---|
165 | |
---|
166 | IDISA_INLINE void do_final_block(struct Basis_bits & basis_bits, struct Lex & lex, BitBlock & EOF_mask) |
---|
167 | { |
---|
168 | BitBlock temp1; |
---|
169 | temp1 = simd_andc(basis_bits.bit_1,basis_bits.bit_0); |
---|
170 | BitBlock temp2; |
---|
171 | temp2 = simd_andc(basis_bits.bit_2,basis_bits.bit_3); |
---|
172 | BitBlock temp3; |
---|
173 | temp3 = simd_and(temp1,temp2); |
---|
174 | BitBlock temp4; |
---|
175 | temp4 = simd_or(basis_bits.bit_4,basis_bits.bit_5); |
---|
176 | BitBlock temp5; |
---|
177 | temp5 = simd_andc(basis_bits.bit_7,basis_bits.bit_6); |
---|
178 | BitBlock temp6; |
---|
179 | temp6 = simd_andc(temp5,temp4); |
---|
180 | lex.a = simd_and(temp3,temp6); |
---|
181 | BitBlock temp7; |
---|
182 | temp7 = simd_and(basis_bits.bit_2,basis_bits.bit_3); |
---|
183 | BitBlock temp8; |
---|
184 | temp8 = simd_and(temp1,temp7); |
---|
185 | BitBlock temp9; |
---|
186 | temp9 = simd_or(basis_bits.bit_6,basis_bits.bit_7); |
---|
187 | BitBlock temp10; |
---|
188 | temp10 = simd_or(temp4,temp9); |
---|
189 | lex.p = simd_andc(temp8,temp10); |
---|
190 | BitBlock temp11; |
---|
191 | temp11 = simd_and(basis_bits.bit_4,basis_bits.bit_5); |
---|
192 | BitBlock temp12; |
---|
193 | temp12 = simd_andc(temp11,temp9); |
---|
194 | lex.l = simd_and(temp3,temp12); |
---|
195 | BitBlock temp13; |
---|
196 | temp13 = simd_andc(basis_bits.bit_5,basis_bits.bit_4); |
---|
197 | BitBlock temp14; |
---|
198 | temp14 = simd_and(temp13,temp5); |
---|
199 | lex.e = simd_and(temp3,temp14); |
---|
200 | BitBlock temp15; |
---|
201 | temp15 = simd_or(basis_bits.bit_0,basis_bits.bit_1); |
---|
202 | BitBlock temp16; |
---|
203 | temp16 = simd_or(basis_bits.bit_2,basis_bits.bit_3); |
---|
204 | BitBlock temp17; |
---|
205 | temp17 = simd_or(temp15,temp16); |
---|
206 | BitBlock temp18; |
---|
207 | temp18 = simd_andc(basis_bits.bit_4,basis_bits.bit_5); |
---|
208 | BitBlock temp19; |
---|
209 | temp19 = simd_andc(basis_bits.bit_6,basis_bits.bit_7); |
---|
210 | BitBlock temp20; |
---|
211 | temp20 = simd_and(temp18,temp19); |
---|
212 | lex.LF = simd_andc(temp20,temp17); |
---|
213 | carry_set_0.carryAdjust(0); |
---|
214 | } |
---|
215 | |
---|
216 | IDISA_INLINE void clear() |
---|
217 | { |
---|
218 | |
---|
219 | } |
---|
220 | |
---|
221 | DeclareRuntimeInfoSet(carry_set_0, 0, 0); |
---|
222 | }; |
---|
223 | |
---|
224 | struct Match |
---|
225 | { |
---|
226 | Match() |
---|
227 | { |
---|
228 | } |
---|
229 | |
---|
230 | IDISA_INLINE void do_block(struct Lex & lex, struct Output & output) |
---|
231 | { |
---|
232 | BitBlock cursor; |
---|
233 | carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_Advance(lex.a,carry_set_0.getCarry(0),cursor)); |
---|
234 | carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(1),cursor)); |
---|
235 | carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(2),cursor)); |
---|
236 | carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.l),carry_set_0.getCarry(3),cursor)); |
---|
237 | carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.e),carry_set_0.getCarry(4),cursor)); |
---|
238 | output.match_follows = cursor; |
---|
239 | carry_set_0.carryAdjust(5); |
---|
240 | } |
---|
241 | |
---|
242 | IDISA_INLINE void do_final_block(struct Lex & lex, struct Output & output, BitBlock & EOF_mask) |
---|
243 | { |
---|
244 | BitBlock cursor; |
---|
245 | carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_Advance(lex.a,carry_set_0.getCarry(0),cursor)); |
---|
246 | carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(1),cursor)); |
---|
247 | carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(2),cursor)); |
---|
248 | carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.l),carry_set_0.getCarry(3),cursor)); |
---|
249 | carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.e),carry_set_0.getCarry(4),cursor)); |
---|
250 | output.match_follows = cursor; |
---|
251 | carry_set_0.carryAdjust(5); |
---|
252 | } |
---|
253 | |
---|
254 | IDISA_INLINE void clear() |
---|
255 | { |
---|
256 | |
---|
257 | } |
---|
258 | |
---|
259 | DeclareRuntimeInfoSet(carry_set_0, 5, 0); |
---|
260 | }; |
---|
261 | |
---|
262 | struct MatchLines |
---|
263 | { |
---|
264 | MatchLines() |
---|
265 | { |
---|
266 | carry_set_0.setCarry(carry_set_0.carryFlip(0), 0); |
---|
267 | carry_set_0.setCarry(carry_set_0.carryFlip(2), 2); |
---|
268 | } |
---|
269 | |
---|
270 | IDISA_INLINE void do_block(struct Lex & lex, struct Output & output) |
---|
271 | { |
---|
272 | BitBlock all_line_starts; |
---|
273 | BitBlock _temp0; |
---|
274 | BitBlock _temp1; |
---|
275 | carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanToFirst(simd_not(lex.LF),carry_set_0.getCarry(0),_temp0)); |
---|
276 | carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(lex.LF,carry_set_0.getCarry(1),_temp1)); |
---|
277 | all_line_starts = simd_or(_temp0,simd_andc(_temp1,lex.LF)); |
---|
278 | BitBlock all_line_ends; |
---|
279 | all_line_ends = lex.LF; |
---|
280 | BitBlock last_line_start; |
---|
281 | carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_ScanToFirst(all_line_starts,carry_set_0.getCarry(2),last_line_start)); |
---|
282 | BitBlock cursor; |
---|
283 | cursor = last_line_start; |
---|
284 | if (bitblock::any(simd_or(cursor,carry_set_0.carryRange(3,3)))) |
---|
285 | { |
---|
286 | if (bitblock::any(simd_and(cursor,all_line_starts))) |
---|
287 | { |
---|
288 | last_line_start = cursor; |
---|
289 | } |
---|
290 | if (bitblock::any(simd_or(simd_and(cursor,output.match_follows),carry_set_0.carryRange(3,2)))) |
---|
291 | { |
---|
292 | carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_not(lex.LF),carry_set_0.getCarry(3),cursor)); |
---|
293 | BitBlock _temp2; |
---|
294 | carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_0.getCarry(4),_temp2)); |
---|
295 | output.lines = simd_or(output.lines,_temp2); |
---|
296 | } |
---|
297 | else |
---|
298 | { |
---|
299 | carry_set_0.carryDequeueEnqueue(3, 2); |
---|
300 | } |
---|
301 | carry_set_0.getCarry(5) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_not(simd_or(all_line_starts,output.match_follows)),carry_set_0.getCarry(5),cursor)); |
---|
302 | while (bitblock::any(cursor)) |
---|
303 | { |
---|
304 | DeclareRuntimeInfoSet(carry_set_1, 3, 0); |
---|
305 | if (bitblock::any(simd_and(cursor,all_line_starts))) |
---|
306 | { |
---|
307 | last_line_start = cursor; |
---|
308 | } |
---|
309 | if (bitblock::any(simd_and(cursor,output.match_follows))) |
---|
310 | { |
---|
311 | carry_set_1.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_not(lex.LF),carry_set_1.getCarry(0),cursor)); |
---|
312 | BitBlock _temp2; |
---|
313 | carry_set_1.getCarry(1) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_1.getCarry(1),_temp2)); |
---|
314 | output.lines = simd_or(output.lines,_temp2); |
---|
315 | } |
---|
316 | carry_set_1.getCarry(2) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_not(simd_or(all_line_starts,output.match_follows)),carry_set_1.getCarry(2),cursor)); |
---|
317 | LocalCarryCombine(carry_set_0, carry_set_1, 3, 3); |
---|
318 | } |
---|
319 | } |
---|
320 | else |
---|
321 | { |
---|
322 | carry_set_0.carryDequeueEnqueue(3, 3); |
---|
323 | } |
---|
324 | output.line_starts = simd_and(output.lines,all_line_starts); |
---|
325 | carry_set_0.getCarry(6) = bitblock::srli<127>(pablo_blk_ScanThru(output.line_starts,simd_not(simd_and(output.lines,all_line_ends)),carry_set_0.getCarry(6),output.line_ends)); |
---|
326 | carry_set_0.carryAdjust(7); |
---|
327 | } |
---|
328 | |
---|
329 | IDISA_INLINE void do_final_block(struct Lex & lex, struct Output & output, BitBlock & EOF_mask) |
---|
330 | { |
---|
331 | BitBlock all_line_starts; |
---|
332 | BitBlock _temp0; |
---|
333 | BitBlock _temp1; |
---|
334 | carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanToFirst(simd_or(simd_not(lex.LF),simd_not(EOF_mask)),carry_set_0.getCarry(0),_temp0)); |
---|
335 | carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(lex.LF,carry_set_0.getCarry(1),_temp1)); |
---|
336 | all_line_starts = simd_or(_temp0,simd_andc(_temp1,lex.LF)); |
---|
337 | BitBlock all_line_ends; |
---|
338 | all_line_ends = lex.LF; |
---|
339 | BitBlock last_line_start; |
---|
340 | carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_ScanToFirst(simd_or(all_line_starts,simd_not(EOF_mask)),carry_set_0.getCarry(2),last_line_start)); |
---|
341 | BitBlock cursor; |
---|
342 | cursor = last_line_start; |
---|
343 | if (bitblock::any(simd_and(simd_or(simd_and(cursor,EOF_mask),carry_set_0.carryRange(3,3)),EOF_mask))) |
---|
344 | { |
---|
345 | if (bitblock::any(simd_and(cursor,all_line_starts))) |
---|
346 | { |
---|
347 | last_line_start = cursor; |
---|
348 | } |
---|
349 | if (bitblock::any(simd_or(simd_and(cursor,output.match_follows),carry_set_0.carryRange(3,2)))) |
---|
350 | { |
---|
351 | carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_andc(EOF_mask,lex.LF),carry_set_0.getCarry(3),cursor)); |
---|
352 | BitBlock _temp2; |
---|
353 | carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_0.getCarry(4),_temp2)); |
---|
354 | output.lines = simd_or(output.lines,_temp2); |
---|
355 | } |
---|
356 | else |
---|
357 | { |
---|
358 | carry_set_0.carryDequeueEnqueue(3, 2); |
---|
359 | } |
---|
360 | carry_set_0.getCarry(5) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_andc(EOF_mask,simd_or(all_line_starts,output.match_follows)),carry_set_0.getCarry(5),cursor)); |
---|
361 | while (bitblock::any(simd_and(simd_and(cursor,EOF_mask),EOF_mask))) |
---|
362 | { |
---|
363 | DeclareRuntimeInfoSet(carry_set_1, 3, 0); |
---|
364 | if (bitblock::any(simd_and(cursor,all_line_starts))) |
---|
365 | { |
---|
366 | last_line_start = cursor; |
---|
367 | } |
---|
368 | if (bitblock::any(simd_and(cursor,output.match_follows))) |
---|
369 | { |
---|
370 | carry_set_1.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_andc(EOF_mask,lex.LF),carry_set_1.getCarry(0),cursor)); |
---|
371 | BitBlock _temp2; |
---|
372 | carry_set_1.getCarry(1) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_1.getCarry(1),_temp2)); |
---|
373 | output.lines = simd_or(output.lines,_temp2); |
---|
374 | } |
---|
375 | carry_set_1.getCarry(2) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_andc(EOF_mask,simd_or(all_line_starts,output.match_follows)),carry_set_1.getCarry(2),cursor)); |
---|
376 | LocalCarryCombine(carry_set_0, carry_set_1, 3, 3); |
---|
377 | } |
---|
378 | } |
---|
379 | else |
---|
380 | { |
---|
381 | carry_set_0.carryDequeueEnqueue(3, 3); |
---|
382 | } |
---|
383 | output.line_starts = simd_and(output.lines,all_line_starts); |
---|
384 | carry_set_0.getCarry(6) = bitblock::srli<127>(pablo_blk_ScanThru(output.line_starts,simd_andc(EOF_mask,simd_and(output.lines,all_line_ends)),carry_set_0.getCarry(6),output.line_ends)); |
---|
385 | carry_set_0.carryAdjust(7); |
---|
386 | } |
---|
387 | |
---|
388 | IDISA_INLINE void clear() |
---|
389 | { |
---|
390 | carry_set_0.setCarry(carry_set_0.carryFlip(0), 0); |
---|
391 | carry_set_0.setCarry(carry_set_0.carryFlip(2), 2); |
---|
392 | } |
---|
393 | |
---|
394 | DeclareRuntimeInfoSet(carry_set_0, 7, 0); |
---|
395 | }; |
---|
396 | |
---|
397 | struct Bind |
---|
398 | { |
---|
399 | Bind() |
---|
400 | { |
---|
401 | } |
---|
402 | |
---|
403 | IDISA_INLINE void do_block() |
---|
404 | { |
---|
405 | carry_set_0.carryAdjust(0); |
---|
406 | } |
---|
407 | |
---|
408 | IDISA_INLINE void do_final_block(BitBlock & EOF_mask) |
---|
409 | { |
---|
410 | carry_set_0.carryAdjust(0); |
---|
411 | } |
---|
412 | |
---|
413 | IDISA_INLINE void clear() |
---|
414 | { |
---|
415 | |
---|
416 | } |
---|
417 | |
---|
418 | DeclareRuntimeInfoSet(carry_set_0, 0, 0); |
---|
419 | }; |
---|
420 | |
---|
421 | |
---|
422 | |
---|
423 | // S2K Bind |
---|
424 | char * buffer; |
---|
425 | BitBlock * line_starts; |
---|
426 | BitBlock * line_ends; |
---|
427 | BitBlock * match_follows; |
---|
428 | |
---|
429 | struct pipeline { |
---|
430 | |
---|
431 | public: |
---|
432 | |
---|
433 | pipeline() { } |
---|
434 | ~pipeline() { } |
---|
435 | |
---|
436 | void process() |
---|
437 | { |
---|
438 | int bytes_remaining = s2k::BUFFER_SIZE; |
---|
439 | int block_index = 0; |
---|
440 | |
---|
441 | // \s2k{} bind. |
---|
442 | char * byte_data; |
---|
443 | |
---|
444 | // Process blocks. |
---|
445 | while (bytes_remaining >= BLOCK_SIZE) { |
---|
446 | |
---|
447 | // \s2k{} bind. |
---|
448 | byte_data = &buffer[block_index * BLOCK_SIZE]; |
---|
449 | |
---|
450 | // \s2k{} 'do_block()' calls. |
---|
451 | transpose.do_block(byte_data, basis_bits); |
---|
452 | classifyBytes.do_block(basis_bits, lex); |
---|
453 | match.do_block(lex, output); |
---|
454 | matchLines.do_block(lex, output); |
---|
455 | |
---|
456 | |
---|
457 | // \s2k{} write. |
---|
458 | match_follows[block_index] = output.match_follows; |
---|
459 | line_starts[block_index] = output.line_starts; |
---|
460 | line_ends[block_index] = output.line_ends; |
---|
461 | |
---|
462 | bytes_remaining -= BLOCK_SIZE; |
---|
463 | block_index++; |
---|
464 | } |
---|
465 | |
---|
466 | // Process a partial block. |
---|
467 | BitBlock EOF_mask = bitblock::srl(simd<1>::constant<1>(), |
---|
468 | convert(BLOCK_SIZE - bytes_remaining)); |
---|
469 | |
---|
470 | // \s2k{} bind. |
---|
471 | byte_data = &buffer[block_index * BLOCK_SIZE]; |
---|
472 | |
---|
473 | // \s2k{} 'do_final_block()' calls. |
---|
474 | transpose.do_final_block(byte_data, basis_bits, EOF_mask); |
---|
475 | classifyBytes.do_final_block(basis_bits, lex, EOF_mask); |
---|
476 | match.do_final_block(lex, output, EOF_mask); |
---|
477 | matchLines.do_final_block(lex, output, EOF_mask); |
---|
478 | |
---|
479 | |
---|
480 | // \s2k{} write. |
---|
481 | match_follows[block_index] = output.match_follows & EOF_mask; |
---|
482 | line_starts[block_index] = output.line_starts & EOF_mask; |
---|
483 | line_ends[block_index] = output.line_ends & EOF_mask; |
---|
484 | } |
---|
485 | |
---|
486 | private: |
---|
487 | |
---|
488 | // S2K Generated |
---|
489 | struct Basis_bits basis_bits; |
---|
490 | struct Lex lex; |
---|
491 | struct Output output; |
---|
492 | |
---|
493 | |
---|
494 | // S2K Generated |
---|
495 | struct Bind bind; |
---|
496 | struct Transpose transpose; |
---|
497 | struct ClassifyBytes classifyBytes; |
---|
498 | struct Match match; |
---|
499 | struct MatchLines matchLines; |
---|
500 | |
---|
501 | |
---|
502 | }; |
---|
503 | |
---|
504 | struct grep { |
---|
505 | |
---|
506 | public: |
---|
507 | |
---|
508 | grep():infile(NULL), outfile(stdout), |
---|
509 | pattern_size(sizeof("apple")-1), |
---|
510 | byte_offset(0), |
---|
511 | pattern_only_matching(0), |
---|
512 | line_matching(1) { |
---|
513 | } |
---|
514 | |
---|
515 | ~grep() { |
---|
516 | destroy(); |
---|
517 | } |
---|
518 | |
---|
519 | void open_infile(char * infilename) { |
---|
520 | |
---|
521 | fdSrc = open(infilename, O_RDONLY); |
---|
522 | if (fdSrc == -1) { |
---|
523 | fprintf(stderr, "Error: cannot open %s for processing.\n", infilename); |
---|
524 | exit(-1); |
---|
525 | } |
---|
526 | |
---|
527 | if (fstat(fdSrc, &infile_sb) == -1) { |
---|
528 | fprintf(stderr, "Error: cannot stat %s for processing.\n", infilename); |
---|
529 | exit(-1); |
---|
530 | } |
---|
531 | |
---|
532 | buffer = (char *) mmap(NULL, infile_sb.st_size, PROT_READ, MAP_PRIVATE, fdSrc, 0); |
---|
533 | if (buffer == MAP_FAILED) { |
---|
534 | fprintf(stderr, "Error: mmap of %s failure.\n", infilename); |
---|
535 | exit(-1); |
---|
536 | } |
---|
537 | } |
---|
538 | |
---|
539 | void read_infile() { |
---|
540 | if((s2k::BUFFER_SIZE = infile_sb.st_size) > 0 ) { |
---|
541 | allocate(); |
---|
542 | }; |
---|
543 | } |
---|
544 | |
---|
545 | void open_outfile(char * outfilename) { |
---|
546 | outfile = fopen(outfilename, "wb"); |
---|
547 | if (!outfile) { |
---|
548 | fprintf(stderr, "Error: cannot open %s.\n", outfilename); |
---|
549 | exit(-1); |
---|
550 | } |
---|
551 | } |
---|
552 | |
---|
553 | void close_infile() { |
---|
554 | if(infile) { close(fdSrc); infile=NULL; } |
---|
555 | } |
---|
556 | |
---|
557 | void close_outfile() { |
---|
558 | if(outfile) { fclose(outfile); outfile=NULL;} |
---|
559 | } |
---|
560 | |
---|
561 | void do_byte_offset() { |
---|
562 | byte_offset = 1; |
---|
563 | } |
---|
564 | |
---|
565 | void do_line_matching() { |
---|
566 | pattern_only_matching = 0; |
---|
567 | line_matching = 1; |
---|
568 | } |
---|
569 | |
---|
570 | void do_pattern_only_matching() { |
---|
571 | pattern_only_matching = 1; |
---|
572 | line_matching = 0; |
---|
573 | } |
---|
574 | |
---|
575 | void process() { |
---|
576 | |
---|
577 | // Segment-at-a-time variables |
---|
578 | int bytes_remaining = s2k::BUFFER_SIZE; |
---|
579 | int block_index = 0; |
---|
580 | int block_base = 0; |
---|
581 | int block_count = ((bytes_remaining % BLOCK_SIZE) == 0) |
---|
582 | ? (bytes_remaining/BLOCK_SIZE) |
---|
583 | : (bytes_remaining/BLOCK_SIZE) + 1; |
---|
584 | |
---|
585 | BitBlockStreamScanner<BitBlock,ScanWord> matches_scanner; |
---|
586 | BitBlockStreamScanner<BitBlock,ScanWord> line_starts_scanner; |
---|
587 | BitBlockStreamScanner<BitBlock,ScanWord> line_ends_scanner; |
---|
588 | |
---|
589 | matches_scanner.init(match_follows, block_count); |
---|
590 | line_starts_scanner.init(line_starts, block_count); |
---|
591 | line_ends_scanner.init(line_ends, block_count); |
---|
592 | |
---|
593 | if(pattern_only_matching) { |
---|
594 | int match_offset = 0; |
---|
595 | while((match_offset = matches_scanner.scan_to_next()) > -1) { |
---|
596 | match_offset -= pattern_size; |
---|
597 | if(byte_offset) { |
---|
598 | int match_stream_offset = block_base + match_offset; |
---|
599 | fprintf(outfile, "%d:", match_stream_offset); |
---|
600 | } |
---|
601 | |
---|
602 | fwrite(&buffer[match_offset], 1, pattern_size, outfile); // lookahead |
---|
603 | fprintf(outfile, "\n"); |
---|
604 | } |
---|
605 | } |
---|
606 | |
---|
607 | if(line_matching) { |
---|
608 | int line_start_offset = 0; |
---|
609 | int line_end_offset = 0; |
---|
610 | |
---|
611 | while( ((line_start_offset = line_starts_scanner.scan_to_next()) > -1) && |
---|
612 | ((line_end_offset = line_ends_scanner.scan_to_next()) > -1)) { |
---|
613 | |
---|
614 | if(byte_offset) { |
---|
615 | fprintf(outfile, "%d:", block_base + line_start_offset, |
---|
616 | block_base + line_end_offset); |
---|
617 | } |
---|
618 | |
---|
619 | fwrite(&buffer[line_start_offset], 1, |
---|
620 | line_end_offset - line_start_offset + 1, outfile); |
---|
621 | } |
---|
622 | } |
---|
623 | } |
---|
624 | |
---|
625 | private: |
---|
626 | |
---|
627 | // helpers |
---|
628 | void allocate() { |
---|
629 | int size = (s2k::BUFFER_SIZE + BLOCK_SIZE) / BLOCK_SIZE; |
---|
630 | line_starts = simd_malloc<BitBlock>(size); |
---|
631 | line_ends = simd_malloc<BitBlock>(size); |
---|
632 | match_follows = simd_malloc<BitBlock>(size); |
---|
633 | } |
---|
634 | |
---|
635 | void destroy() { |
---|
636 | simd_free<BitBlock>(line_starts); |
---|
637 | simd_free<BitBlock>(line_ends); |
---|
638 | simd_free<BitBlock>(match_follows); |
---|
639 | } |
---|
640 | |
---|
641 | // members |
---|
642 | int fdSrc; |
---|
643 | struct stat infile_sb; |
---|
644 | FILE *infile, * outfile; |
---|
645 | |
---|
646 | int pattern_size; |
---|
647 | int byte_offset; |
---|
648 | int pattern_only_matching; |
---|
649 | int line_matching; |
---|
650 | |
---|
651 | }; |
---|
652 | |
---|
653 | int main(int argc, char * argv[]) { |
---|
654 | |
---|
655 | struct pipeline pipeline; |
---|
656 | struct grep grep; |
---|
657 | |
---|
658 | int opt_code; |
---|
659 | while ((opt_code = getopt(argc, argv, "bo?")) != -1) { |
---|
660 | switch (opt_code) { |
---|
661 | case 'b': |
---|
662 | grep.do_byte_offset(); |
---|
663 | break; |
---|
664 | case 'o': |
---|
665 | grep.do_pattern_only_matching(); |
---|
666 | break; |
---|
667 | case '?': |
---|
668 | default: |
---|
669 | printf ("Invalid option: %c\n", opt_code); |
---|
670 | printf("Usage: %s [OPTION] <inputfile> [<outputfile>]\n", argv[0]); |
---|
671 | printf("\t-b,\tprint the byte offset with output lines\n"); |
---|
672 | printf("\t-o,\tshow only the part of a line matching PATTERN\n"); |
---|
673 | printf("\t-V,\tprint version information and exit"); |
---|
674 | exit(-1); |
---|
675 | } |
---|
676 | } |
---|
677 | |
---|
678 | if (optind >= argc) { |
---|
679 | printf ("Too few arguments\n"); |
---|
680 | printf("Usage: %s [-b] [-o] <inputfile> [<outputfile>]\n", argv[0]); |
---|
681 | exit(-1); |
---|
682 | } |
---|
683 | |
---|
684 | char * infilename = argv[optind++]; |
---|
685 | grep.open_infile(infilename); |
---|
686 | |
---|
687 | if(!(optind >= argc)) { |
---|
688 | char * outfilename = argv[optind++]; |
---|
689 | grep.open_outfile(outfilename); |
---|
690 | /* |
---|
691 | if (optind != argc) { |
---|
692 | printf ("Too many arguments\n"); |
---|
693 | printf("Usage: %s [-c] [-v] <regex> <inputfile> [<outputfile>]\n", argv[0]); |
---|
694 | exit(-1); |
---|
695 | } |
---|
696 | */ |
---|
697 | } |
---|
698 | |
---|
699 | grep.read_infile(); |
---|
700 | pipeline.process(); |
---|
701 | grep.process(); |
---|
702 | grep.close_infile(); |
---|
703 | grep.close_outfile(); |
---|
704 | |
---|
705 | return 0; |
---|
706 | } |
---|