source: proto/s2k/trunk/demo/grep/src/grep.cpp @ 4054

Last change on this file since 4054 was 4054, checked in by ksherdy, 5 years ago

Added example s2k output file.

File size: 20.6 KB
Line 
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>
90using namespace std;
91
92// S2K Generated
93struct Lex
94{
95        BitBlock a;
96        BitBlock p;
97        BitBlock l;
98        BitBlock e;
99        BitBlock LF;
100};
101 
102struct Output
103{
104        BitBlock match_follows;
105        BitBlock lines;
106        BitBlock line_starts;
107        BitBlock line_ends;
108};
109 
110struct 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 
224struct 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 
262struct 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 
397struct 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
424char * buffer;
425BitBlock * line_starts;
426BitBlock * line_ends;
427BitBlock * match_follows;
428
429struct 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);
452classifyBytes.do_block(basis_bits, lex);
453match.do_block(lex, output);
454matchLines.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);
475classifyBytes.do_final_block(basis_bits, lex, EOF_mask);
476match.do_final_block(lex, output, EOF_mask);
477matchLines.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
489struct Basis_bits basis_bits;
490struct Lex lex;
491struct Output output;
492
493
494// S2K Generated
495struct Bind bind;
496struct Transpose transpose;
497struct ClassifyBytes classifyBytes;
498struct Match match;
499struct MatchLines matchLines;
500   
501
502};
503
504struct 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
653int 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}
Note: See TracBrowser for help on using the repository browser.