C:/Users/Dennis/src/lang/russell.orig/src/RIC_to_C/strings.c

Go to the documentation of this file.
00001 
00002 # define DEBUG
00003 # undef DEBUG
00004 # include <stdio.h>
00005 
00006 # include "strings.h"  /* Contains data structure definition for strings */
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 /* Concatenate two strings.  Note that an empty string will not occur */
00016 /* as a leaf unless the place_holder function is used.  Even then at  */
00017 /* most one leaf may be empty.                                        */
00018 char * concat(x, y)
00019 char * x, * y;  /* May actually be struct str_hdr * */
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 /* Make a placeholder string that can be embedded in other strings, and */
00034 /* subsequently filled in.                                              */
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 /* fill in a placeholder p */
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 /* Determine the length of a string in characters */
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;  /* 1 above top of stack */
00075     register char *s;                 /* Substring currently being examined */
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; /* So we can report overflow */
00081     PUSH(x);
00082     while (stack_ptr > len_stack) {
00083         POP;
00084         while (*s == HDR_MARK) {
00085             /* It's important to push the first, rather than the last part. */
00086             /* Otherwise the stack grows too much for typical situations.   */
00087             /* This way a stack overflow is very unlikely, so we do a       */
00088             /* sloppy job at checking for it.                               */
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 /* Concatenate characters from s to the C string in buffer buf until it has */
00103 /* n characters or s is exhausted.                                          */
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 /* Return the last character in s              */
00121 /* Assumes non-flat strings are not empty.     */
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 /* Convert the string s into a contiguous string starting at *buf  */
00140 /* *buf is updated to point one past the trailing NULL.            */
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;  /* 1 above top of stack */
00162     register char *s;                 /* Substring currently being examined */
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             /* Stack would be much smaller if we did this backwards.  But */
00171             /* that would cost us time.                                   */
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 /* Convert a string s to the standard sequential representation. */
00185 /* Return its length in *size.                                   */
00186 char * flatten(s, sz)
00187 char *s;
00188 long * sz;
00189 {
00190     int len = str_length(s);  /* includes trailing NULL */
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 /* Check two strings for equality. (Rather inefficient) */
00206 int str_eq(s,t)
00207 char *s, *t;
00208 {
00209     int len_s = str_length(s) + 1;  /* includes trailing NULL */
00210     int len_t = str_length(t) + 1;  /* includes trailing NULL */
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 

Generated on Fri Jan 25 10:39:47 2008 for russell by  doxygen 1.5.4