Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/regex/example/grep/grep.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 6.7 KB
Line 
1/*
2 *
3 * Copyright (c) 2004
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12#include <iostream>
13#include <fstream>
14#include <string>
15#include <vector>
16#include <boost/program_options.hpp>
17#include <boost/regex.hpp>
18
19namespace po = boost::program_options;
20
21int after_context;
22int before_context;
23bool print_byte_offset;
24bool count_only;
25std::string pattern;
26bool print_non_matching_files;
27bool files_only;
28bool print_line_numbers;
29
30boost::regex_constants::syntax_option_type flags = boost::regex_constants::basic;
31boost::regex re;
32boost::smatch what;
33std::string current_file;
34int file_count;
35
36void process_stream(std::istream& is)
37{
38   std::string line;
39   int match_found = 0;
40   int linenum = 1;
41   while(std::getline(is, line))
42   {
43      bool result = boost::regex_search(line, what, re);
44      if(result)
45      {
46         if(print_non_matching_files)
47            return;
48         if(files_only)
49         {
50            std::cout << current_file << std::endl;
51            return;
52         }
53         if(!match_found && !count_only && (file_count > 1))
54         {
55            std::cout << current_file << ":\n";
56         }
57         ++match_found;
58         if(!count_only)
59         {
60            if(print_line_numbers)
61            {
62               std::cout << linenum << ":";
63            }
64            if(print_byte_offset)
65            {
66               std::cout << what.position() << ":";
67            }
68            std::cout << what[0] << std::endl;
69         }
70      }
71      ++linenum;
72   }
73   if(count_only && match_found)
74   {
75      std::cout << match_found << " matches found in file " << current_file << std::endl;
76   }
77   else if(print_non_matching_files && !match_found)
78   {
79      std::cout << current_file << std::endl;
80   }
81}
82
83void process_file(const std::string& name)
84{
85   current_file = name;
86   std::ifstream is(name.c_str());
87   if(is.bad())
88   {
89      std::cerr << "Unable to open file " << name << std::endl;
90   }
91   process_stream(is);
92}
93
94int main(int argc, char * argv[])
95{
96   try{
97      po::options_description opts("Options");
98      opts.add_options()
99         ("help,h", "produce help message") 
100         //("after-context,A", po::value<int>(&after_context)->default_value(0), "Print arg  lines  of  trailing  context  after  matching  lines. Places  a  line  containing  --  between  contiguous  groups  of matches.")
101         //("before-context,B", po::value<int>(&before_context)->default_value(0), "Print  arg  lines  of  leading  context  before  matching lines. Places  a  line  containing  --  between  contiguous  groups  of matches.")
102         //("context,C", po::value<int>(), "Print  arg lines of output context.  Places a line containing -- between contiguous groups of matches.")
103         ("byte-offset,b", "Print the byte offset within the input file before each line  of output.")
104         ("count,c", "Suppress normal output; instead print a count of matching  lines for  each  input  file.  With the -v, --invert-match option (see below), count non-matching lines.")
105         ("extended-regexp,E", "Interpret PATTERN as an POSIX-extended regular expression.")
106         ("perl-regexp,P", "Interpret PATTERN as a Perl regular expression.")
107         //("regexp,e", po::value<std::string>(&pattern), "Use PATTERN as the pattern; useful to protect patterns beginning with -.")
108         ("basic-regexp,G", "Interpret arg as a POSIX-basic regular expression (see below).  This is the default.")
109         ("ignore-case,i", "Ignore case distinctions in  both  the  PATTERN  and  the  input files.")
110         ("files-without-match,L", "Suppress  normal  output;  instead  print the name of each input file from which no output would normally have been printed.  The scanning will stop on the first match.")
111         ("files-with-matches,l", "Suppress  normal  output;  instead  print the name of each input file from which output would normally have  been  printed.   The scanning will stop on the first match.")
112         ("line-number,n", "Prefix each line of output with the line number within its input file.")
113         ;
114      // Hidden options, will be allowed both on command line and
115      // in config file, but will not be shown to the user.
116      po::options_description hidden("Hidden options");
117      hidden.add_options()
118         ("input-file", po::value< std::vector<std::string> >(), "input file")
119         ("input-pattern", po::value< std::string >(), "input file")
120         ;
121
122      po::options_description cmdline_options;
123      cmdline_options.add(opts).add(hidden);
124
125      po::positional_options_description p;
126      p.add("input-pattern", 1);
127      p.add("input-file", -1);
128
129      po::variables_map vm;
130      po::store(po::command_line_parser(argc, argv).options(cmdline_options)/*.options(hidden)*/.positional(p).run(), vm);
131      po::notify(vm);
132
133      if (vm.count("help")) 
134      {
135         std::cout << opts << "\n";
136         return 0;
137      }
138      if (vm.count("context")) 
139      {
140         after_context = vm["context"].as< int >();
141         before_context = after_context;
142      }
143      if(vm.count("extended-regexp"))
144      {
145         flags = boost::regex_constants::extended;
146      }
147      if(vm.count("basic-regexp"))
148      {
149         flags = boost::regex_constants::basic;
150      }
151      if(vm.count("perl-regexp"))
152      {
153         flags = boost::regex_constants::perl;
154      }
155      if(vm.count("ignore-case"))
156      {
157         flags |= boost::regex_constants::icase;
158      }
159      if(vm.count("byte-offset"))
160      {
161         print_byte_offset = true;
162      }
163      if(vm.count("count"))
164      {
165         count_only = true;
166      }
167      if(vm.count("files-without-match"))
168      {
169         print_non_matching_files = true;
170      }
171      if(vm.count("files-with-matches"))
172      {
173         files_only = true;
174      }
175      if(vm.count("line-number"))
176      {
177         print_line_numbers = true;
178      }
179      if(vm.count("input-pattern"))
180      {
181         pattern = vm["input-pattern"].as< std::string >();
182         re.assign(pattern, flags);
183      }
184      else
185      {
186         std::cerr << "No pattern specified" << std::endl;
187         return 1;
188      }
189      if (vm.count("input-file"))
190      {
191         const std::vector<std::string>& files = vm["input-file"].as< std::vector<std::string> >();
192         file_count = files.size();
193         for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i)
194         {
195            process_file(*i);
196         }
197      }
198      else
199      {
200         // no input files, scan stdin instead:
201         process_stream(std::cin);
202      }
203
204   }
205   catch(const std::exception& e)
206   {
207      std::cerr << e.what() << std::endl;
208   }
209
210   return 0;
211}
212
Note: See TracBrowser for help on using the repository browser.