sheepy

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

Buffer_navigation.i (7961B)


      1 /* vim: set ft=c:
      2  * 
      3  * PURPOSE: Buffer's seek: 
      4  *  
      5  *    .---------------------------------------------------------------.
      6  *    |  Setting the '_read_p' to a specific position in the stream.  |
      7  *    '---------------------------------------------------------------'
      8  *
      9  * This is the type of 'seek' used in the user interface's seek functions.
     10  *
     11  * NOT TO CONFUSE with two other forms of seek:
     12  *
     13  *    -- LexatomLoader's seek sets the input position of the next 
     14  *       lexatom to be loaded into the buffer.
     15  *    -- QUEX_NAME(ByteLoader)'s seek sets the position in the low level input
     16  *       stream.
     17  *
     18  * A 'seek' always implies that the following happens:
     19  *
     20  *                      _lexeme_start_p = _read_p  
     21  * 
     22  * The two stored lexatoms will be assigned after seeking as
     23  *
     24  *       _lexatom_at_lexeme_start     = _read_p[0]
     25  *       _lexatom_before_lexeme_start = _read_p[-1]
     26  * 
     27  * If the read pointer stands at the beginning of the file, then
     28  *
     29  *       _lexatom_before_lexeme_start = newline
     30  *
     31  * It is crucial to understand the difference between 'stream seeking' and 
     32  * 'buffer seeking'. Stream seeking determines the next position in the input
     33  * stream from where content is loaded into the buffer. Buffer seeking sets
     34  * the input pointer '_read_p' to a particular position. The position-1 where 
     35  * it points contains the next lexatom to be read during analysis.           
     36  *
     37  * (C) Frank-Rene Schaefer                                                   */
     38 #ifndef __QUEX_INCLUDE_GUARD__BUFFER__BUFFER_NAVIGATION_I
     39 #define __QUEX_INCLUDE_GUARD__BUFFER__BUFFER_NAVIGATION_I
     40 
     41 QUEX_NAMESPACE_MAIN_OPEN
     42 
     43 QUEX_INLINE bool
     44 QUEX_NAME(Buffer_finish_seek_based_on_read_p)(QUEX_NAME(Buffer)* me);
     45 
     46 QUEX_INLINE QUEX_TYPE_STREAM_POSITION  
     47 QUEX_NAME(Buffer_input_lexatom_index_begin)(QUEX_NAME(Buffer)* me)
     48 /* Determine lexatom index of first lexatom in the buffer.               */
     49 {
     50     __quex_assert(me->input.lexatom_index_begin >= 0);
     51     return me->input.lexatom_index_begin;
     52 }
     53 
     54 QUEX_INLINE bool  
     55 QUEX_NAME(Buffer_seek_forward)(QUEX_NAME(Buffer)* me, const ptrdiff_t CharacterN)
     56 /* Move '_read_p' forwards by 'CharacterN'. This may involve reload in 
     57  * forward direction. 
     58  *
     59  * Seeking error => Buffer is completely left as is. In particular no change
     60  *                  to '_read_p' or '_lexeme_start_p'. 
     61  * 
     62  * RETURNS: True -- if positioning was successful,
     63  *          False -- else.                                                   */
     64 {
     65     QUEX_TYPE_LEXATOM*       BeginP = &me->_memory._front[1];
     66     QUEX_TYPE_STREAM_POSITION  CharacterIndexAtReadP =   me->input.lexatom_index_begin
     67                                                        + (me->_read_p - BeginP);
     68     QUEX_TYPE_STREAM_POSITION  target = CharacterIndexAtReadP + CharacterN;
     69     QUEX_TYPE_STREAM_POSITION  new_lexatom_index_begin;
     70 
     71     if( ! CharacterN ) {
     72         return true;
     73     }
     74     else if( target < QUEX_NAME(Buffer_input_lexatom_index_end)(me) ) {
     75         me->_read_p += CharacterN;
     76         /* => &me->_read_p[-1] inside buffer.                                */
     77     }
     78     else if(    me->input.lexatom_index_end_of_stream != -1 
     79              && target > me->input.lexatom_index_end_of_stream ) {
     80         return false;
     81     }
     82     else {
     83         /* Character index at read_p = lexatom index at begin + offset     */
     84         new_lexatom_index_begin = QUEX_MAX(0, target - QUEX_SETTING_BUFFER_MIN_FALLBACK_N);
     85         if( ! QUEX_NAME(Buffer_move_and_load_forward)(me, new_lexatom_index_begin, target) ) {
     86             QUEX_BUFFER_ASSERT_CONSISTENCY(me);
     87             return false;
     88         }
     89 
     90         me->_read_p = &BeginP[target - new_lexatom_index_begin];
     91     }
     92     me->_lexeme_start_p = me->_read_p;
     93 
     94     return QUEX_NAME(Buffer_finish_seek_based_on_read_p)(me);
     95 }
     96 
     97 QUEX_INLINE bool  
     98 QUEX_NAME(Buffer_seek_backward)(QUEX_NAME(Buffer)* me, 
     99                                 const ptrdiff_t    CharacterN)
    100 /* Move '_read_p' backwards by 'CharacterN'. This may involve reload in
    101  * backward direction.                                                   
    102  *
    103  * Seeking error => Buffer is completely left as is. In particular no change
    104  *                  to '_read_p' or '_lexeme_start_p'. 
    105  * 
    106  * RETURNS: True -- if positioning was successful, 
    107  *          False -- else.                                                   */
    108 {
    109     QUEX_TYPE_LEXATOM*       BeginP = &me->_memory._front[1];
    110     QUEX_TYPE_STREAM_POSITION  CharacterIndexAtReadP =   me->input.lexatom_index_begin
    111                                                        + (me->_read_p - BeginP);
    112     QUEX_TYPE_STREAM_POSITION  target      = CharacterIndexAtReadP - CharacterN;
    113     const ptrdiff_t            ContentSize = (ptrdiff_t)QUEX_NAME(Buffer_content_size)(me); 
    114     QUEX_TYPE_STREAM_POSITION  new_lexatom_index_begin;
    115     ptrdiff_t                  offset;
    116 
    117     if( ! CharacterN ) {
    118         return true;
    119     }
    120     else if( target > me->input.lexatom_index_begin ) {
    121         /* => &me->_read_p[-1] inside buffer.                                */
    122         me->_read_p -= CharacterN;
    123     }
    124     else {
    125         /* offset = desired distance from begin to 'read_p'.                 */
    126         offset                    = (ptrdiff_t)QUEX_MIN((QUEX_TYPE_STREAM_POSITION)(ContentSize >> 1), target);
    127         new_lexatom_index_begin = target - offset;
    128 
    129         if( ! QUEX_NAME(Buffer_move_and_load_backward)(me, new_lexatom_index_begin) ) {
    130             /* QUEX_ERROR_EXIT() initiated inside above function.            */
    131             return false;
    132         }
    133         me->_read_p = &BeginP[offset];
    134     }
    135 
    136     return QUEX_NAME(Buffer_finish_seek_based_on_read_p)(me);
    137 }
    138 
    139 QUEX_INLINE QUEX_TYPE_STREAM_POSITION  
    140 QUEX_NAME(Buffer_tell)(QUEX_NAME(Buffer)* me)
    141 /* RETURNS: lexatom index which corresponds to the position of the input
    142  *          pointer.                                                         */
    143 {
    144     const QUEX_TYPE_STREAM_POSITION DeltaToBufferBegin = me->_read_p - &me->_memory._front[1];
    145     QUEX_BUFFER_ASSERT_CONSISTENCY(me);
    146 
    147     return DeltaToBufferBegin + QUEX_NAME(Buffer_input_lexatom_index_begin)(me);
    148 }
    149 
    150 QUEX_INLINE void    
    151 QUEX_NAME(Buffer_seek)(QUEX_NAME(Buffer)* me, const QUEX_TYPE_STREAM_POSITION CharacterIndex)
    152 /* Set the _read_p according to a lexatom index of the input. It is the 
    153  * inverse of 'tell()'.                                                      */
    154 {
    155     const QUEX_TYPE_STREAM_POSITION CurrentCharacterIndex = QUEX_NAME(Buffer_tell)(me);
    156 
    157     if( CharacterIndex > CurrentCharacterIndex ) {
    158         QUEX_NAME(Buffer_seek_forward)(me, (ptrdiff_t)(CharacterIndex - CurrentCharacterIndex));
    159     }
    160     else if( CharacterIndex < CurrentCharacterIndex ) {
    161         QUEX_NAME(Buffer_seek_backward)(me,(ptrdiff_t)(CurrentCharacterIndex - CharacterIndex));
    162     }
    163 }
    164 
    165 QUEX_INLINE bool
    166 QUEX_NAME(Buffer_finish_seek_based_on_read_p)(QUEX_NAME(Buffer)* me)
    167 {
    168     QUEX_TYPE_LEXATOM* BeginP    = &me->_memory._front[1];
    169     bool                 verdict_f = true;
    170 
    171     if( me->_read_p >= me->input.end_p ) {
    172         me->_read_p = me->input.end_p;
    173         verdict_f = false;
    174     }
    175     else if( me->_read_p < BeginP ) {
    176         me->_read_p = BeginP;
    177         verdict_f = false;
    178     }
    179 
    180     me->_lexeme_start_p                = me->_read_p;
    181     me->_lexatom_at_lexeme_start     = me->_read_p[0];
    182 #   ifdef __QUEX_OPTION_SUPPORT_BEGIN_OF_LINE_PRE_CONDITION
    183     /* Seek was towards 'target - 1'
    184      * => Now, there must be at least one lexatom before '_read_p'.
    185      *    Or if not, then the target was on the lower limit 0 and the '_read_p'
    186      *    stands on the buffer's content front.                              */
    187     me->_lexatom_before_lexeme_start = me->_read_p > BeginP ? me->_read_p[-1]
    188                                          : QUEX_SETTING_CHARACTER_NEWLINE_IN_ENGINE_CODEC;
    189 #   endif
    190     QUEX_BUFFER_ASSERT_CONSISTENCY(me);
    191     return verdict_f;
    192 }
    193 
    194 QUEX_NAMESPACE_MAIN_CLOSE
    195 #endif                  /* __QUEX_INCLUDE_GUARD__BUFFER__BUFFER_NAVIGATION_I */