"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