sheepy

build system (sheepy) and package manager (spm) for C
git clone https://spartatek.se/git/sheepy.git
Log | Files | Refs | README | LICENSE

Accumulator.i (7066B)


      1 /* -*- C++ -*- vim:set syntax=cpp:
      2  *
      3  * (C) 2005-2009 Frank-Rene Schaefer
      4  *
      5  * __QUEX_INCLUDE_GUARD__ANALYZER__ACCUMULATOR may be undefined in case
      6  *    that multiple lexical analyzers are used. Then, the name of the
      7  *    QUEX_NAME(Accumulator) must be different.                             */
      8 #ifndef __QUEX_INCLUDE_GUARD__ANALYZER__ACCUMULATOR_I
      9 #define __QUEX_INCLUDE_GUARD__ANALYZER__ACCUMULATOR_I
     10 
     11 #include "definitions"
     12 #include "Accumulator"
     13 #include "MemoryManager"
     14 #include "TokenPolicy"
     15 
     16 QUEX_NAMESPACE_MAIN_OPEN
     17 
     18 QUEX_INLINE void
     19 QUEX_NAME(Accumulator_construct)(QUEX_NAME(Accumulator)*   me, 
     20                                  QUEX_TYPE_ANALYZER*       lexer)
     21 {
     22     me->the_lexer = lexer;
     23     QUEX_NAME(Accumulator_init_memory)(me);
     24     __QUEX_IF_COUNT_LINES(me->_begin_line = 0);
     25     __QUEX_IF_COUNT_COLUMNS(me->_begin_column = 0);
     26 }
     27 
     28 
     29 QUEX_INLINE void
     30 QUEX_NAME(Accumulator_destruct)(QUEX_NAME(Accumulator)* me)
     31 {
     32     if( me->text.begin ) {
     33         QUEXED(MemoryManager_free)((void*)me->text.begin,
     34                                    E_MemoryObjectType_TEXT);
     35     }
     36     me->the_lexer       = 0x0;
     37     me->text.begin      = 0x0;
     38     me->text.end        = 0x0;
     39     me->text.memory_end = 0x0;
     40 }
     41 
     42 QUEX_INLINE void
     43 QUEX_NAME(Accumulator_init_memory)(QUEX_NAME(Accumulator)*   me) 
     44 {
     45     if( QUEX_SETTING_ACCUMULATOR_INITIAL_SIZE == 0 ) {
     46         me->text.begin = 0x0;
     47     } 
     48     else {
     49         me->text.begin = \
     50             (QUEX_TYPE_LEXATOM*)
     51             QUEXED(MemoryManager_allocate)(
     52                       QUEX_SETTING_ACCUMULATOR_INITIAL_SIZE * sizeof(QUEX_TYPE_LEXATOM),
     53                       E_MemoryObjectType_TEXT);
     54         if( ! me->text.begin ) {
     55             QUEX_ERROR_EXIT("Quex engine: out of memory--cannot allocate Accumulator.");
     56         }
     57     }
     58     me->text.end        = me->text.begin;
     59     me->text.memory_end = me->text.begin + QUEX_SETTING_ACCUMULATOR_INITIAL_SIZE;
     60 }
     61 
     62 QUEX_INLINE bool
     63 QUEX_NAME(Accumulator_extend)(QUEX_NAME(Accumulator)* me, size_t MinAddSize)
     64 {
     65     const size_t  OldContentSize = (size_t)(me->text.end - me->text.begin);
     66     const size_t  Size    = (size_t)(me->text.memory_end - me->text.begin);
     67     const size_t  AddSize = (size_t)((float)Size * (float)QUEX_SETTING_ACCUMULATOR_GRANULARITY_FACTOR);
     68     const size_t  NewSize = Size + (AddSize < MinAddSize ? MinAddSize : AddSize);
     69 
     70     QUEX_TYPE_LEXATOM*  chunk = \
     71           (QUEX_TYPE_LEXATOM*)
     72           QUEXED(MemoryManager_allocate)(NewSize*sizeof(QUEX_TYPE_LEXATOM),
     73                                          E_MemoryObjectType_TEXT);
     74 
     75     if( chunk == 0x0 ) return false;
     76 
     77     __quex_assert(me->text.end >= me->text.begin);
     78     __quex_assert(me->text.memory_end >= me->text.begin);
     79 
     80     __QUEX_STD_memcpy(chunk, me->text.begin, sizeof(QUEX_TYPE_LEXATOM) * Size);
     81 
     82     QUEXED(MemoryManager_free)((void*)me->text.begin, E_MemoryObjectType_TEXT);
     83 
     84     me->text.begin      = chunk;
     85     me->text.end        = chunk + OldContentSize;
     86     me->text.memory_end = chunk + NewSize;
     87     return true;
     88 }
     89 
     90 QUEX_INLINE void
     91 QUEX_NAME(Accumulator_clear)(QUEX_NAME(Accumulator)* me)
     92 {
     93     /* If no text is to be flushed, return undone */
     94     if( me->text.begin == me->text.end ) return;
     95     me->text.end = me->text.begin;
     96 }
     97 
     98 QUEX_INLINE void 
     99 QUEX_NAME(Accumulator_add)(QUEX_NAME(Accumulator)* me,
    100                            const QUEX_TYPE_LEXATOM* Begin, const QUEX_TYPE_LEXATOM* End)
    101 { 
    102     const size_t L = (size_t)(End - Begin);
    103     __quex_assert(End > Begin);
    104 
    105     /* If it is the first string to be appended, the store the location */
    106 #   ifdef __QUEX_OPTION_COUNTER
    107     if( me->text.begin == me->text.end ) {
    108         __QUEX_IF_COUNT_COLUMNS(me->_begin_column = me->the_lexer->counter._column_number_at_begin);
    109         __QUEX_IF_COUNT_LINES(me->_begin_line     = me->the_lexer->counter._line_number_at_begin);
    110     }
    111 #   endif
    112 
    113     /* Ensure, that there is one more cell between end and .memory_end to store
    114      * the terminating zero for flushing or printing.                           */
    115     if( me->text.memory_end <= me->text.end + L ) {
    116         /* L + 1 we need space for the string + the terminating zero */
    117         if( QUEX_NAME(Accumulator_extend)(me, L + 1) == false ) {
    118             QUEX_ERROR_EXIT("Quex Engine: Out of Memory. Accumulator could not be further extended.\n");
    119         }
    120     }
    121 
    122     __QUEX_STD_memcpy(me->text.end, Begin, L * sizeof(QUEX_TYPE_LEXATOM));
    123     me->text.end += L;
    124 }
    125 
    126 
    127 QUEX_INLINE void 
    128 QUEX_NAME(Accumulator_add_character)(QUEX_NAME(Accumulator)*     me,
    129                                      const QUEX_TYPE_LEXATOM  Character)
    130 { 
    131     /* If it is the first string to be appended, the store the location */
    132 #   ifdef __QUEX_OPTION_COUNTER
    133     if( me->text.begin == me->text.end ) {
    134         __QUEX_IF_COUNT_COLUMNS(me->_begin_column = me->the_lexer->counter._column_number_at_begin);
    135         __QUEX_IF_COUNT_LINES(me->_begin_line     = me->the_lexer->counter._line_number_at_begin);
    136     }
    137 #   endif
    138 
    139     /* Ensure, that there is one more cell between end and .memory_end to store
    140      * the terminating zero for flushing or printing.                           */
    141     if( me->text.memory_end <= me->text.end + 1 ) {
    142         /* 1 + 1 we need space for the character + the terminating zero */
    143         if( QUEX_NAME(Accumulator_extend)(me, 2) == false ) {
    144             QUEX_ERROR_EXIT("Quex Engine: Out of Memory. Accumulator could not be further extended.\n");
    145         }
    146     }
    147 
    148     *(me->text.end) = Character;
    149     ++(me->text.end);
    150 }
    151 
    152 #if 0
    153 QUEX_INLINE void
    154 QUEX_NAME(Accumulator_flush)(QUEX_NAME(Accumulator)*    me,
    155                              const QUEX_TYPE_TOKEN_ID  TokenID)
    156 {
    157     /* All functions must ensure that there is one cell left to store the terminating zero. */
    158     __quex_assert(me->text.end < me->text.memory_end);
    159 
    160 
    161     /* If no text is to be flushed, return undone */
    162     if( me->text.begin == me->text.end ) return;
    163 
    164     *(me->text.end) = (QUEX_TYPE_LEXATOM)0; /* see above '__quex_assert()' */
    165 
    166 #   define self (*me->the_lexer)
    167     self_token_set_id(TokenID);
    168     if( QUEX_NAME_TOKEN(take_text)(__QUEX_CURRENT_TOKEN_P, 
    169                                    me->the_lexer, 
    170                                    me->text.begin, 
    171                                    me->text.end) == false ) {
    172         /* The called function does not need the memory chunk, we reuse it. */
    173         QUEX_NAME(Accumulator_clear)(me);
    174     } else {
    175         /* The called function wants to use the memory, so we get some new. */
    176         QUEX_NAME(Accumulator_init_memory)(me);
    177     }
    178     QUEX_TOKEN_POLICY_PREPARE_NEXT();            
    179 #   undef  self
    180 }
    181 #endif
    182 
    183 QUEX_INLINE void  
    184 QUEX_NAME(Accumulator_print_this)(QUEX_NAME(Accumulator)* me)
    185 {
    186     /* All functions must ensure that there is one cell left to store the terminating zero. */
    187     __quex_assert(me->text.end < me->text.memory_end);
    188 
    189     *(me->text.end) = (QUEX_TYPE_LEXATOM)0; /* see above '__quex_assert()' */
    190 
    191     __QUEX_STD_printf("   Accumulator = '%s'\n", (const char*)me->text.begin);
    192 }
    193 
    194 QUEX_NAMESPACE_MAIN_CLOSE
    195 
    196 #endif /* __QUEX_INCLUDE_GUARD__ANALYZER__ACCUMULATOR_I */