Include the root in the include history.
[ragel.git] / common / common.h
blobce06028f1eec12692fff0e4f8b98e32fbc43fbb3
1 /*
2 * Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
3 */
5 /* This file is part of Ragel.
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.
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.
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
22 #ifndef _COMMON_H
23 #define _COMMON_H
25 #include <fstream>
26 #include <climits>
27 #include "dlist.h"
29 typedef unsigned long long Size;
31 struct Key
33 private:
34 long key;
36 public:
37 friend inline Key operator+(const Key key1, const Key key2);
38 friend inline Key operator-(const Key key1, const Key key2);
39 friend inline Key operator/(const Key key1, const Key key2);
40 friend inline long operator&(const Key key1, const Key key2);
42 friend inline bool operator<( const Key key1, const Key key2 );
43 friend inline bool operator<=( const Key key1, const Key key2 );
44 friend inline bool operator>( const Key key1, const Key key2 );
45 friend inline bool operator>=( const Key key1, const Key key2 );
46 friend inline bool operator==( const Key key1, const Key key2 );
47 friend inline bool operator!=( const Key key1, const Key key2 );
49 friend struct KeyOps;
51 Key( ) {}
52 Key( const Key &key ) : key(key.key) {}
53 Key( long key ) : key(key) {}
55 /* Returns the value used to represent the key. This value must be
56 * interpreted based on signedness. */
57 long getVal() const { return key; };
59 /* Returns the key casted to a long long. This form of the key does not
60 * require any signedness interpretation. */
61 long long getLongLong() const;
63 /* Returns the distance from the key value to the maximum value that the
64 * key implementation can hold. */
65 Size availableSpace() const;
67 bool isUpper() const { return ( 'A' <= key && key <= 'Z' ); }
68 bool isLower() const { return ( 'a' <= key && key <= 'z' ); }
69 bool isPrintable() const
71 return ( 7 <= key && key <= 13 ) || ( 32 <= key && key < 127 );
74 Key toUpper() const
75 { return Key( 'A' + ( key - 'a' ) ); }
76 Key toLower() const
77 { return Key( 'a' + ( key - 'A' ) ); }
79 void operator+=( const Key other )
81 /* FIXME: must be made aware of isSigned. */
82 key += other.key;
85 void operator-=( const Key other )
87 /* FIXME: must be made aware of isSigned. */
88 key -= other.key;
91 void operator|=( const Key other )
93 /* FIXME: must be made aware of isSigned. */
94 key |= other.key;
97 /* Decrement. Needed only for ranges. */
98 inline void decrement();
99 inline void increment();
102 struct HostType
104 const char *data1;
105 const char *data2;
106 const char *internalName;
107 bool isSigned;
108 long long minVal;
109 long long maxVal;
110 unsigned int size;
113 struct HostLang
115 /* Target language. */
116 enum Lang
118 C, D, Java, Ruby, CSharp
121 Lang lang;
122 HostType *hostTypes;
123 int numHostTypes;
124 HostType *defaultAlphType;
125 bool explicitUnsigned;
128 extern HostLang *hostLang;
130 extern HostLang hostLangC;
131 extern HostLang hostLangD;
132 extern HostLang hostLangJava;
133 extern HostLang hostLangRuby;
134 extern HostLang hostLangCSharp;
136 HostType *findAlphType( char *s1 );
137 HostType *findAlphType( char *s1, char *s2 );
138 HostType *findAlphTypeInternal( char *s1 );
140 /* An abstraction of the key operators that manages key operations such as
141 * comparison and increment according the signedness of the key. */
142 struct KeyOps
144 /* Default to signed alphabet. */
145 KeyOps() :
146 isSigned(true),
147 alphType(0)
150 /* Default to signed alphabet. */
151 KeyOps( bool isSigned )
152 :isSigned(isSigned) {}
154 bool isSigned;
155 Key minKey, maxKey;
156 HostType *alphType;
158 void setAlphType( HostType *alphType )
160 this->alphType = alphType;
161 isSigned = alphType->isSigned;
162 if ( isSigned ) {
163 minKey = (long) alphType->minVal;
164 maxKey = (long) alphType->maxVal;
166 else {
167 minKey = (long) (unsigned long) alphType->minVal;
168 maxKey = (long) (unsigned long) alphType->maxVal;
172 /* Compute the distance between two keys. */
173 Size span( Key key1, Key key2 )
175 return isSigned ?
176 (unsigned long long)(
177 (long long)key2.key -
178 (long long)key1.key + 1) :
179 (unsigned long long)(
180 (unsigned long)key2.key) -
181 (unsigned long long)((unsigned long)key1.key) + 1;
184 Size alphSize()
185 { return span( minKey, maxKey ); }
187 HostType *typeSubsumes( long long maxVal )
189 for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
190 if ( maxVal <= hostLang->hostTypes[i].maxVal )
191 return hostLang->hostTypes + i;
193 return 0;
196 HostType *typeSubsumes( bool isSigned, long long maxVal )
198 for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
199 if ( ( ( isSigned && hostLang->hostTypes[i].isSigned ) || !isSigned ) &&
200 maxVal <= hostLang->hostTypes[i].maxVal )
201 return hostLang->hostTypes + i;
203 return 0;
207 extern KeyOps *keyOps;
209 inline bool operator<( const Key key1, const Key key2 )
211 return keyOps->isSigned ? key1.key < key2.key :
212 (unsigned long)key1.key < (unsigned long)key2.key;
215 inline bool operator<=( const Key key1, const Key key2 )
217 return keyOps->isSigned ? key1.key <= key2.key :
218 (unsigned long)key1.key <= (unsigned long)key2.key;
221 inline bool operator>( const Key key1, const Key key2 )
223 return keyOps->isSigned ? key1.key > key2.key :
224 (unsigned long)key1.key > (unsigned long)key2.key;
227 inline bool operator>=( const Key key1, const Key key2 )
229 return keyOps->isSigned ? key1.key >= key2.key :
230 (unsigned long)key1.key >= (unsigned long)key2.key;
233 inline bool operator==( const Key key1, const Key key2 )
235 return key1.key == key2.key;
238 inline bool operator!=( const Key key1, const Key key2 )
240 return key1.key != key2.key;
243 /* Decrement. Needed only for ranges. */
244 inline void Key::decrement()
246 key = keyOps->isSigned ? key - 1 : ((unsigned long)key)-1;
249 /* Increment. Needed only for ranges. */
250 inline void Key::increment()
252 key = keyOps->isSigned ? key+1 : ((unsigned long)key)+1;
255 inline long long Key::getLongLong() const
257 return keyOps->isSigned ? (long long)key : (long long)(unsigned long)key;
260 inline Size Key::availableSpace() const
262 if ( keyOps->isSigned )
263 return (long long)LONG_MAX - (long long)key;
264 else
265 return (unsigned long long)ULONG_MAX - (unsigned long long)(unsigned long)key;
268 inline Key operator+(const Key key1, const Key key2)
270 /* FIXME: must be made aware of isSigned. */
271 return Key( key1.key + key2.key );
274 inline Key operator-(const Key key1, const Key key2)
276 /* FIXME: must be made aware of isSigned. */
277 return Key( key1.key - key2.key );
280 inline long operator&(const Key key1, const Key key2)
282 /* FIXME: must be made aware of isSigned. */
283 return key1.key & key2.key;
286 inline Key operator/(const Key key1, const Key key2)
288 /* FIXME: must be made aware of isSigned. */
289 return key1.key / key2.key;
292 /* Filter on the output stream that keeps track of the number of lines
293 * output. */
294 class output_filter : public std::filebuf
296 public:
297 output_filter( char *fileName ) : fileName(fileName), line(1) { }
299 virtual int sync();
300 virtual std::streamsize xsputn(const char* s, std::streamsize n);
302 char *fileName;
303 int line;
306 class cfilebuf : public std::streambuf
308 public:
309 cfilebuf( char *fileName, FILE* file ) : fileName(fileName), file(file) { }
310 char *fileName;
311 FILE *file;
313 int sync()
315 fflush( file );
316 return 0;
319 int overflow( int c )
321 if ( c != EOF )
322 fputc( c, file );
323 return 0;
326 std::streamsize xsputn( const char* s, std::streamsize n )
328 std::streamsize written = fwrite( s, 1, n, file );
329 return written;
333 class costream : public std::ostream
335 public:
336 costream( cfilebuf *b ) :
337 std::ostream(b), b(b) {}
339 ~costream()
340 { delete b; }
342 void fclose()
343 { ::fclose( b->file ); }
345 cfilebuf *b;
349 char *findFileExtension( char *stemFile );
350 char *fileNameFromStem( char *stemFile, const char *suffix );
352 struct Export
354 Export( const char *name, Key key )
355 : name(name), key(key) {}
357 const char *name;
358 Key key;
360 Export *prev, *next;
363 typedef DList<Export> ExportList;
365 struct exit_object { };
366 extern exit_object endp;
367 void operator<<( std::ostream &out, exit_object & );
369 #endif /* _COMMON_H */