1 // COVTOOL -- test coverage analysis tool.
2 // Copyright (C) 2002, Lowell Boggs Jr.
3 // mailto:lowell.boggs@attbi.com
4 
5 // This file contains free software.  You can redistribute it
6 // and/or modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2, or
8 // (at your option) any later version.
9 
10 // This source code is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 
15 // Write to the Free Software Foundation, 59 Temple Place - Suite 330,
16 // Boston, MA  02111-1307, USA for a copy of the GNU General Public License.
17 //
18 
19 
20 #ifndef COVSTREAM_H_INCLUDED
21 #define COVSTREAM_H_INCLUDED
22 
23 #include <stdio.h>
24 #include <utility>  /* to get pair */
25 #include <string>
26 
27 #ifndef __hpux
28 using namespace std;
29 #endif
30 
31 class CovStream
32   //
33   // A CovStream is a source of C++ source characters including the
34   // preprocessor injected. line and file specifications.  The assumption
35   // is that a the source text has already been run CPP.  No macro processing
36   // is done.
37   //
38   // A CovStream is a linked list of blocks of text.  CovStream has
39   // an iterator that knows how to skip magically across the blocks so
40   // the caller doesn't have to know about the chunking up of the input
41   // text.  It is a forward only iterator, and refers to a location in
42   // the input stream -- which, again, is stored in ram.  Incrementing
43   // the iterator moves iterator by exactly 1 character, not a token.
44   //
45 {
46 
47   struct chunk
48   {
49      chunk *next_;
50 
51      char data_[37268];
52      char *end_;         // points into data_
53      long offset_;       // from file start
54 
chunkchunk55      chunk(): next_(0), end_(0), offset_(0) {}
56   };
57 
58   chunk *chunks_;
59 
60   long file_size_;
61 
62 public:
63 
file_size()64   long file_size() const { return file_size_; }
65 
66   struct iterator;
67 
68   friend struct iterator;
69 
70   struct iterator
71   {
72 
73     char * ptr_;
74     char * end_; // a copy of chunk_->end_ to speed up comparisons
75 
76     chunk* chunk_;
77 
78     char operator*() const { return *ptr_; }
79 
80     iterator& operator++()
81     {
82       if(ptr_ == end_)
83       {
84 	if(chunk_->next_)
85 	{
86 	  chunk_ = chunk_->next_;
87 	  ptr_   = &chunk_->data_[0];
88 	  end_   = chunk_->end_;
89 	}
90 	else
91 	{
92 	  ptr_ = 0;
93 	  end_ = 0;
94 	}
95 
96       }
97       else
98       {
99 	++ptr_;
100 
101 	if(ptr_ == end_ )
102 	{
103 
104 	  if(chunk_->next_)
105 	  {
106 	    chunk_ = chunk_->next_;
107 	    ptr_   = &chunk_->data_[0];
108 	    end_   = chunk_->end_;
109 	  }
110 	  else
111 	  {
112 	    ptr_ = 0;
113 	    end_ = 0;
114 	  }
115 	}
116 
117       }
118 
119       return *this;
120     }
121 
122     iterator operator++(int)
123     {
124       iterator old = *this;
125 
126       if(ptr_ == end_)
127       {
128 	if(chunk_->next_)
129 	{
130 	  chunk_ = chunk_->next_;
131 	  ptr_   = &chunk_->data_[0];
132 	  end_   = chunk_->end_;
133 	}
134 	else
135 	{
136 	  ptr_ = 0;
137 	  end_ = 0;
138 	}
139 
140       }
141       else
142       {
143 	++ptr_;
144 
145 	if(ptr_ == end_ )
146 	{
147 
148 	  if(chunk_->next_)
149 	  {
150 	    chunk_ = chunk_->next_;
151 	    ptr_   = &chunk_->data_[0];
152 	    end_   = chunk_->end_;
153 	  }
154 	  else
155 	  {
156 	    ptr_ = 0;
157 	    end_ = 0;
158 	  }
159 	}
160 
161       }
162 
163       return old;
164     }
165 
166     bool operator== (iterator const &r) const
167       {
168 	return ptr_ == r.ptr_;
169       }
170     bool operator!= (iterator const &r) const { return ptr_ != r.ptr_; }
171 
172 
173   };
174 
175 
begin()176   iterator begin() const
177   {
178     iterator tmp;
179 
180     if(chunks_)
181     {
182 
183       tmp.chunk_ = chunks_;
184       tmp.ptr_   = &chunks_->data_[0];
185       tmp.end_   = chunks_->end_;
186     }
187     else
188     {
189       tmp.chunk_ = 0;
190       tmp.ptr_   = 0;
191       tmp.end_   = 0;
192     }
193 
194     return tmp;
195   }
196 
end()197   iterator end() const
198   {
199     iterator tmp;
200 
201     tmp.chunk_ = 0;
202     tmp.ptr_   = 0;
203     tmp.end_   = 0;
204 
205     return tmp;
206   }
207 
208   CovStream(FILE*);   // read file into a CovStream
209 
210   ~CovStream();       // destroy and free memory
211 
212   typedef pair<iterator,iterator> token;
213 
214   static token parse_token(iterator start, iterator end);
215 					  // parse C++ tokens from start
216 					  // iterator position, returning
217 					  // iterator to 1 character past
218 					  // the token.  Won't go past
219 					  // end position.  token.first
220 					  // is begin of token, token.second
221 					  // is end of token -- the point from
222 					  // which subsequent parsing should
223 					  // continue
224 
225   static string fullname(string const &); // convert a string of the form
226 					  // "../somefile" (including '"'s)
227 					  // to the form
228 					  // "/dir/somefile".  Meaning, it
229 					  // resolves . and .. in the filename
230 					  // to the full pathanmes.
231 
232 private:
233 
234   CovStream(CovStream const &r);            // no can copy big fella ;->
235   CovStream &operator=(CovStream const &r);
236 
237 };
238 
239 
240 #endif
241