Back to index

lightning-sunbird  0.9+nobinonly
cord_pos.h
Go to the documentation of this file.
00001 /* 
00002  * Copyright (c) 1993-1994 by Xerox Corporation.  All rights reserved.
00003  *
00004  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00005  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00006  *
00007  * Permission is hereby granted to use or copy this program
00008  * for any purpose,  provided the above notices are retained on all copies.
00009  * Permission to modify the code and to distribute modified code is granted,
00010  * provided the above notices are retained, and a notice that the code was
00011  * modified is included with the above copyright notice.
00012  */
00013 /* Boehm, May 19, 1994 2:23 pm PDT */
00014 # ifndef CORD_POSITION_H
00015 
00016 /* The representation of CORD_position.  This is private to the       */
00017 /* implementation, but the size is known to clients.  Also     */
00018 /* the implementation of some exported macros relies on it.    */
00019 /* Don't use anything defined here and not in cord.h.          */
00020 
00021 # define MAX_DEPTH 48
00022        /* The maximum depth of a balanced cord + 1.            */
00023        /* We don't let cords get deeper than MAX_DEPTH. */
00024 
00025 struct CORD_pe {
00026     CORD pe_cord;
00027     size_t pe_start_pos;
00028 };
00029 
00030 /* A structure describing an entry on the path from the root   */
00031 /* to current position.                                        */
00032 typedef struct CORD_Pos {
00033     size_t cur_pos;
00034     int path_len;
00035 #      define CORD_POS_INVALID (0x55555555)
00036               /* path_len == INVALID <==> position invalid */
00037     const char *cur_leaf;   /* Current leaf, if it is a string.       */
00038                             /* If the current leaf is a function,     */
00039                             /* then this may point to function_buf    */
00040                             /* containing the next few characters.    */
00041                             /* Always points to a valid string */
00042                             /* containing the current character       */
00043                             /* unless cur_end is 0.                   */
00044     size_t cur_start;       /* Start position of cur_leaf      */
00045     size_t cur_end;  /* Ending position of cur_leaf     */
00046                      /* 0 if cur_leaf is invalid.       */
00047     struct CORD_pe path[MAX_DEPTH + 1];
00048        /* path[path_len] is the leaf corresponding to cur_pos  */
00049        /* path[0].pe_cord is the cord we point to.             */
00050 #   define FUNCTION_BUF_SZ 8
00051     char function_buf[FUNCTION_BUF_SZ];   /* Space for next few chars */
00052                                    /* from function node.             */
00053 } CORD_pos[1];
00054 
00055 /* Extract the cord from a position:      */
00056 CORD CORD_pos_to_cord(CORD_pos p);
00057        
00058 /* Extract the current index from a position:    */
00059 size_t CORD_pos_to_index(CORD_pos p);
00060        
00061 /* Fetch the character located at the given position:   */
00062 char CORD_pos_fetch(CORD_pos p);
00063        
00064 /* Initialize the position to refer to the give cord and index.       */
00065 /* Note that this is the most expensive function on positions: */
00066 void CORD_set_pos(CORD_pos p, CORD x, size_t i);
00067        
00068 /* Advance the position to the next character.   */
00069 /* P must be initialized and valid.              */
00070 /* Invalidates p if past end:                    */
00071 void CORD_next(CORD_pos p);
00072 
00073 /* Move the position to the preceding character. */
00074 /* P must be initialized and valid.                     */
00075 /* Invalidates p if past beginning:                     */
00076 void CORD_prev(CORD_pos p);
00077        
00078 /* Is the position valid, i.e. inside the cord?         */
00079 int CORD_pos_valid(CORD_pos p);
00080 
00081 char CORD__pos_fetch(CORD_pos);
00082 void CORD__next(CORD_pos);
00083 void CORD__prev(CORD_pos);
00084 
00085 #define CORD_pos_fetch(p)   \
00086     (((p)[0].cur_end != 0)? \
00087        (p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \
00088        : CORD__pos_fetch(p))
00089 
00090 #define CORD_next(p) \
00091     (((p)[0].cur_pos + 1 < (p)[0].cur_end)? \
00092        (p)[0].cur_pos++ \
00093        : (CORD__next(p), 0))
00094 
00095 #define CORD_prev(p) \
00096     (((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start)? \
00097        (p)[0].cur_pos-- \
00098        : (CORD__prev(p), 0))
00099 
00100 #define CORD_pos_to_index(p) ((p)[0].cur_pos)
00101 
00102 #define CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord)
00103 
00104 #define CORD_pos_valid(p) ((p)[0].path_len != CORD_POS_INVALID)
00105 
00106 /* Some grubby stuff for performance-critical friends:  */
00107 #define CORD_pos_chars_left(p) ((long)((p)[0].cur_end) - (long)((p)[0].cur_pos))
00108        /* Number of characters in cache.  <= 0 ==> none */
00109 
00110 #define CORD_pos_advance(p,n) ((p)[0].cur_pos += (n) - 1, CORD_next(p))
00111        /* Advance position by n characters       */
00112        /* 0 < n < CORD_pos_chars_left(p)  */
00113 
00114 #define CORD_pos_cur_char_addr(p) \
00115        (p)[0].cur_leaf + ((p)[0].cur_pos - (p)[0].cur_start)
00116        /* address of current character in cache. */
00117 
00118 #endif