vul_awk.cxx
Go to the documentation of this file.
1 // This is core/vul/vul_awk.cxx
2 //:
3 // \file
4 // \author Andrew W. Fitzgibbon, Oxford RRG
5 // \date 17 May 1997
6 // \verbatim
7 // Modifications
8 // AWF (Oxford) 17 May 1997: Initial version.
9 // Eric Moyer 15 Jul 2009: Added strip comment functionality
10 // \endverbatim
11 //
12 //-----------------------------------------------------------------------------
13 
14 #include <cctype>
15 #include <cstring>
16 #include <iostream>
17 #include <cstdio>
18 #include "vul_awk.h"
19 
20 #ifdef _MSC_VER
21 # include <vcl_msvc_warnings.h>
22 #endif
23 
24 //: Construct from input stream
25 vul_awk::vul_awk(std::istream& s, ModeFlags mode):
26  fd_(s),
27  mode_(mode)
28 {
29  done_ = false;
30  line_number_ = 0;
31  split_line_ = nullptr;
32 
33  next();
34 }
35 
37 {
38  delete [] split_line_;
39 }
40 
41 void vul_awk::next()
42 {
43  bool do_strip_comments = ( ((int)mode_) & ((int)strip_comments) ) != 0;
44 #if 0
45  bool do_backslash_continuations = (int(mode_) & int(backslash_continuations)) != 0;
46 #endif
47  bool discard_current_line = true;
48  while (discard_current_line)
49  {
50  bool extract_fields = true;
51  discard_current_line = false;
52 
53  // Read line -- should be quite fast after the first one.
54  line_.erase();
55 
56  while (true) {
57  int c = fd_.get();
58  if (c == EOF || fd_.eof()) {
59  done_ = true;
60  break;
61  }
62  if (c == '\n')
63  break;
64  line_ += char(c);
65  }
66 
67  char const* linep = line_.c_str();
68 
69  // copy string
70  delete [] split_line_;
71  split_line_ = new char[line_.size() + 1];
72  std::strcpy(split_line_, linep);
73 
74  //strip comments
75  if (do_strip_comments) {
76  //find the first # character
77  char* comment_char = split_line_;
78  while (*comment_char != '#' && *comment_char != '\0') ++comment_char;
79  //replace the # with a single space and terminate the string. I
80  //use a single space since that will help the backslash
81  //continuation if it is ever implemented
82  if (*comment_char == '#') {
83  //Replace with a space
84  *comment_char = ' '; ++comment_char;
85  //Terminate the string
86  if (*comment_char != '\0') { *comment_char = '\0'; }
87  if (comment_char - split_line_ == 1) {
88  //The line was only a comment -- don't try to extract
89  //records, just discard the current line and go to the next
90  extract_fields = false;
91  discard_current_line = true;
92  }
93  }
94  }
95 
96  if (extract_fields) {
97  // Chop line up into fields
98  fields_.clear();
99  char* cp = split_line_;
100 
101  while (true) {
102  // Eat white
103  while (*cp && std::isspace(*cp))
104  ++cp;
105  if (!*cp) break;
106 
107  // Push
108  fields_.push_back(cp);
109 
110  // Find nonwhite
111  while (*cp && !std::isspace(*cp))
112  ++cp;
113  if (!*cp) break;
114 
115  // Zap space
116  *cp++ = '\0';
117  }
118  }
119  // Increment line number
120  ++line_number_;
121  }
122 }
124 char const* vul_awk::line_from(int field_number) const
125 {
126  char const *p = line_.c_str();
127  if (field_number >= NF())
128  field_number = NF() - 1;
129  if (field_number < 0) {
130  std::cerr << "vul_awk::line_from("<< field_number <<") -- ZOIKS\n";
131  return line();
132  }
133 
134  return p + (fields_[field_number] - split_line_);
135 }
137 void testvul_awk()
138 {
139  std::cout << "Start\n";
140  for (vul_awk awk(std::cin); awk; ++awk) {
141  std::cout << awk.NF() << ':' << awk[2] << std::endl;
142  }
143 }
char * split_line_
Definition: vul_awk.h:121
~vul_awk()
Definition: vul_awk.cxx:35
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 testvul_awk()
Definition: vul_awk.cxx:136
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
ModeFlags mode_
Definition: vul_awk.h:115
void next()
Definition: vul_awk.cxx:40