Annotation of researchv10no/cmd/nupas/common/string.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <ctype.h>
                      3: #include "mail.h"
                      4: #include "string.h"
                      5: 
                      6: /* imports */
                      7: extern char *malloc();
                      8: extern char *realloc();
                      9: extern void exit();
                     10: 
                     11: /* global to this file */
                     12: #define STRLEN 128
                     13: #define STRALLOC 128
                     14: #define MAXINCR 250000
                     15: 
                     16: /* buffer pool for allocating string structures */
                     17: typedef struct {
                     18:        string s[STRALLOC];
                     19:        int o;
                     20: } stralloc;
                     21: static stralloc *freep=NULL;
                     22: 
                     23: /* pool of freed strings */
                     24: static string *freed=NULL;
                     25: 
                     26: void
                     27: s_free(sp)
                     28:        string *sp;
                     29: {
                     30:        if (sp != NULL) {
                     31:                sp->ptr = (char *)freed;
                     32:                freed = sp;
                     33:        }
                     34: }
                     35: 
                     36: /* allocate a string head */
                     37: static string *
                     38: s_alloc() {
                     39:        if (freep==NULL || freep->o >= STRALLOC) {
                     40:                freep = (stralloc *)malloc(sizeof(stralloc));
                     41:                if (freep==NULL) {
                     42:                        perror("allocating string");
                     43:                        exit(1);
                     44:                }
                     45:                freep->o = 0;
                     46:        }
                     47:        return &(freep->s[freep->o++]);
                     48: }
                     49: 
                     50: /* create a new `short' string */
                     51: extern string *
                     52: s_new()
                     53: {
                     54:        string *sp;
                     55: 
                     56:        if (freed!=NULL) {
                     57:                sp = freed;
                     58:                freed = (string *)(freed->ptr);
                     59:                sp->ptr = sp->base;
                     60:                return sp;
                     61:        }
                     62:        sp = s_alloc();
                     63:        sp->base = sp->ptr = malloc(STRLEN);
                     64:        if (sp->base == NULL) {
                     65:                perror("allocating string");
                     66:                exit(1);
                     67:        }
                     68:        sp->end = sp->base + STRLEN;
                     69:        s_terminate(sp);
                     70:        return sp;
                     71: }
                     72: 
                     73: /* grow a string's allocation by at least `incr' bytes */
                     74: extern int
                     75: s_simplegrow(sp, incr) 
                     76:        string *sp;
                     77:        int incr;
                     78: {
                     79:        char *cp;
                     80:        int size;
                     81: 
                     82:        /*
                     83:         *  take a larger increment to avoid mallocing too often
                     84:         */
                     85:        if((sp->end-sp->base) < incr && MAXINCR < incr)
                     86:                size = (sp->end-sp->base) + incr;
                     87:        else if((sp->end-sp->base) > MAXINCR)
                     88:                size = (sp->end-sp->base)+MAXINCR;
                     89:        else
                     90:                size = 2*(sp->end-sp->base);
                     91: 
                     92:        cp = realloc(sp->base, size);
                     93:        if (cp == NULL) {
                     94:                perror("string:");
                     95:                exit(1);
                     96:        }
                     97:        sp->ptr = (sp->ptr - sp->base) + cp;
                     98:        sp->end = cp + size;
                     99:        sp->base = cp;
                    100: }
                    101: 
                    102: /* grow a string's allocation */
                    103: extern int
                    104: s_grow(sp, c)
                    105:        string *sp;
                    106:        int c;
                    107: {
                    108:        s_simplegrow(sp, 2);
                    109:        s_putc(sp, c);
                    110:        return c;
                    111: }
                    112: 
                    113: /* return a string containing a character array (this had better not grow) */
                    114: string *
                    115: s_array(cp, len)
                    116:        char *cp;
                    117:        int len;
                    118: {
                    119:        string *sp = s_alloc();
                    120: 
                    121:        sp->base = sp->ptr = cp;
                    122:        sp->end = sp->base + len;
                    123:        return sp;
                    124: }
                    125: 
                    126: /* return a string containing a copy of the passed char array */
                    127: extern string*
                    128: s_copy(cp)
                    129:        char *cp;
                    130: {
                    131:        string *sp;
                    132:        int len;
                    133: 
                    134:        sp = s_alloc();
                    135:        len = strlen(cp)+1;
                    136:        sp->base = malloc(len);
                    137:        if (sp->base == NULL) {
                    138:                perror("string:");
                    139:                exit(1);
                    140:        }
                    141:        sp->end = sp->base + len;       /* point past end of allocation */
                    142:        strcpy(sp->base, cp);
                    143:        sp->ptr = sp->end - 1;          /* point to NULL terminator */
                    144:        return sp;
                    145: }
                    146: 
                    147: /* convert string to lower case */
                    148: extern int
                    149: s_tolower(sp)
                    150:        string *sp;
                    151: {
                    152:        char *cp;
                    153: 
                    154:        for(cp=sp->ptr; *cp; cp++)
                    155:                if(isupper(*cp))
                    156:                        *cp = tolower(*cp);
                    157: }
                    158: 
                    159: /* append a char array to a string */
                    160: extern string *
                    161: s_append(to, from)
                    162:        register string *to;
                    163:        register char *from;
                    164: {
                    165:        int want, have;
                    166: 
                    167:        if (to == NULL)
                    168:                to = s_new();
                    169:        if (from == NULL)
                    170:                return to;
                    171:        for(; *from; from++)
                    172:                s_putc(to, *from);
                    173:        s_terminate(to);
                    174:        return to;
                    175: }
                    176: 
                    177: /* append a char array ( of up to n characters) to a string */
                    178: extern string *
                    179: s_nappend(to, from, n)
                    180:        register string *to;
                    181:        register char *from;
                    182: {
                    183:        int want, have;
                    184: 
                    185:        if (to == NULL)
                    186:                to = s_new();
                    187:        if (from == NULL)
                    188:                return to;
                    189:        for(; *from && n; from++, n--)
                    190:                s_putc(to, *from);
                    191:        s_terminate(to);
                    192:        return to;
                    193: }
                    194: 
                    195: /* Append a logical input sequence into a string.  Ignore blank and
                    196:  * comment lines.  Backslash preceding newline indicates continuation.
                    197:  * The `lineortoken' variable indicates whether the sequence to beinput
                    198:  * is a whitespace delimited token or a whole line.
                    199:  *
                    200:  * Returns a pointer to the string (or NULL). Trailing newline is stripped off.
                    201:  */
                    202: extern string *
                    203: s_seq_read(fp, to, lineortoken)
                    204:        FILE *fp;               /* stream to read from */
                    205:        string *to;             /* where to put token */
                    206:        int lineortoken;        /* how the sequence terminates */
                    207: {
                    208:        register int c;
                    209:        int done=0;
                    210: 
                    211:        if(feof(fp))
                    212:                return NULL;
                    213: 
                    214:        /* get rid of leading goo */
                    215:        do {
                    216:                c = getc(fp);
                    217:                switch(c) {
                    218:                case EOF:
                    219:                        if (to != NULL)
                    220:                                s_terminate(to);
                    221:                        return NULL;
                    222:                case '#':
                    223:                        while((c = getc(fp)) != '\n' && c != EOF);
                    224:                        break;
                    225:                case ' ':
                    226:                case '\t':
                    227:                case '\n':
                    228:                case '\r':
                    229:                case '\f':
                    230:                        break;
                    231:                default:
                    232:                        done = 1;
                    233:                        break;
                    234:                }
                    235:        } while (!done);
                    236: 
                    237:        if (to == NULL)
                    238:                to = s_new();
                    239: 
                    240:        /* gather up a sequence */
                    241:        for (;;) {
                    242:                switch(c) {
                    243:                case '\\':
                    244:                        c = getc(fp);
                    245:                        if (c != '\n') {
                    246:                                s_putc(to, '\\');
                    247:                                s_putc(to, c);
                    248:                        }
                    249:                        break;
                    250:                case EOF:
                    251:                case '\r':
                    252:                case '\f':
                    253:                case '\n':
                    254:                        s_terminate(to);
                    255:                        return to;
                    256:                case ' ':
                    257:                case '\t':
                    258:                        if (lineortoken == TOKEN) {
                    259:                                s_terminate(to);
                    260:                                return to;
                    261:                        }
                    262:                        /* fall through */
                    263:                default:
                    264:                        s_putc(to, c);
                    265:                        break;
                    266:                }
                    267:                c = getc(fp);
                    268:        }
                    269: }
                    270: 
                    271: /* Append an input line to a string.
                    272:  *
                    273:  * Returns a pointer to the string (or NULL).
                    274:  * Trailing newline is left on.
                    275:  */ 
                    276: extern char *
                    277: s_read_line(fp, to)
                    278:        register FILE *fp;
                    279:        register string *to;
                    280: {
                    281:        register int c;
                    282:        register int len=0;
                    283: 
                    284:        s_terminate(to);
                    285: 
                    286:        /* end of input */
                    287:        if (feof(fp) || (c=getc(fp)) == EOF)
                    288:                return NULL;
                    289: 
                    290:        /* gather up a line */
                    291:        for(;;) {
                    292:                len++;
                    293:                switch(c) {
                    294:                case EOF:
                    295:                        s_terminate(to);
                    296:                        return to->ptr-len;
                    297:                case '\n':
                    298:                        s_putc(to, '\n');
                    299:                        s_terminate(to);
                    300:                        return to->ptr-len;
                    301:                default:
                    302:                        s_putc(to, c);
                    303:                        break;
                    304:                }
                    305:                c=getc(fp);
                    306:        }
                    307: }
                    308: 
                    309: /*
                    310:  *  Read till eof or some limit is passed.  If the limit is passed,
                    311:  *  return a negative counr.
                    312:  */
                    313: extern int
                    314: s_read_to_lim(fp, to, lim)
                    315:        register FILE *fp;
                    316:        register string *to;
                    317:        int lim;
                    318: {
                    319:        register int c;
                    320:        register int got;
                    321:        register int have;
                    322: 
                    323:        s_terminate(to);
                    324: 
                    325:        for(;;){
                    326:                if(lim && to->ptr - to->base > lim){
                    327:                        s_terminate(to);
                    328:                        return -(to->ptr - to->base);
                    329:                }
                    330:                if(feof(fp))
                    331:                        break;
                    332:                /* allocate room for a full buffer */
                    333:                have = to->end - to->ptr;
                    334:                if(have<4096)
                    335:                        s_simplegrow(to, 4096);
                    336: 
                    337:                /* get a buffers worth */
                    338:                have = to->end - to->ptr;
                    339:                got = fread(to->ptr, 1, have, fp);
                    340:                if(got<=0)
                    341:                        break;
                    342:                to->ptr += got;
                    343:        }
                    344: 
                    345:        /* null terminate the line */
                    346:        s_terminate(to);
                    347:        return to->ptr - to->base;
                    348: }
                    349: 
                    350: /*
                    351:  *  read to eof
                    352:  */
                    353: extern int
                    354: s_read_to_eof(fp, to)
                    355:        register FILE *fp;
                    356:        register string *to;
                    357: {
                    358:        return s_read_to_lim(fp, to, 0);
                    359: }
                    360: 
                    361: /* Get the next field from a string.  The field is delimited by white space,
                    362:  * single or double quotes.
                    363:  */
                    364: extern string *
                    365: s_parse(from, to)
                    366:        string *from;   /* string to parse */
                    367:        string *to;     /* where to put parsed token */
                    368: {
                    369:        while (isspace(*from->ptr))
                    370:                from->ptr++;
                    371:        if (*from->ptr == '\0')
                    372:                return NULL;
                    373:        if (to == NULL)
                    374:                to = s_new();
                    375:        if (*from->ptr == '\'') {
                    376:                from->ptr++;
                    377:                for (;*from->ptr != '\'' && *from->ptr != '\0'; from->ptr++)
                    378:                        s_putc(to, *from->ptr);
                    379:                if (*from->ptr == '\'') 
                    380:                        from->ptr++;
                    381:        } else if (*from->ptr == '"') {
                    382:                from->ptr++;
                    383:                for (;*from->ptr != '"' && *from->ptr != '\0'; from->ptr++)
                    384:                        s_putc(to, *from->ptr);
                    385:                if (*from->ptr == '"')  
                    386:                        from->ptr++;
                    387:        } else {
                    388:                for (;!isspace(*from->ptr) && *from->ptr != '\0'; from->ptr++)
                    389:                        s_putc(to, *from->ptr);
                    390:        }
                    391:        s_terminate(to);
                    392: 
                    393:        return to;
                    394: }
                    395: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.