"Fossies" - the Fresh Open Source Software Archive 
Member "ragel-6.10/ragel/common.h" (24 Mar 2017, 9150 Bytes) of package /linux/misc/ragel-6.10.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "common.h" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
6.9_vs_6.10.
1 /*
2 * Copyright 2001-2006 Adrian Thurston <thurston@complang.org>
3 */
4
5 /* This file is part of Ragel.
6 *
7 * Ragel is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * Ragel is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Ragel; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #ifndef _COMMON_H
23 #define _COMMON_H
24
25 #include <fstream>
26 #include <climits>
27 #include "dlist.h"
28
29 /* Location in an input file. */
30 struct InputLoc
31 {
32 const char *fileName;
33 long line;
34 long col;
35 };
36
37
38 typedef unsigned long long Size;
39
40 struct Key
41 {
42 private:
43 long key;
44
45 public:
46 friend inline Key operator+(const Key key1, const Key key2);
47 friend inline Key operator-(const Key key1, const Key key2);
48 friend inline Key operator/(const Key key1, const Key key2);
49 friend inline long operator&(const Key key1, const Key key2);
50
51 friend inline bool operator<( const Key key1, const Key key2 );
52 friend inline bool operator<=( const Key key1, const Key key2 );
53 friend inline bool operator>( const Key key1, const Key key2 );
54 friend inline bool operator>=( const Key key1, const Key key2 );
55 friend inline bool operator==( const Key key1, const Key key2 );
56 friend inline bool operator!=( const Key key1, const Key key2 );
57
58 friend struct KeyOps;
59
60 Key( ) {}
61 Key( const Key &key ) : key(key.key) {}
62 Key( long key ) : key(key) {}
63
64 /* Returns the value used to represent the key. This value must be
65 * interpreted based on signedness. */
66 long getVal() const { return key; };
67
68 /* Returns the key casted to a long long. This form of the key does not
69 * require any signedness interpretation. */
70 long long getLongLong() const;
71
72 /* Returns the distance from the key value to the maximum value that the
73 * key implementation can hold. */
74 Size availableSpace() const;
75
76 bool isUpper() const { return ( 'A' <= key && key <= 'Z' ); }
77 bool isLower() const { return ( 'a' <= key && key <= 'z' ); }
78 bool isPrintable() const
79 {
80 return ( 7 <= key && key <= 13 ) || ( 32 <= key && key < 127 );
81 }
82
83 Key toUpper() const
84 { return Key( 'A' + ( key - 'a' ) ); }
85 Key toLower() const
86 { return Key( 'a' + ( key - 'A' ) ); }
87
88 void operator+=( const Key other )
89 {
90 /* FIXME: must be made aware of isSigned. */
91 key += other.key;
92 }
93
94 void operator-=( const Key other )
95 {
96 /* FIXME: must be made aware of isSigned. */
97 key -= other.key;
98 }
99
100 void operator|=( const Key other )
101 {
102 /* FIXME: must be made aware of isSigned. */
103 key |= other.key;
104 }
105
106 /* Decrement. Needed only for ranges. */
107 inline void decrement();
108 inline void increment();
109 };
110
111 struct HostType
112 {
113 const char *data1;
114 const char *data2;
115 const char *internalName;
116 bool isSigned;
117 bool isOrd;
118 bool isChar;
119 long long sMinVal;
120 long long sMaxVal;
121 unsigned long long uMinVal;
122 unsigned long long uMaxVal;
123 unsigned int size;
124 };
125
126 struct HostLang
127 {
128 /* Target language. */
129 enum Lang
130 {
131 C, D, D2, Go, Java, Ruby, CSharp, OCaml
132 };
133
134 Lang lang;
135 HostType *hostTypes;
136 int numHostTypes;
137 HostType *defaultAlphType;
138 bool explicitUnsigned;
139 };
140
141 extern HostLang *hostLang;
142
143 extern HostLang hostLangC;
144 extern HostLang hostLangD;
145 extern HostLang hostLangD2;
146 extern HostLang hostLangGo;
147 extern HostLang hostLangJava;
148 extern HostLang hostLangRuby;
149 extern HostLang hostLangCSharp;
150 extern HostLang hostLangOCaml;
151
152 HostType *findAlphType( const char *s1 );
153 HostType *findAlphType( const char *s1, const char *s2 );
154 HostType *findAlphTypeInternal( const char *s1 );
155
156 /* An abstraction of the key operators that manages key operations such as
157 * comparison and increment according the signedness of the key. */
158 struct KeyOps
159 {
160 /* Default to signed alphabet. */
161 KeyOps() :
162 isSigned(true),
163 alphType(0)
164 {}
165
166 /* Default to signed alphabet. */
167 KeyOps( bool isSigned )
168 :isSigned(isSigned) {}
169
170 bool isSigned;
171 Key minKey, maxKey;
172 HostType *alphType;
173
174 void setAlphType( HostType *alphType )
175 {
176 this->alphType = alphType;
177 isSigned = alphType->isSigned;
178 if ( isSigned ) {
179 minKey = (long) alphType->sMinVal;
180 maxKey = (long) alphType->sMaxVal;
181 }
182 else {
183 minKey = (long) (unsigned long) alphType->uMinVal;
184 maxKey = (long) (unsigned long) alphType->uMaxVal;
185 }
186 }
187
188 /* Compute the distance between two keys. */
189 Size span( Key key1, Key key2 )
190 {
191 return isSigned ?
192 (unsigned long long)(
193 (long long)key2.key -
194 (long long)key1.key + 1) :
195 (unsigned long long)(
196 (unsigned long)key2.key) -
197 (unsigned long long)((unsigned long)key1.key) + 1;
198 }
199
200 Size alphSize()
201 { return span( minKey, maxKey ); }
202
203 HostType *typeSubsumes( long long maxVal )
204 {
205 HostType *hostTypes = hostLang->hostTypes;
206
207 for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
208 long long typeMaxVal = hostTypes[i].isSigned ? hostTypes[i].sMaxVal : hostTypes[i].uMaxVal;
209 if ( maxVal <= typeMaxVal )
210 return &hostLang->hostTypes[i];
211 }
212
213 return 0;
214 }
215
216 HostType *typeSubsumes( bool isSigned, long long maxVal )
217 {
218 HostType *hostTypes = hostLang->hostTypes;
219
220 for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
221 long long typeMaxVal = hostTypes[i].isSigned ? hostTypes[i].sMaxVal : hostTypes[i].uMaxVal;
222 if ( ( ( isSigned && hostTypes[i].isSigned ) || !isSigned ) &&
223 maxVal <= typeMaxVal )
224 return hostLang->hostTypes + i;
225 }
226 return 0;
227 }
228 };
229
230 extern KeyOps *keyOps;
231
232 inline bool operator<( const Key key1, const Key key2 )
233 {
234 return keyOps->isSigned ? key1.key < key2.key :
235 (unsigned long)key1.key < (unsigned long)key2.key;
236 }
237
238 inline bool operator<=( const Key key1, const Key key2 )
239 {
240 return keyOps->isSigned ? key1.key <= key2.key :
241 (unsigned long)key1.key <= (unsigned long)key2.key;
242 }
243
244 inline bool operator>( const Key key1, const Key key2 )
245 {
246 return keyOps->isSigned ? key1.key > key2.key :
247 (unsigned long)key1.key > (unsigned long)key2.key;
248 }
249
250 inline bool operator>=( const Key key1, const Key key2 )
251 {
252 return keyOps->isSigned ? key1.key >= key2.key :
253 (unsigned long)key1.key >= (unsigned long)key2.key;
254 }
255
256 inline bool operator==( const Key key1, const Key key2 )
257 {
258 return key1.key == key2.key;
259 }
260
261 inline bool operator!=( const Key key1, const Key key2 )
262 {
263 return key1.key != key2.key;
264 }
265
266 /* Decrement. Needed only for ranges. */
267 inline void Key::decrement()
268 {
269 key = keyOps->isSigned ? key - 1 : ((unsigned long)key)-1;
270 }
271
272 /* Increment. Needed only for ranges. */
273 inline void Key::increment()
274 {
275 key = keyOps->isSigned ? key+1 : ((unsigned long)key)+1;
276 }
277
278 inline long long Key::getLongLong() const
279 {
280 return keyOps->isSigned ? (long long)key : (long long)(unsigned long)key;
281 }
282
283 inline Size Key::availableSpace() const
284 {
285 if ( keyOps->isSigned )
286 return (long long)LONG_MAX - (long long)key;
287 else
288 return (unsigned long long)ULONG_MAX - (unsigned long long)(unsigned long)key;
289 }
290
291 inline Key operator+(const Key key1, const Key key2)
292 {
293 /* FIXME: must be made aware of isSigned. */
294 return Key( key1.key + key2.key );
295 }
296
297 inline Key operator-(const Key key1, const Key key2)
298 {
299 /* FIXME: must be made aware of isSigned. */
300 return Key( key1.key - key2.key );
301 }
302
303 inline long operator&(const Key key1, const Key key2)
304 {
305 /* FIXME: must be made aware of isSigned. */
306 return key1.key & key2.key;
307 }
308
309 inline Key operator/(const Key key1, const Key key2)
310 {
311 /* FIXME: must be made aware of isSigned. */
312 return key1.key / key2.key;
313 }
314
315 /* Filter on the output stream that keeps track of the number of lines
316 * output. */
317 class output_filter : public std::filebuf
318 {
319 public:
320 output_filter( const char *fileName ) : fileName(fileName), line(1) { }
321
322 virtual int sync();
323 virtual std::streamsize xsputn(const char* s, std::streamsize n);
324
325 const char *fileName;
326 int line;
327 };
328
329 class cfilebuf : public std::streambuf
330 {
331 public:
332 cfilebuf( char *fileName, FILE* file ) : fileName(fileName), file(file) { }
333 char *fileName;
334 FILE *file;
335
336 int sync()
337 {
338 fflush( file );
339 return 0;
340 }
341
342 int overflow( int c )
343 {
344 if ( c != EOF )
345 fputc( c, file );
346 return 0;
347 }
348
349 std::streamsize xsputn( const char* s, std::streamsize n )
350 {
351 std::streamsize written = fwrite( s, 1, n, file );
352 return written;
353 }
354 };
355
356 class costream : public std::ostream
357 {
358 public:
359 costream( cfilebuf *b ) :
360 std::ostream(b), b(b) {}
361
362 ~costream()
363 { delete b; }
364
365 void fclose()
366 { ::fclose( b->file ); }
367
368 cfilebuf *b;
369 };
370
371
372 const char *findFileExtension( const char *stemFile );
373 const char *fileNameFromStem( const char *stemFile, const char *suffix );
374
375 struct Export
376 {
377 Export( const char *name, Key key )
378 : name(name), key(key) {}
379
380 const char *name;
381 Key key;
382
383 Export *prev, *next;
384 };
385
386 typedef DList<Export> ExportList;
387
388 struct exit_object { };
389 extern exit_object endp;
390 void operator<<( std::ostream &out, exit_object & );
391
392 #endif