1 |
721 |
jeremybenn |
/*
|
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
|