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

unix.superglobalmegacorp.com

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