Annotation of win32/development/msvcee/cord/cordbscs.cpp, revision 1.4

1.1       paf         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:  * Author: Hans-J. Boehm (boehm@parc.xerox.com)
                     14:  */
                     15: /* Boehm, October 3, 1994 5:19 pm PDT */
                     16: # include "cord.h"
                     17: # include <stdlib.h>
                     18: # include <stdio.h>
                     19: # include <string.h>
                     20: 
                     21: /* An implementation of the cord primitives.  These are the only       */
                     22: /* Functions that understand the representation.  We perform only      */
                     23: /* minimal checks on arguments to these functions.  Out of bounds      */
                     24: /* arguments to the iteration functions may result in client functions */
                     25: /* invoked on garbage data.  In most cases, client functions should be */
                     26: /* programmed defensively enough that this does not result in memory   */
                     27: /* smashes.                                                            */ 
                     28: 
                     29: #define GC_NEW(s) 0
                     30: #define GC_MALLOC_ATOMIC(s) 0
                     31: 
                     32: typedef void (* oom_fn)(void);
                     33: 
                     34: oom_fn CORD_oom_fn = (oom_fn) 0;
                     35: 
                     36: # define OUT_OF_MEMORY {  if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
                     37:                          ABORT("Out of memory\n"); }
                     38: # define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
                     39: 
                     40: typedef unsigned long word;
                     41: 
                     42: typedef union {
                     43:     struct Concatenation {
                     44:        char null;
                     45:        char header;
                     46:        char depth;     /* concatenation nesting depth. */
                     47:        unsigned char left_len;
                     48:                        /* Length of left child if it is sufficiently   */
                     49:                        /* short; 0 otherwise.                          */
                     50: #          define MAX_LEFT_LEN 255
                     51:        word len;
                     52:        CORD left;      /* length(left) > 0     */
                     53:        CORD right;     /* length(right) > 0    */
                     54:     } concatenation;
                     55:     struct Function {
                     56:        char null;
                     57:        char header;
                     58:        char depth;     /* always 0     */
                     59:        char left_len;  /* always 0     */
                     60:        word len;
                     61:        CORD_fn fn;
                     62:        void * client_data;
                     63:     } function;
                     64:     struct Generic {
                     65:        char null;
                     66:        char header;
                     67:        char depth;
                     68:        char left_len;
                     69:        word len;
                     70:     } generic;
                     71:     char string[1];
                     72: } CordRep;
                     73: 
                     74: # define CONCAT_HDR 1
                     75:        
                     76: # define FN_HDR 4
                     77: # define SUBSTR_HDR 6
                     78:        /* Substring nodes are a special case of function nodes.        */
                     79:        /* The client_data field is known to point to a substr_args     */
                     80:        /* structure, and the function is either CORD_apply_access_fn   */
                     81:        /* or CORD_index_access_fn.                                     */
                     82: 
                     83: /* The following may be applied only to function and concatenation nodes: */
                     84: #define IS_CONCATENATION(s)  (((CordRep *)s)->generic.header == CONCAT_HDR)
                     85: 
                     86: #define IS_FUNCTION(s)  ((((CordRep *)s)->generic.header & FN_HDR) != 0)
                     87: 
                     88: #define IS_SUBSTR(s) (((CordRep *)s)->generic.header == SUBSTR_HDR)
                     89: 
                     90: #define LEN(s) (((CordRep *)s) -> generic.len)
                     91: #define DEPTH(s) (((CordRep *)s) -> generic.depth)
                     92: #define GEN_LEN(s) (CORD_IS_STRING(s) ? strlen(s) : LEN(s))
                     93: 
                     94: #define LEFT_LEN(c) ((c) -> left_len != 0? \
                     95:                                (c) -> left_len \
                     96:                                : (CORD_IS_STRING(D((c) -> left)) ? \
                     97:                                        (c) -> len - GEN_LEN(D((c) -> right)) \
                     98:                                        : LEN(D((c) -> left))))
                     99: 
                    100: size_t CORD_len(CORD x)
                    101: {
                    102:     if (x == 0) {
                    103:        return(0);
                    104:     } else {
                    105:        return(GEN_LEN(x));
                    106:     }
                    107: }
                    108: 
                    109: struct substr_args {
                    110:     CordRep * sa_cord;
                    111:     size_t sa_index;
                    112: };
                    113: 
                    114: /* See cord.h for definition.  We assume i is in range.        */
                    115: int CORD_iter5(DEBUGHELPER *pHelper, CORD x, size_t i, CORD_iter_fn f1,
                    116:                         CORD_batched_iter_fn f2, void * client_data)
                    117: {
                    118:        int result;
                    119:     if (x == 0) return(0);
                    120:     if (CORD_IS_STRING(x)) {
                    121:        register const char* p = x+i;
                    122:        
                    123:        if (*p == '\0') ABORT("2nd arg to CORD_iter5 too big");
                    124:         if (f2 != CORD_NO_FN) {
                    125:             return((*f2)(p, client_data));
                    126:         } else {
                    127:            while (*p) {
                    128:                 if (result=(*f1)(*p, client_data)) 
                    129:                                        return result;
                    130:                 p++;
                    131:            }
                    132:            return(0);
                    133:         }
                    134:     } else if (IS_CONCATENATION(x)) {
                    135:        register CordRep::Concatenation * conc = &(((CordRep *)x) -> concatenation);
                    136:        if (i > 0) {
                    137:            register size_t left_len = LEFT_LEN(conc);
                    138:            
                    139:            if (i >= left_len) {
                    140:                return(CORD_iter5(pHelper, D(conc -> right), i - left_len, f1, f2,
                    141:                                  client_data));
                    142:            }
                    143:        }
                    144:                result=CORD_iter5(pHelper, D(conc -> left), i, f1, f2, client_data);
                    145:        if (result) return result;
                    146:        return(CORD_iter5(pHelper, D(conc -> right), 0, f1, f2, client_data));
                    147:     } else /* function */ {
1.2       paf       148:                //  todo: expand substrings
1.1       paf       149:         register CordRep::Function * f = &(((CordRep *)x) -> function);
                    150:         register size_t j;
                    151:         register size_t lim = f -> len;
1.2       paf       152: 
1.4     ! paf       153:                const char c=IS_SUBSTR(x)?'!':'?';
1.1       paf       154:         
                    155:         for (j = i; j < lim; j++) {
1.2       paf       156:             if (result=(*f1)(c/*(*(f -> fn))(j, f -> client_data)*/, client_data)) 
1.1       paf       157:                                return result;
                    158:         }
                    159:         return(0);
                    160:     }
                    161: }
1.2       paf       162: 
                    163: /*
1.3       paf       164:                if(IS_SUBSTR(x)) {
                    165:                    register struct substr_args* sa = (struct substr_args *)D(f -> client_data);
                    166:                        sa->sa_cord = (CordRep *)x;
                    167:                        sa->sa_index = i;
                    168:                } else {
                    169:                        for (j = i; j < lim; j++) {
                    170:                                if (result=(*f1)('?'/*(*(f -> fn))(j, f -> client_data)* /, client_data)) 
                    171:                                        return result;
                    172:                        }
                    173:                }
                    174: */
                    175: 
                    176: 
                    177: /*
1.2       paf       178: char CORD_index_access_fn(size_t i, void * client_data)
                    179: {
                    180:     register struct substr_args *descr = (struct substr_args *)client_data;
                    181:     
                    182:     return(((char *)(descr->sa_cord))[i + descr->sa_index]);
                    183: }
                    184: 
                    185: CORD CORD_substr_closure(CORD x, size_t i, size_t n, CORD_fn f)
                    186: {
                    187:     register struct substr_args * sa = GC_NEW(struct substr_args);
                    188:     CORD result;
                    189:     
                    190:     if (sa == 0) OUT_OF_MEMORY;
                    191:     sa->sa_cord = (CordRep *)x;
                    192:     sa->sa_index = i;
                    193:     result = CORD_from_fn(f, (void *)sa, n);
                    194:     ((CordRep *)result) -> function.header = SUBSTR_HDR;
                    195:     return (result);
                    196: }
                    197: */

E-mail: