00001
00002 # define DEBUG
00003 # undef DEBUG
00004 # include <stdio.h>
00005
00006 # include "strings.h"
00007
00008 # define new_hdr(p, first, last) { \
00009 p = (struct str_hdr *)GC_malloc(sizeof(struct str_hdr)); \
00010 p -> hdr_mark = HDR_MARK; \
00011 p -> first_part = (first); \
00012 p -> last_part = (last); \
00013 }
00014
00015
00016
00017
00018 char * concat(x, y)
00019 char * x, * y;
00020 {
00021 if (*y == '\0') {
00022 return(x);
00023 } else if (*x == '\0') {
00024 return(y);
00025 } else {
00026 struct str_hdr *p;
00027
00028 new_hdr(p,x,y);
00029 return((char *)p);
00030 }
00031 }
00032
00033
00034
00035 char * placeholder()
00036 {
00037 register struct str_hdr *p;
00038
00039 p = (struct str_hdr *)GC_malloc(sizeof(struct str_hdr));
00040 p -> hdr_mark = HDR_MARK;
00041 p -> first_part = CS_NIL;
00042 p -> last_part = "";
00043 return((char *)p);
00044 }
00045
00046
00047 void set_ph(p, s)
00048 struct str_hdr * p;
00049 char * s;
00050 {
00051 p -> first_part = s;
00052 }
00053
00054 # ifdef UNDEFINED
00055
00056 int str_length(x)
00057 char *x;
00058 {
00059 if (*x == HDR_MARK) {
00060 return(str_length(((struct str_hdr *) x) -> first_part)
00061 + str_length(((struct str_hdr *) x) -> last_part));
00062 } else {
00063 return(strlen(x));
00064 }
00065 }
00066 # endif
00067
00068 int str_length(x)
00069 char * x;
00070 {
00071 # define STACK_SIZE 1024
00072 # define TOS_MARK ((char *)0x55555555)
00073 char * len_stack[STACK_SIZE];
00074 register char ** stack_ptr = len_stack;
00075 register char *s;
00076 # define PUSH(y) *stack_ptr++ = (y)
00077 # define POP s = *(--stack_ptr)
00078 register unsigned long len = 0;
00079
00080 len_stack[STACK_SIZE-1] = TOS_MARK;
00081 PUSH(x);
00082 while (stack_ptr > len_stack) {
00083 POP;
00084 while (*s == HDR_MARK) {
00085
00086
00087
00088
00089 PUSH(((struct str_hdr *) s) -> first_part);
00090 s = ((struct str_hdr *)s) -> last_part;
00091 }
00092 while (*s++) { len++; }
00093 }
00094 if (len_stack[STACK_SIZE-1] != TOS_MARK) {
00095 fprintf(stderr, "str_length: stack overflow\n");
00096 exit(1);
00097 }
00098 return(len);
00099 }
00100
00101
00102
00103
00104 void str_firstn(buf, n, s)
00105 char *buf;
00106 int n;
00107 char *s;
00108 {
00109 if (s == CS_NIL) return;
00110 if (*s == HDR_MARK) {
00111 str_firstn(buf, n, ((struct str_hdr *) s) -> first_part);
00112 if (strlen(buf) < n) {
00113 str_firstn(buf, n, ((struct str_hdr *) s) -> last_part);
00114 }
00115 } else {
00116 strncat(buf, s, n - strlen(buf));
00117 }
00118 }
00119
00120
00121
00122 char str_last(s)
00123 char *s;
00124 {
00125 char * t = s;
00126
00127 while (*t == HDR_MARK) {
00128 if (*(((struct str_hdr *) t) -> last_part) == '\0') {
00129 t = ((struct str_hdr *) t) -> first_part;
00130 } else {
00131 t = ((struct str_hdr *) t) -> last_part;
00132 }
00133 }
00134 if (*t == '\0') return(*t);
00135 while (*(t+1) != '\0') t++;
00136 return(*t);
00137 }
00138
00139
00140
00141 void str_to_contig1();
00142
00143 void str_to_contig(s, buf)
00144 char * s;
00145 char **buf;
00146 {
00147 str_to_contig1(s,buf);
00148 **buf = '\0';
00149 (*buf)++;
00150 }
00151
00152 void str_to_contig1(x, buf)
00153 char * x;
00154 char **buf;
00155 {
00156 register char *b = *buf;
00157 # undef STACK_SIZE
00158 # define STACK_SIZE 10240
00159 # define TOS_MARK ((char *)0x55555555)
00160 char * stc_stack[STACK_SIZE];
00161 register char ** stack_ptr = stc_stack;
00162 register char *s;
00163 # define PUSH(y) *stack_ptr++ = (y)
00164 # define POP s = *(--stack_ptr)
00165
00166 PUSH(x);
00167 while (stack_ptr > stc_stack) {
00168 POP;
00169 while (*s == HDR_MARK) {
00170
00171
00172 PUSH(((struct str_hdr *) s) -> last_part);
00173 if (stack_ptr >= &stc_stack[STACK_SIZE]) {
00174 fprintf(stderr, "str_to_contig1: stack overflow (function too big)\n");
00175 exit(1);
00176 }
00177 s = ((struct str_hdr *)s) -> first_part;
00178 }
00179 while (*s) { *b++ = *s++; }
00180 }
00181 *buf = b;
00182 }
00183
00184
00185
00186 char * flatten(s, sz)
00187 char *s;
00188 long * sz;
00189 {
00190 int len = str_length(s);
00191 char * result = (char *)GC_malloc_atomic(len+1);
00192 char * bufptr;
00193
00194 if (sz != (long *)0) {
00195 *sz = len;
00196 }
00197 bufptr = result;
00198 str_to_contig(s, &bufptr);
00199 if (bufptr != result+len+1) {
00200 abort("flatten: inconsistent length", result, len, bufptr);
00201 }
00202 return(result);
00203 }
00204
00205
00206 int str_eq(s,t)
00207 char *s, *t;
00208 {
00209 int len_s = str_length(s) + 1;
00210 int len_t = str_length(t) + 1;
00211 char *sflat, *tflat;
00212 char *bufptr;
00213 extern int strcmp();
00214
00215 if (len_s != len_t) {
00216 return(0);
00217 } else {
00218 sflat = (char *)GC_malloc_atomic(len_s);
00219 bufptr = sflat;
00220 str_to_contig(s, &bufptr);
00221 tflat = (char *)GC_malloc_atomic(len_t);
00222 bufptr = tflat;
00223 str_to_contig(t, &bufptr);
00224 }
00225 return(strcmp(sflat, tflat) == 0);
00226 }
00227
00228