Annotation of researchv10no/cmd/worm/scsi/tcl/tclAssem.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * tclAssem.c --
                      3:  *
                      4:  *     This file contains procedures to help assemble Tcl commands
                      5:  *     from an input source  where commands may arrive in pieces, e.g.
                      6:  *     several lines of type-in corresponding to one command.
                      7:  *
                      8:  * Copyright 1990 Regents of the University of California
                      9:  * Permission to use, copy, modify, and distribute this
                     10:  * software and its documentation for any purpose and without
                     11:  * fee is hereby granted, provided that the above copyright
                     12:  * notice appear in all copies.  The University of California
                     13:  * makes no representations about the suitability of this
                     14:  * software for any purpose.  It is provided "as is" without
                     15:  * express or implied warranty.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: static char rcsid[] = "$Header: /sprite/src/lib/tcl/RCS/tclAssem.c,v 1.4 90/03/23 16:26:20 ouster Exp $ SPRITE (Berkeley)";
                     20: #pragma ref rcsid
                     21: #endif not lint
                     22: 
                     23: #define        _POSIX_SOURCE
                     24: 
                     25: #include "tclInt.h"
                     26: #include <ctype.h>
                     27: #include <stdio.h>
                     28: #include <stdlib.h>
                     29: #include <string.h>
                     30: 
                     31: /*
                     32:  * The structure below is the internal representation for a command
                     33:  * buffer, which is used to hold a piece of a command until a full
                     34:  * command is available.  When a full command is available, it will
                     35:  * be returned to the user, but it will also be retained in the buffer
                     36:  * until the NEXT call to Tcl_AssembleCmd, at which point it will be
                     37:  * removed.
                     38:  */
                     39: 
                     40: typedef struct {
                     41:     char *buffer;              /* Storage for command being assembled.
                     42:                                 * Malloc-ed, and grows as needed. */
                     43:     int bufSize;               /* Total number of bytes in buffer. */
                     44:     int bytesUsed;             /* Number of bytes in buffer currently
                     45:                                 * occupied (0 means there is not a
                     46:                                 * buffered incomplete command). */
                     47: } CmdBuf;
                     48: 
                     49: /*
                     50:  * Default amount of space to allocate in command buffer:
                     51:  */
                     52: 
                     53: #define CMD_BUF_SIZE 100
                     54: 
                     55: /*
                     56:  *----------------------------------------------------------------------
                     57:  *
                     58:  * Tcl_CreateCmdBuf --
                     59:  *
                     60:  *     Allocate and initialize a command buffer.
                     61:  *
                     62:  * Results:
                     63:  *     The return value is a token that may be passed to
                     64:  *     Tcl_AssembleCmd and Tcl_DeleteCmdBuf.
                     65:  *
                     66:  * Side effects:
                     67:  *     Memory is allocated.
                     68:  *
                     69:  *----------------------------------------------------------------------
                     70:  */
                     71: 
                     72: Tcl_CmdBuf
                     73: Tcl_CreateCmdBuf()
                     74: {
                     75:     register CmdBuf *cbPtr;
                     76: 
                     77:     cbPtr = (CmdBuf *) malloc(sizeof(CmdBuf));
                     78:     cbPtr->buffer = malloc(CMD_BUF_SIZE);
                     79:     cbPtr->bufSize = CMD_BUF_SIZE;
                     80:     cbPtr->bytesUsed = 0;
                     81:     return (Tcl_CmdBuf) cbPtr;
                     82: }
                     83: 
                     84: /*
                     85:  *----------------------------------------------------------------------
                     86:  *
                     87:  * Tcl_DeleteCmdBuf --
                     88:  *
                     89:  *     Release all of the resources associated with a command buffer.
                     90:  *     The caller should never again use buffer again.
                     91:  *
                     92:  * Results:
                     93:  *     None.
                     94:  *
                     95:  * Side effects:
                     96:  *     Memory is released.
                     97:  *
                     98:  *----------------------------------------------------------------------
                     99:  */
                    100: 
                    101: void
                    102: Tcl_DeleteCmdBuf(buffer)
                    103:     Tcl_CmdBuf buffer;         /* Token for command buffer (return value
                    104:                                 * from previous call to Tcl_CreateCmdBuf). */
                    105: {
                    106:     register CmdBuf *cbPtr = (CmdBuf *) buffer;
                    107: 
                    108:     free(cbPtr->buffer);
                    109:     free((char *) cbPtr);
                    110: }
                    111: 
                    112: /*
                    113:  *----------------------------------------------------------------------
                    114:  *
                    115:  * Tcl_AssembleCmd --
                    116:  *
                    117:  *     This is a utility procedure to assist in situations where
                    118:  *     commands may be read piece-meal from some input source.  Given
                    119:  *     some input text, it adds the text to an input buffer and returns
                    120:  *     whole commands when they are ready.
                    121:  *
                    122:  * Results:
                    123:  *     If the addition of string to any currently-buffered information
                    124:  *     results in one or more complete Tcl commands, then the return value
                    125:  *     is a pointer to the complete command(s).  The command value will
                    126:  *     only be valid until the next call to this procedure with the
                    127:  *     same buffer.  If the addition of string leaves an incomplete
                    128:  *     command at the end of the buffer, then NULL is returned.
                    129:  *
                    130:  * Side effects:
                    131:  *     If string leaves a command incomplete, the partial command
                    132:  *     information is buffered for use in later calls to this procedure.
                    133:  *     Once a command has been returned, that command is deleted from
                    134:  *     the buffer on the next call to this procedure.
                    135:  *
                    136:  *----------------------------------------------------------------------
                    137:  */
                    138: 
                    139: char *
                    140: Tcl_AssembleCmd(buffer, string)
                    141:     Tcl_CmdBuf buffer;         /* Token for a command buffer previously
                    142:                                 * created by Tcl_CreateCmdBuf.  */
                    143:     char *string;              /* Bytes to be appended to command stream.
                    144:                                 * Note:  if the string is zero length,
                    145:                                 * then whatever is buffered will be
                    146:                                 * considered to be a complete command
                    147:                                 * regardless of whether parentheses are
                    148:                                 * matched or not. */
                    149: {
                    150:     register CmdBuf *cbPtr = (CmdBuf *) buffer;
                    151:     int length, totalLength;
                    152:     register char *p;
                    153: 
                    154:     /*
                    155:      * If an empty string is passed in, just pretend the current
                    156:      * command is complete, whether it really is or not.
                    157:      */
                    158: 
                    159:     length = strlen(string);
                    160:     if (length == 0) {
                    161:        cbPtr->bytesUsed = 0;
                    162:        return cbPtr->buffer;
                    163:     }
                    164: 
                    165:     /*
                    166:      * Add the new information to the buffer.  If the current buffer
                    167:      * isn't large enough, grow it by at least a factor of two, or
                    168:      * enough to hold the new text.
                    169:      */
                    170: 
                    171:     length = strlen(string);
                    172:     totalLength = cbPtr->bytesUsed + length + 1;
                    173:     if (totalLength > cbPtr->bufSize) {
                    174:        unsigned int newSize;
                    175:        char *newBuf;
                    176: 
                    177:        newSize = cbPtr->bufSize*2;
                    178:        if (newSize < totalLength) {
                    179:            newSize = totalLength;
                    180:        }
                    181:        newBuf = malloc(newSize);
                    182:        strcpy(newBuf, cbPtr->buffer);
                    183:        free(cbPtr->buffer);
                    184:        cbPtr->buffer = newBuf;
                    185:        cbPtr->bufSize = newSize;
                    186:     }
                    187:     strcpy(cbPtr->buffer+cbPtr->bytesUsed, string);
                    188:     cbPtr->bytesUsed += length;
                    189: 
                    190:     /*
                    191:      * See if there is now a complete command in the buffer.
                    192:      */
                    193: 
                    194:     p = cbPtr->buffer;
                    195:     while (1) {
                    196:        int gotNewLine = 0;
                    197: 
                    198:        while (isspace(*p)) {
                    199:            if (*p == '\n') {
                    200:                gotNewLine = 1;
                    201:            }
                    202:            p++;
                    203:        }
                    204:        if (*p == 0) {
                    205:            if (gotNewLine) {
                    206:                cbPtr->bytesUsed = 0;
                    207:                return cbPtr->buffer;
                    208:            }
                    209:            return NULL;
                    210:        }
                    211:        p = TclWordEnd(p, 0);
                    212:     }
                    213: }

unix.superglobalmegacorp.com

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