]> cvs.zerfleddert.de Git - micropolis/blob - src/tcl/tclassem.c
Fixes for compilation with gcc 15
[micropolis] / src / tcl / tclassem.c
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 \f
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 (void)
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 \f
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 (
97 Tcl_CmdBuf buffer /* Token for command buffer (return value
98 * from previous call to Tcl_CreateCmdBuf). */
99 )
100 {
101 register CmdBuf *cbPtr = (CmdBuf *) buffer;
102
103 ckfree(cbPtr->buffer);
104 ckfree((char *) cbPtr);
105 }
106 \f
107 /*
108 *----------------------------------------------------------------------
109 *
110 * Tcl_AssembleCmd --
111 *
112 * This is a utility procedure to assist in situations where
113 * commands may be read piece-meal from some input source. Given
114 * some input text, it adds the text to an input buffer and returns
115 * whole commands when they are ready.
116 *
117 * Results:
118 * If the addition of string to any currently-buffered information
119 * results in one or more complete Tcl commands, then the return value
120 * is a pointer to the complete command(s). The command value will
121 * only be valid until the next call to this procedure with the
122 * same buffer. If the addition of string leaves an incomplete
123 * command at the end of the buffer, then NULL is returned.
124 *
125 * Side effects:
126 * If string leaves a command incomplete, the partial command
127 * information is buffered for use in later calls to this procedure.
128 * Once a command has been returned, that command is deleted from
129 * the buffer on the next call to this procedure.
130 *
131 *----------------------------------------------------------------------
132 */
133
134 char *
135 Tcl_AssembleCmd (
136 Tcl_CmdBuf buffer, /* Token for a command buffer previously
137 * created by Tcl_CreateCmdBuf. */
138 char *string /* Bytes to be appended to command stream.
139 * Note: if the string is zero length,
140 * then whatever is buffered will be
141 * considered to be a complete command
142 * regardless of whether parentheses are
143 * matched or not. */
144 )
145 {
146 register CmdBuf *cbPtr = (CmdBuf *) buffer;
147 int length, totalLength;
148 register char *p;
149
150 /*
151 * If an empty string is passed in, just pretend the current
152 * command is complete, whether it really is or not.
153 */
154
155 length = strlen(string);
156 if (length == 0) {
157 cbPtr->bytesUsed = 0;
158 return cbPtr->buffer;
159 }
160
161 /*
162 * Add the new information to the buffer. If the current buffer
163 * isn't large enough, grow it by at least a factor of two, or
164 * enough to hold the new text.
165 */
166
167 length = strlen(string);
168 totalLength = cbPtr->bytesUsed + length + 1;
169 if (totalLength > cbPtr->bufSize) {
170 unsigned int newSize;
171 char *newBuf;
172
173 newSize = cbPtr->bufSize*2;
174 if (newSize < totalLength) {
175 newSize = totalLength;
176 }
177 newBuf = (char *) ckalloc(newSize);
178 strcpy(newBuf, cbPtr->buffer);
179 ckfree(cbPtr->buffer);
180 cbPtr->buffer = newBuf;
181 cbPtr->bufSize = newSize;
182 }
183 strcpy(cbPtr->buffer+cbPtr->bytesUsed, string);
184 cbPtr->bytesUsed += length;
185
186 /*
187 * See if there is now a complete command in the buffer.
188 */
189
190 p = cbPtr->buffer;
191 while (1) {
192 int gotNewLine = 0;
193
194 while (isspace(*p)) {
195 if (*p == '\n') {
196 gotNewLine = 1;
197 }
198 p++;
199 }
200 if (*p == 0) {
201 if (gotNewLine) {
202 cbPtr->bytesUsed = 0;
203 return cbPtr->buffer;
204 }
205 return NULL;
206 }
207 p = TclWordEnd(p, 0);
208 }
209 }
Impressum, Datenschutz