Annotation of researchv10no/cmd/upas/common/string.c, revision 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.