Annotation of researchv10no/cmd/worm/scsi/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 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.