51488
|
1 /*
|
|
2 * Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved.
|
|
3 *
|
|
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
|
|
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
|
|
6 *
|
|
7 * Permission is hereby granted to use or copy this program
|
|
8 * for any purpose, provided the above notices are retained on all copies.
|
|
9 * Permission to modify the code and to distribute modified code is granted,
|
|
10 * provided the above notices are retained, and a notice that the code was
|
|
11 * modified is included with the above copyright notice.
|
|
12 */
|
|
13 /* Boehm, May 19, 1994 2:23 pm PDT */
|
|
14 # ifndef CORD_POSITION_H
|
|
15
|
|
16 /* The representation of CORD_position. This is private to the */
|
|
17 /* implementation, but the size is known to clients. Also */
|
|
18 /* the implementation of some exported macros relies on it. */
|
|
19 /* Don't use anything defined here and not in cord.h. */
|
|
20
|
|
21 # define MAX_DEPTH 48
|
|
22 /* The maximum depth of a balanced cord + 1. */
|
|
23 /* We don't let cords get deeper than MAX_DEPTH. */
|
|
24
|
|
25 struct CORD_pe {
|
|
26 CORD pe_cord;
|
|
27 size_t pe_start_pos;
|
|
28 };
|
|
29
|
|
30 /* A structure describing an entry on the path from the root */
|
|
31 /* to current position. */
|
|
32 typedef struct CORD_Pos {
|
|
33 size_t cur_pos;
|
|
34 int path_len;
|
|
35 # define CORD_POS_INVALID (0x55555555)
|
|
36 /* path_len == INVALID <==> position invalid */
|
|
37 const char *cur_leaf; /* Current leaf, if it is a string. */
|
|
38 /* If the current leaf is a function, */
|
|
39 /* then this may point to function_buf */
|
|
40 /* containing the next few characters. */
|
|
41 /* Always points to a valid string */
|
|
42 /* containing the current character */
|
|
43 /* unless cur_end is 0. */
|
|
44 size_t cur_start; /* Start position of cur_leaf */
|
|
45 size_t cur_end; /* Ending position of cur_leaf */
|
|
46 /* 0 if cur_leaf is invalid. */
|
|
47 struct CORD_pe path[MAX_DEPTH + 1];
|
|
48 /* path[path_len] is the leaf corresponding to cur_pos */
|
|
49 /* path[0].pe_cord is the cord we point to. */
|
|
50 # define FUNCTION_BUF_SZ 8
|
|
51 char function_buf[FUNCTION_BUF_SZ]; /* Space for next few chars */
|
|
52 /* from function node. */
|
|
53 } CORD_pos[1];
|
|
54
|
|
55 /* Extract the cord from a position: */
|
|
56 CORD CORD_pos_to_cord(CORD_pos p);
|
|
57
|
|
58 /* Extract the current index from a position: */
|
|
59 size_t CORD_pos_to_index(CORD_pos p);
|
|
60
|
|
61 /* Fetch the character located at the given position: */
|
|
62 char CORD_pos_fetch(CORD_pos p);
|
|
63
|
|
64 /* Initialize the position to refer to the give cord and index. */
|
|
65 /* Note that this is the most expensive function on positions: */
|
|
66 void CORD_set_pos(CORD_pos p, CORD x, size_t i);
|
|
67
|
|
68 /* Advance the position to the next character. */
|
|
69 /* P must be initialized and valid. */
|
|
70 /* Invalidates p if past end: */
|
|
71 void CORD_next(CORD_pos p);
|
|
72
|
|
73 /* Move the position to the preceding character. */
|
|
74 /* P must be initialized and valid. */
|
|
75 /* Invalidates p if past beginning: */
|
|
76 void CORD_prev(CORD_pos p);
|
|
77
|
|
78 /* Is the position valid, i.e. inside the cord? */
|
|
79 int CORD_pos_valid(CORD_pos p);
|
|
80
|
|
81 char CORD__pos_fetch(CORD_pos);
|
|
82 void CORD__next(CORD_pos);
|
|
83 void CORD__prev(CORD_pos);
|
|
84
|
|
85 #define CORD_pos_fetch(p) \
|
|
86 (((p)[0].cur_end != 0)? \
|
|
87 (p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \
|
|
88 : CORD__pos_fetch(p))
|
|
89
|
|
90 #define CORD_next(p) \
|
|
91 (((p)[0].cur_pos + 1 < (p)[0].cur_end)? \
|
|
92 (p)[0].cur_pos++ \
|
|
93 : (CORD__next(p), 0))
|
|
94
|
|
95 #define CORD_prev(p) \
|
|
96 (((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start)? \
|
|
97 (p)[0].cur_pos-- \
|
|
98 : (CORD__prev(p), 0))
|
|
99
|
|
100 #define CORD_pos_to_index(p) ((p)[0].cur_pos)
|
|
101
|
|
102 #define CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord)
|
|
103
|
|
104 #define CORD_pos_valid(p) ((p)[0].path_len != CORD_POS_INVALID)
|
|
105
|
|
106 /* Some grubby stuff for performance-critical friends: */
|
|
107 #define CORD_pos_chars_left(p) ((long)((p)[0].cur_end) - (long)((p)[0].cur_pos))
|
|
108 /* Number of characters in cache. <= 0 ==> none */
|
|
109
|
|
110 #define CORD_pos_advance(p,n) ((p)[0].cur_pos += (n) - 1, CORD_next(p))
|
|
111 /* Advance position by n characters */
|
|
112 /* 0 < n < CORD_pos_chars_left(p) */
|
|
113
|
|
114 #define CORD_pos_cur_char_addr(p) \
|
|
115 (p)[0].cur_leaf + ((p)[0].cur_pos - (p)[0].cur_start)
|
|
116 /* address of current character in cache. */
|
|
117
|
|
118 #endif
|