8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sh / word.c
blob6e4417a9526920dfd8b506d902ef4ef17534e6f8
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
24 * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
33 * UNIX shell
36 #include "defs.h"
37 #include "sym.h"
38 #include <errno.h>
39 #include <fcntl.h>
41 static int readb(struct fileblk *, int, int);
43 /* ======== character handling for command lines ======== */
45 int
46 word(void)
48 unsigned int c, d, cc;
49 struct argnod *arg = (struct argnod *)locstak();
50 unsigned char *argp = arg->argval;
51 unsigned char *oldargp;
52 int alpha = 1;
53 unsigned char *pc;
55 wdnum = 0;
56 wdset = 0;
58 while (1)
60 while (c = nextwc(), space(c)) /* skipc() */
63 if (c == COMCHAR)
65 while ((c = readwc()) != NL && c != EOF);
66 peekc = c;
68 else
70 break; /* out of comment - white space loop */
73 if (!eofmeta(c))
77 if (c == LITERAL)
79 oldargp = argp;
80 while ((c = readwc()) && c != LITERAL){
82 * quote each character within
83 * single quotes
85 pc = readw(c);
86 if (argp >= brkend)
87 growstak(argp);
88 *argp++='\\';
89 /* Pick up rest of multibyte character */
90 if (c == NL)
91 chkpr();
92 while (c = *pc++) {
93 if (argp >= brkend)
94 growstak(argp);
95 *argp++ = (unsigned char)c;
98 if (argp == oldargp) { /* null argument - '' */
100 * Word will be represented by quoted null
101 * in macro.c if necessary
103 if (argp >= brkend)
104 growstak(argp);
105 *argp++ = '"';
106 if (argp >= brkend)
107 growstak(argp);
108 *argp++ = '"';
111 else
113 if (c == 0) {
114 if (argp >= brkend)
115 growstak(argp);
116 *argp++ = 0;
117 } else {
118 pc = readw(c);
119 while (*pc) {
120 if (argp >= brkend)
121 growstak(argp);
122 *argp++ = *pc++;
125 if (c == '\\') {
126 if ((cc = readwc()) == 0) {
127 if (argp >= brkend)
128 growstak(argp);
129 *argp++ = 0;
130 } else {
131 pc = readw(cc);
132 while (*pc) {
133 if (argp >= brkend)
134 growstak(argp);
135 *argp++ = *pc++;
139 if (c == '=')
140 wdset |= alpha;
141 if (!alphanum(c))
142 alpha = 0;
143 if (qotchar(c))
145 d = c;
146 for (;;)
148 if ((c = nextwc()) == 0) {
149 if (argp >= brkend)
150 growstak(argp);
151 *argp++ = 0;
152 } else {
153 pc = readw(c);
154 while (*pc) {
155 if (argp >= brkend)
156 growstak(argp);
157 *argp++ = *pc++;
160 if (c == 0 || c == d)
161 break;
162 if (c == NL)
163 chkpr();
165 * don't interpret quoted
166 * characters
168 if (c == '\\') {
169 if ((cc = readwc()) == 0) {
170 if (argp >= brkend)
171 growstak(argp);
172 *argp++ = 0;
173 } else {
174 pc = readw(cc);
175 while (*pc) {
176 if (argp >= brkend)
177 growstak(argp);
178 *argp++ = *pc++;
185 } while ((c = nextwc(), !eofmeta(c)));
186 argp = endstak(argp);
187 if (!letter(arg->argval[0]))
188 wdset = 0;
190 peekn = c | MARK;
191 if (arg->argval[1] == 0 &&
192 (d = arg->argval[0], digit(d)) &&
193 (c == '>' || c == '<'))
195 word();
196 wdnum = d - '0';
197 }else{ /* check for reserved words */
198 if (reserv == FALSE ||
199 (wdval = syslook(arg->argval,
200 reserved, no_reserved)) == 0) {
201 wdval = 0;
203 /* set arg for reserved words too */
204 wdarg = arg;
206 }else if (dipchar(c)){
207 if ((d = nextwc()) == c)
209 wdval = c | SYMREP;
210 if (c == '<')
212 if ((d = nextwc()) == '-')
213 wdnum |= IOSTRIP;
214 else
215 peekn = d | MARK;
218 else
220 peekn = d | MARK;
221 wdval = c;
224 else
226 if ((wdval = c) == EOF)
227 wdval = EOFSYM;
228 if (iopend && eolchar(c))
230 struct ionod *tmp_iopend;
231 tmp_iopend = iopend;
232 iopend = 0;
233 copy(tmp_iopend);
236 reserv = FALSE;
237 return (wdval);
240 unsigned int skipwc()
242 unsigned int c;
244 while (c = nextwc(), space(c))
246 return (c);
249 unsigned int nextwc()
251 unsigned int c, d;
253 retry:
254 if ((d = readwc()) == ESCAPE) {
255 if ((c = readwc()) == NL) {
256 chkpr();
257 goto retry;
259 peekc = c | MARK;
261 return (d);
264 unsigned char *readw(d)
265 wchar_t d;
267 static unsigned char c[MULTI_BYTE_MAX + 1];
268 int length;
269 wchar_t l;
270 if (isascii(d)) {
271 c[0] = d;
272 c[1] = '\0';
273 return (c);
276 length = wctomb((char *)c, d);
277 if (length <= 0) {
278 c[0] = (unsigned char)d;
279 length = 1;
281 c[length] = '\0';
282 return (c);
285 unsigned int
286 readwc()
288 wchar_t c;
289 int len;
290 struct fileblk *f;
291 int mbmax = MB_CUR_MAX;
292 int i, mlen;
294 if (peekn) {
295 c = peekn & 0x7fffffff;
296 peekn = 0;
297 return (c);
299 if (peekc) {
300 c = peekc & 0x7fffffff;
301 peekc = 0;
302 return (c);
304 f = standin;
306 retry:
307 if (f->fend > f->fnxt) {
309 * something in buffer
311 if (*f->fnxt == 0) {
312 f->fnxt++;
313 f->nxtoff++;
314 if (f->feval == 0)
315 goto retry; /* = c = readc(); */
316 if (estabf(*f->feval++))
317 c = EOF;
318 else
319 c = SPACE;
320 if (flags & readpr && standin->fstak == 0)
321 prc(c);
322 if (c == NL)
323 f->flin++;
324 return (c);
327 if (isascii(c = (unsigned char)*f->fnxt)) {
328 f->fnxt++;
329 f->nxtoff++;
330 if (flags & readpr && standin->fstak == 0)
331 prc(c);
332 if (c == NL)
333 f->flin++;
334 return (c);
337 for (i = 1; i <= mbmax; i++) {
338 int rest;
339 if ((rest = f->fend - f->fnxt) < i) {
341 * not enough bytes available
342 * f->fsiz could be BUFFERSIZE or 1
343 * since mbmax is enough smaller than BUFFERSIZE,
344 * this loop won't overrun the f->fbuf buffer.
346 len = readb(f,
347 (f->fsiz == 1) ? 1 : (f->fsiz - rest),
348 rest);
349 if (len == 0)
350 break;
352 mlen = mbtowc(&c, (char *)f->fnxt, i);
353 if (mlen > 0)
354 break;
357 if (i > mbmax) {
359 * enough bytes available but cannot be converted to
360 * a valid wchar.
362 c = (unsigned char)*f->fnxt;
363 mlen = 1;
366 f->fnxt += mlen;
367 f->nxtoff += mlen;
368 if (flags & readpr && standin->fstak == 0)
369 prwc(c);
370 if (c == NL)
371 f->flin++;
372 return (c);
375 if (f->feof || f->fdes < 0){
376 c = EOF;
377 f->feof++;
378 return (c);
381 if (readb(f, f->fsiz, 0) <= 0){
382 if (f->fdes != input || !isatty(input)) {
383 close(f->fdes);
384 f->fdes = -1;
386 f->feof++;
387 c = EOF;
388 return (c);
390 goto retry;
393 static int
394 readb(struct fileblk *f, int toread, int rest)
396 int len;
397 int fflags;
399 if (rest) {
401 * copies the remaining 'rest' bytes from f->fnxt
402 * to f->fbuf
404 (void) memcpy(f->fbuf, f->fnxt, rest);
405 f->fnxt = f->fbuf;
406 f->fend = f->fnxt + rest;
407 f->nxtoff = 0;
408 f->endoff = rest;
409 if (f->fbuf[rest - 1] == '\n') {
411 * if '\n' found, it should be
412 * a bondary of multibyte char.
414 return (rest);
418 retry:
419 do {
420 if (trapnote & SIGSET) {
421 newline();
422 sigchk();
423 } else if ((trapnote & TRAPSET) && (rwait > 0)) {
424 newline();
425 chktrap();
426 clearup();
428 } while ((len = read(f->fdes, f->fbuf + rest, toread)) < 0 && trapnote);
430 * if child sets O_NDELAY or O_NONBLOCK on stdin
431 * and exited then turn the modes off and retry
433 if (len == 0) {
434 if (((flags & intflg) ||
435 ((flags & oneflg) == 0 && isatty(input) &&
436 (flags & stdflg))) &&
437 ((fflags = fcntl(f->fdes, F_GETFL, 0)) & O_NDELAY)) {
438 fflags &= ~O_NDELAY;
439 fcntl(f->fdes, F_SETFL, fflags);
440 goto retry;
442 } else if (len < 0) {
443 if (errno == EAGAIN) {
444 fflags = fcntl(f->fdes, F_GETFL, 0);
445 fflags &= ~O_NONBLOCK;
446 fcntl(f->fdes, F_SETFL, fflags);
447 goto retry;
449 len = 0;
451 f->fnxt = f->fbuf;
452 f->fend = f->fnxt + (len + rest);
453 f->nxtoff = 0;
454 f->endoff = len + rest;
455 return (len + rest);