summaryrefslogtreecommitdiff
path: root/cord
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-10-20 09:37:02 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-10-20 19:14:21 +0300
commit9135a7eab9b80aaab309f71055e040165509837a (patch)
treef5c2b662d58a3e7970ac5b351f452d76998aa49b /cord
parent5ab0ce84f3bf6e217e1ffe20a55bede4426ebbc3 (diff)
downloadbdwgc-9135a7eab9b80aaab309f71055e040165509837a.tar.gz
Move fields common between Concatenation and Function to Generic structure
(refactoring) * cord/cordbscs.c (word): Remove type. * cord/cordbscs.c (Concatenation, Function): Remove null, header, depth, left_len fields; move some comments to Generic. * cord/cordbscs.c (MAX_LEFT_LEN): Move definition down. * cord/cordbscs.c (Generic.null): Rename to nul. * cord/cordbscs.c (Generic.left_len): Change type from char to unsigned char (as was in Concatenation). * cord/cordbscs.c (Generic.len): Change type from word to unsigned long. * cord/cordbscs.c (ConcatOrFunc): New union type (with concat and function items). * cord/cordbscs.c (CordRep): Change type from union to struct with generic and data fields; remove concatenation, function and string items. * cord/cordbscs.c (LEFT_LEN): Change argument from c (of Concatenation type) to s (of CordRep* type). * cord/cordbscs.c (CORD_dump_inner, CORD_cat_char_star, CORD_cat, CORD_from_fn_inner, CORD_apply_access_fn, CORD_substr_closure, CORD_substr_checked, CORD_iter5, CORD_riter4, CORD_balance_insert, CORD__extend_path, CORD__pos_fetch, CORD__next): Update after change of CordRep, Concatenation and Function.
Diffstat (limited to 'cord')
-rw-r--r--cord/cordbscs.c177
1 files changed, 84 insertions, 93 deletions
diff --git a/cord/cordbscs.c b/cord/cordbscs.c
index cc5bfee0..0836bcd5 100644
--- a/cord/cordbscs.c
+++ b/cord/cordbscs.c
@@ -41,44 +41,34 @@ oom_fn CORD_oom_fn = (oom_fn) 0;
ABORT("Out of memory"); }
# define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
-typedef unsigned long word;
-
struct Concatenation {
- char null;
- char header;
- char depth; /* concatenation nesting depth. */
- unsigned char left_len;
- /* Length of left child if it is sufficiently */
- /* short; 0 otherwise. */
-# define MAX_LEFT_LEN 255
- word len;
CORD left; /* length(left) > 0 */
CORD right; /* length(right) > 0 */
};
struct Function {
- char null;
- char header;
- char depth; /* always 0 */
- char left_len; /* always 0 */
- word len;
CORD_fn fn;
void * client_data;
};
struct Generic {
- char null;
+ char nul;
char header;
- char depth;
- char left_len;
- word len;
+ char depth; /* Concatenation nesting depth; 0 for function. */
+ unsigned char left_len;
+ /* Length of left concatenated child if it is */
+ /* sufficiently short; 0 otherwise. */
+ unsigned long len;
};
-typedef union {
- struct Concatenation concatenation;
+union ConcatOrFunc {
+ struct Concatenation concat;
struct Function function;
- struct Generic generic;
- char string[1];
+};
+
+typedef struct {
+ struct Generic generic;
+ union ConcatOrFunc data;
} CordRep;
# define CONCAT_HDR 1
@@ -101,16 +91,18 @@ typedef union {
#define DEPTH(s) (((CordRep *)s) -> generic.depth)
#define GEN_LEN(s) (CORD_IS_STRING(s) ? strlen(s) : LEN(s))
-#define LEFT_LEN(c) ((c) -> left_len != 0? \
- (c) -> left_len \
- : (CORD_IS_STRING((c) -> left) ? \
- (c) -> len - GEN_LEN((c) -> right) \
- : LEN((c) -> left)))
+#define MAX_LEFT_LEN 255
+
+#define LEFT_LEN(s) (((CordRep *)s) -> generic.left_len != 0 ? \
+ ((CordRep *)s) -> generic.left_len \
+ : (CORD_IS_STRING(((CordRep *)s) -> data.concat.left) ? \
+ ((CordRep *)s) -> generic.len - \
+ GEN_LEN(((CordRep *)s) -> data.concat.right) \
+ : LEN(((CordRep *)s) -> data.concat.left)))
#define SHORT_LIMIT (sizeof(CordRep) - 1)
/* Cords shorter than this are C strings */
-
/* Dump the internal representation of x to stdout, with initial */
/* indentation level n. */
void CORD_dump_inner(CORD x, unsigned n)
@@ -130,21 +122,22 @@ void CORD_dump_inner(CORD x, unsigned n)
if (x[i] != '\0') fputs("...", stdout);
putchar('\n');
} else if (IS_CONCATENATION(x)) {
- struct Concatenation * conc = &(((CordRep *)x) -> concatenation);
+ struct Concatenation * conc = &(((CordRep *)x) -> data.concat);
printf("Concatenation: %p (len: %d, depth: %d)\n",
- (void *)x, (int)(conc -> len), (int)(conc -> depth));
+ (void *)x, (int)LEN(x), (int)DEPTH(x));
CORD_dump_inner(conc -> left, n+1);
CORD_dump_inner(conc -> right, n+1);
} else /* function */ {
- struct Function * func = &(((CordRep *)x) -> function);
+ struct Function * f = &(((CordRep *)x) -> data.function);
+ size_t lim = (size_t)LEN(x);
if (IS_SUBSTR(x)) printf("(Substring) ");
- printf("Function: %p (len: %d): ", (void *)x, (int)(func -> len));
- for (i = 0; i < 20 && i < func -> len; i++) {
- putchar((*(func -> fn))(i, func -> client_data));
+ printf("Function: %p (len: %d): ", (void *)x, (int)lim);
+ for (i = 0; i < 20 && i < lim; i++) {
+ putchar((*(f -> fn))(i, f -> client_data));
}
- if (i < func -> len) fputs("...", stdout);
+ if (i < lim) fputs("...", stdout);
putchar('\n');
}
}
@@ -193,14 +186,14 @@ CORD CORD_cat_char_star(CORD x, const char * y, size_t leny)
if (leny <= SHORT_LIMIT/2
&& IS_CONCATENATION(x)
- && CORD_IS_STRING(right = ((CordRep *)x) -> concatenation.right)) {
+ && CORD_IS_STRING(right = ((CordRep *)x) -> data.concat.right)) {
size_t right_len;
/* Merge y into right part of x. */
- if (!CORD_IS_STRING(left = ((CordRep *)x) -> concatenation.left)) {
+ if (!CORD_IS_STRING(left = ((CordRep *)x) -> data.concat.left)) {
right_len = lenx - LEN(left);
- } else if (((CordRep *)x) -> concatenation.left_len != 0) {
- right_len = lenx - ((CordRep *)x) -> concatenation.left_len;
+ } else if (((CordRep *)x) -> generic.left_len != 0) {
+ right_len = lenx - ((CordRep *)x) -> generic.left_len;
} else {
right_len = strlen(right);
}
@@ -229,16 +222,16 @@ CORD CORD_cat_char_star(CORD x, const char * y, size_t leny)
}
{
/* The general case; lenx, result_len is known: */
- struct Concatenation * result = GC_NEW(struct Concatenation);
+ CordRep *result = GC_NEW(CordRep);
if (NULL == result) OUT_OF_MEMORY;
- result->header = CONCAT_HDR;
- result->depth = (char)depth;
+ result -> generic.header = CONCAT_HDR;
+ result -> generic.depth = (char)depth;
if (lenx <= MAX_LEFT_LEN)
- result->left_len = (unsigned char)lenx;
- result->len = (word)result_len;
- result->left = x;
- GC_PTR_STORE_AND_DIRTY((void *)&result->right, y);
+ result -> generic.left_len = (unsigned char)lenx;
+ result -> generic.len = (unsigned long)result_len;
+ result -> data.concat.left = x;
+ GC_PTR_STORE_AND_DIRTY((void *)(&result -> data.concat.right), y);
GC_reachable_here(x);
if (depth >= MAX_DEPTH) {
return CORD_balance((CORD)result);
@@ -248,7 +241,6 @@ CORD CORD_cat_char_star(CORD x, const char * y, size_t leny)
}
}
-
CORD CORD_cat(CORD x, CORD y)
{
size_t result_len;
@@ -271,16 +263,16 @@ CORD CORD_cat(CORD x, CORD y)
}
result_len = lenx + LEN(y);
{
- struct Concatenation * result = GC_NEW(struct Concatenation);
+ CordRep *result = GC_NEW(CordRep);
if (NULL == result) OUT_OF_MEMORY;
- result->header = CONCAT_HDR;
- result->depth = (char)depth;
+ result -> generic.header = CONCAT_HDR;
+ result -> generic.depth = (char)depth;
if (lenx <= MAX_LEFT_LEN)
- result->left_len = (unsigned char)lenx;
- result->len = (word)result_len;
- result->left = x;
- GC_PTR_STORE_AND_DIRTY((void *)&result->right, y);
+ result -> generic.left_len = (unsigned char)lenx;
+ result -> generic.len = (unsigned long)result_len;
+ result -> data.concat.left = x;
+ GC_PTR_STORE_AND_DIRTY((void *)&(result -> data.concat.right), y);
GC_reachable_here(x);
if (depth >= MAX_DEPTH) {
return CORD_balance((CORD)result);
@@ -290,7 +282,6 @@ CORD CORD_cat(CORD x, CORD y)
}
}
-
static CordRep *CORD_from_fn_inner(CORD_fn fn, void * client_data, size_t len)
{
if (0 == len) return NULL;
@@ -314,15 +305,16 @@ static CordRep *CORD_from_fn_inner(CORD_fn fn, void * client_data, size_t len)
}
gen_case:
{
- struct Function * result = GC_NEW(struct Function);
+ CordRep *result = GC_NEW(CordRep);
if (NULL == result) OUT_OF_MEMORY;
- result->header = FN_HDR;
+ result -> generic.header = FN_HDR;
/* depth is already 0 */
- result->len = (word)len;
- result->fn = fn;
- GC_PTR_STORE_AND_DIRTY(&result->client_data, client_data);
- return (CordRep *)result;
+ result -> generic.len = (unsigned long)len;
+ result -> data.function.fn = fn;
+ GC_PTR_STORE_AND_DIRTY(&(result -> data.function.client_data),
+ client_data);
+ return result;
}
}
@@ -351,9 +343,9 @@ char CORD_index_access_fn(size_t i, void * client_data)
char CORD_apply_access_fn(size_t i, void * client_data)
{
struct substr_args *descr = (struct substr_args *)client_data;
- struct Function * fn_cord = &(descr->sa_cord->function);
+ struct Function * fn_cord = &(descr -> sa_cord -> data.function);
- return fn_cord->fn(i + descr->sa_index, fn_cord->client_data);
+ return fn_cord -> fn(i + descr -> sa_index, fn_cord -> client_data);
}
/* A version of CORD_substr that simply returns a function node, thus */
@@ -369,8 +361,8 @@ CORD CORD_substr_closure(CORD x, size_t i, size_t n, CORD_fn f)
sa->sa_index = i;
GC_PTR_STORE_AND_DIRTY(&sa->sa_cord, x);
result = CORD_from_fn_inner(f, (void *)sa, n);
- if ((CORD)result != CORD_EMPTY && 0 == result -> function.null)
- result -> function.header = SUBSTR_HDR;
+ if ((CORD)result != CORD_EMPTY && 0 == result -> generic.nul)
+ result -> generic.header = SUBSTR_HDR;
return (CORD)result;
}
@@ -379,7 +371,7 @@ CORD CORD_substr_closure(CORD x, size_t i, size_t n, CORD_fn f)
/* this are flat strings. Othewise we use a functional */
/* representation, which is significantly slower to access. */
-/* A version of CORD_substr that assumes i >= 0, n > 0, and i + n < length(x).*/
+/* A version of CORD_substr that assumes i >= 0, n > 0, i + n < length(x). */
CORD CORD_substr_checked(CORD x, size_t i, size_t n)
{
if (CORD_IS_STRING(x)) {
@@ -394,9 +386,9 @@ CORD CORD_substr_checked(CORD x, size_t i, size_t n)
return result;
}
} else if (IS_CONCATENATION(x)) {
- struct Concatenation * conc = &(((CordRep *)x) -> concatenation);
- size_t left_len = LEFT_LEN(conc);
- size_t right_len = conc -> len - left_len;
+ struct Concatenation * conc = &(((CordRep *)x) -> data.concat);
+ size_t left_len = LEFT_LEN(x);
+ size_t right_len = (size_t)LEN(x) - left_len;
if (i >= left_len) {
if (n == right_len) return conc -> right;
@@ -413,7 +405,8 @@ CORD CORD_substr_checked(CORD x, size_t i, size_t n)
if (i == 0) {
left_part = conc -> left;
} else {
- left_part = CORD_substr_checked(conc -> left, i, left_part_len);
+ left_part = CORD_substr_checked(conc -> left, i,
+ left_part_len);
}
if (i + n == right_len + left_len) {
right_part = conc -> right;
@@ -427,18 +420,18 @@ CORD CORD_substr_checked(CORD x, size_t i, size_t n)
if (n > SUBSTR_LIMIT) {
if (IS_SUBSTR(x)) {
/* Avoid nesting substring nodes. */
- struct Function * f = &(((CordRep *)x) -> function);
+ struct Function * f = &(((CordRep *)x) -> data.function);
struct substr_args *descr =
(struct substr_args *)(f -> client_data);
return CORD_substr_closure((CORD)descr->sa_cord,
- i + descr->sa_index, n, f->fn);
+ i + descr->sa_index, n, f -> fn);
} else {
return CORD_substr_closure(x, i, n, CORD_apply_access_fn);
}
} else {
char * result;
- struct Function * f = &(((CordRep *)x) -> function);
+ struct Function * f = &(((CordRep *)x) -> data.function);
char buf[SUBSTR_LIMIT+1];
char * p = buf;
size_t j;
@@ -489,10 +482,10 @@ int CORD_iter5(CORD x, size_t i, CORD_iter_fn f1,
return 0;
}
} else if (IS_CONCATENATION(x)) {
- struct Concatenation * conc = &(((CordRep *)x) -> concatenation);
+ struct Concatenation * conc = &(((CordRep *)x) -> data.concat);
if (i > 0) {
- size_t left_len = LEFT_LEN(conc);
+ size_t left_len = LEFT_LEN(x);
if (i >= left_len) {
return CORD_iter5(conc -> right, i - left_len, f1, f2,
@@ -504,9 +497,9 @@ int CORD_iter5(CORD x, size_t i, CORD_iter_fn f1,
}
return CORD_iter5(conc -> right, 0, f1, f2, client_data);
} else /* function */ {
- struct Function * f = &(((CordRep *)x) -> function);
+ struct Function * f = &(((CordRep *)x) -> data.function);
size_t j;
- size_t lim = f -> len;
+ size_t lim = (size_t)LEN(x);
for (j = i; j < lim; j++) {
if (f1(f->fn(j, f->client_data), client_data)) {
@@ -538,9 +531,9 @@ int CORD_riter4(CORD x, size_t i, CORD_iter_fn f1, void * client_data)
p--;
}
} else if (IS_CONCATENATION(x)) {
- struct Concatenation * conc = &(((CordRep *)x) -> concatenation);
+ struct Concatenation * conc = &(((CordRep *)x) -> data.concat);
CORD left_part = conc -> left;
- size_t left_len = LEFT_LEN(conc);
+ size_t left_len = LEFT_LEN(x);
if (i >= left_len) {
if (CORD_riter4(conc -> right, i - left_len, f1, client_data)) {
@@ -551,11 +544,11 @@ int CORD_riter4(CORD x, size_t i, CORD_iter_fn f1, void * client_data)
return CORD_riter4(left_part, i, f1, client_data);
}
} else /* function */ {
- struct Function * f = &(((CordRep *)x) -> function);
+ struct Function * f = &(((CordRep *)x) -> data.function);
size_t j;
for (j = i; ; j--) {
- if (f1(f->fn(j, f->client_data), client_data)) {
+ if (f1(f -> fn(j, f -> client_data), client_data)) {
return 1;
}
if (0 == j) break;
@@ -622,7 +615,6 @@ void CORD_init_min_len(void)
min_len_init = 1;
}
-
void CORD_init_forest(ForestElement * forest, size_t max_len)
{
int i;
@@ -703,8 +695,8 @@ void CORD_balance_insert(CORD x, size_t len, ForestElement * forest)
} else if (IS_CONCATENATION(x)
&& ((depth = DEPTH(x)) >= MAX_DEPTH
|| len < min_len[depth])) {
- struct Concatenation * conc = &(((CordRep *)x) -> concatenation);
- size_t left_len = LEFT_LEN(conc);
+ struct Concatenation * conc = &(((CordRep *)x) -> data.concat);
+ size_t left_len = LEFT_LEN(x);
CORD_balance_insert(conc -> left, left_len, forest);
CORD_balance_insert(conc -> right, len - left_len, forest);
@@ -713,7 +705,6 @@ void CORD_balance_insert(CORD x, size_t len, ForestElement * forest)
}
}
-
CORD CORD_balance(CORD x)
{
Forest forest;
@@ -745,11 +736,11 @@ void CORD__extend_path(CORD_pos p)
size_t top_len = GEN_LEN(top);
/* Fill in the rest of the path. */
- while(!CORD_IS_STRING(top) && IS_CONCATENATION(top)) {
- struct Concatenation * conc = &(((CordRep *)top) -> concatenation);
+ while (!CORD_IS_STRING(top) && IS_CONCATENATION(top)) {
+ struct Concatenation * conc = &(((CordRep *)top) -> data.concat);
size_t left_len;
- left_len = LEFT_LEN(conc);
+ left_len = LEFT_LEN(top);
current_pe++;
if (pos >= top_pos + left_len) {
current_pe -> pe_cord = top = conc -> right;
@@ -786,8 +777,8 @@ char CORD__pos_fetch(CORD_pos p)
leaf = pe -> pe_cord;
if (!IS_FUNCTION(leaf))
ABORT("CORD_pos_fetch: bad leaf");
- f = &((CordRep *)leaf)->function;
- return f->fn(p[0].cur_pos - pe->pe_start_pos, f->client_data);
+ f = &((CordRep *)leaf) -> data.function;
+ return f -> fn(p[0].cur_pos - pe -> pe_start_pos, f -> client_data);
}
void CORD__next(CORD_pos p)
@@ -805,9 +796,9 @@ void CORD__next(CORD_pos p)
p[0].cur_pos = cur_pos;
if (!CORD_IS_STRING(leaf)) {
/* Function leaf */
- struct Function * f = &(((CordRep *)leaf) -> function);
+ struct Function * f = &(((CordRep *)leaf) -> data.function);
size_t start_pos = current_pe -> pe_start_pos;
- size_t end_pos = start_pos + f -> len;
+ size_t end_pos = start_pos + (size_t)LEN(leaf);
if (cur_pos < end_pos) {
/* Fill cache and return. */