Annotation of micropolis/src/tcl/tclassem.c, revision 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.