]>
Commit | Line | Data |
---|---|---|
73ffefd0 TT |
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 |