vul_awk.h
Go to the documentation of this file.
1 // This is core/vul/vul_awk.h
2 #ifndef vul_awk_h_
3 #define vul_awk_h_
4 //:
5 // \file
6 // \author Andrew W. Fitzgibbon, Oxford RRG
7 // \date 17 May 97
8 //
9 // \verbatim
10 // Modifications
11 // 970517 AWF Initial version.
12 // PDA (Manchester) 21/03/2001: Tidied up the documentation
13 // Peter Vanroose 27/05/2001: Corrected the documentation
14 // Eric Moyer 15/07/2009: Modified the documentation to reflect
15 // working strip_comments and non-working
16 // backslash_continuation
17 // \endverbatim
18 
19 
20 #include <string>
21 #include <iosfwd>
22 #include <vector>
23 #ifdef _MSC_VER
24 # include <vcl_msvc_warnings.h>
25 #endif
26 
27 //: The core of awk
28 // vul_awk reads lines from a std::istream and breaks them into whitespace-separated
29 // fields. Its primary advantage is that its name defines the semantics of
30 // its methods---except that this C++ version uses zero-based fields. The
31 // usage is exemplified in this example, to print the second field in every
32 // line:
33 // \code
34 // for (vul_awk awk=cin; awk; ++awk)
35 // std::cout << awk[2] << std::endl;
36 // \endcode
37 //
38 // The constructor takes an integer mode-flag variable. Right now,
39 // only the strip_comments flag has any effect, though the ModeFlags
40 // enumeration contains other potential flags.
41 //
42 // When the strip_comments flag is set then everything from the first
43 // '#' character to the end of the line is replaced with a single
44 // space. As a special feature, lines that contain an # as the first
45 // character are skipped entirely by the next() routine, no attempt
46 // will be made to extract fields from them. They will be counted in
47 // the line numbering so that error messages can easily refer to the
48 // correct line in the file. To extend the above example to handle
49 // comments in the file, write:
50 // \code
51 // for (vul_awk awk(cin, vul_awk::strip_comments); awk; ++awk)
52 // std::cout << awk[2] << std::endl;
53 // \endcode
54 //
55 
56 class vul_awk
57 {
58 
59  public:
60  // Constructors/Destructors--------------------------------------------------
61  enum ModeFlags {
62  none = 0x00,
63  verbose = 0x01,
66  };
67 
68  vul_awk(std::istream& s, ModeFlags mode = none);
69  ~vul_awk();
70 
71  // Operations----------------------------------------------------------------
72 
73 //: Return field i. Counting starts at 0.
74  char const* operator[] (unsigned i) const {
75  if (i < fields_.size())
76  return fields_[i];
77  else
78  return nullptr;
79  }
80 
81 //: Return the current "record number", i.e. line number
82  int NR() const { return line_number_; }
83 
84 //: Return the number of fields on this line.
85  int NF() const { return int(fields_.size()); }
86 
87 //: Return the entire line
88  char const* line() const { return (char const*)line_.c_str(); }
89 
90 //: Return the remainder of the line, starting from field_number.
91 // (0 is from the first non-whitespace character)
92  char const* line_from(int field_number) const;
93 
94 //: Return true if this line is not the last.
95  explicit operator bool () const
96  { return (!done_)? true : false; }
97 
98 //: Return false if this line is not the last.
99  bool operator!() const
100  { return done_; }
101 
102 //: Advance to the next line
103  vul_awk& operator ++ () { next(); return *this; }
104 
105 //: Display error message, line number.
106 // Also display optional field number and char within field.
107 
108  void error(std::ostream&, char const* message, int field = -1,
109  int char_within_field = 0);
110 
111  protected:
112  // Data Members--------------------------------------------------------------
113  std::istream& fd_;
114 
116 
117  // The last input line.
118  std::string line_;
119 
120  // Copy of last line with null characters at the start of every field
121  char* split_line_;
122  // Pointers to the fields within split_line_;
123  std::vector<char *> fields_;
124 
125  // May as well keep track of it...
127 
128  // Set to true when the current line is the last one.
129  bool done_;
130 
131  void next();
132 
133  vul_awk(const vul_awk& that);
134  vul_awk& operator=(const vul_awk& that);
135 };
136 
137 #endif // vul_awk_h_
char * split_line_
Definition: vul_awk.h:121
char const * operator[](unsigned i) const
Return field i. Counting starts at 0.
Definition: vul_awk.h:74
~vul_awk()
Definition: vul_awk.cxx:35
int NR() const
Return the current "record number", i.e. line number.
Definition: vul_awk.h:82
std::istream & fd_
Definition: vul_awk.h:113
std::string line_
Definition: vul_awk.h:118
int line_number_
Definition: vul_awk.h:126
char const * line() const
Return the entire line.
Definition: vul_awk.h:88
std::vector< char * > fields_
Definition: vul_awk.h:123
vul_awk(std::istream &s, ModeFlags mode=none)
Construct from input stream.
Definition: vul_awk.cxx:24
void error(std::ostream &, char const *message, int field=-1, int char_within_field=0)
Display error message, line number.
bool operator!() const
Return false if this line is not the last.
Definition: vul_awk.h:99
The core of awk.
Definition: vul_awk.h:56
bool done_
Definition: vul_awk.h:129
int NF() const
Return the number of fields on this line.
Definition: vul_awk.h:85
char const * line_from(int field_number) const
Return the remainder of the line, starting from field_number.
Definition: vul_awk.cxx:123
ModeFlags
Definition: vul_awk.h:61
vul_awk & operator=(const vul_awk &that)
ModeFlags mode_
Definition: vul_awk.h:115
vul_awk & operator++()
Advance to the next line.
Definition: vul_awk.h:103
void next()
Definition: vul_awk.cxx:40