|
1 //input.c - read and store lines of input |
|
2 // |
|
3 // © Portions Copyright (c) Symbian Software Ltd 2007. All rights reserved. |
|
4 // |
|
5 /* |
|
6 * This file is part of zsh, the Z shell. |
|
7 * |
|
8 * Copyright (c) 1992-1997 Paul Falstad |
|
9 * All rights reserved. |
|
10 * |
|
11 * Permission is hereby granted, without written agreement and without |
|
12 * license or royalty fees, to use, copy, modify, and distribute this |
|
13 * software and to distribute modified versions of this software for any |
|
14 * purpose, provided that the above copyright notice and the following |
|
15 * two paragraphs appear in all copies of this software. |
|
16 * |
|
17 * In no event shall Paul Falstad or the Zsh Development Group be liable |
|
18 * to any party for direct, indirect, special, incidental, or consequential |
|
19 * damages arising out of the use of this software and its documentation, |
|
20 * even if Paul Falstad and the Zsh Development Group have been advised of |
|
21 * the possibility of such damage. |
|
22 * |
|
23 * Paul Falstad and the Zsh Development Group specifically disclaim any |
|
24 * warranties, including, but not limited to, the implied warranties of |
|
25 * merchantability and fitness for a particular purpose. The software |
|
26 * provided hereunder is on an "as is" basis, and Paul Falstad and the |
|
27 * Zsh Development Group have no obligation to provide maintenance, |
|
28 * support, updates, enhancements, or modifications. |
|
29 * |
|
30 */ |
|
31 |
|
32 |
|
33 /* |
|
34 * This file deals with input buffering, supplying characters to the |
|
35 * history expansion code a character at a time. Input is stored on a |
|
36 * stack, which allows insertion of strings into the input, possibly with |
|
37 * flags marking the end of alias expansion, with minimal copying of |
|
38 * strings. The same stack is used to record the fact that the input |
|
39 * is a history or alias expansion and to store the alias while it is in use. |
|
40 * |
|
41 * Input is taken either from zle, if appropriate, or read directly from |
|
42 * the input file, or may be supplied by some other part of the shell (such |
|
43 * as `eval' or $(...) substitution). In the last case, it should be |
|
44 * supplied by pushing a new level onto the stack, via inpush(input_string, |
|
45 * flag, alias); if the current input really needs to be altered, use |
|
46 * inputsetline(input_string, flag). `Flag' can include or's of INP_FREE |
|
47 * (if the input string is to be freed when used), INP_CONT (if the input |
|
48 * is to continue onto what's already in the input queue), INP_ALIAS |
|
49 * (push supplied alias onto stack) or INP_HIST (ditto, but used to |
|
50 * mark history expansion). `alias' is ignored unless INP_ALIAS or |
|
51 * INP_HIST is supplied. INP_ALIAS is always set if INP_HIST is. |
|
52 * |
|
53 * Note that the input string is itself used as the input buffer: it is not |
|
54 * copied, nor is it every written back to, so using a constant string |
|
55 * should work. Consequently, when passing areas of memory from the heap |
|
56 * it is necessary that that heap last as long as the operation of reading |
|
57 * the string. After the string is read, the stack should be popped with |
|
58 * inpop(), which effectively flushes any unread input as well as restoring |
|
59 * the previous input state. |
|
60 * |
|
61 * The internal flag INP_ALCONT shows that the stack element was pushed |
|
62 * by an alias expansion; it should not be needed elsewhere. |
|
63 * |
|
64 * The global variable inalmore is set to indicate aliases should |
|
65 * continue to be expanded because the last alias expansion ended |
|
66 * in a space. It is only reset after a complete word was read |
|
67 * without expanding a new alias, in exalias(). |
|
68 * |
|
69 * PWS 1996/12/10 |
|
70 */ |
|
71 |
|
72 #ifdef HAVE_STDIO_H |
|
73 #include <stdio.h> |
|
74 #endif |
|
75 |
|
76 #include "zsh.mdh" |
|
77 #include "input.pro" |
|
78 |
|
79 /* the shell input fd */ |
|
80 |
|
81 /**/ |
|
82 int SHIN; |
|
83 |
|
84 /* buffered shell input for non-interactive shells */ |
|
85 |
|
86 /**/ |
|
87 FILE *bshin; |
|
88 |
|
89 /* != 0 means we are reading input from a string */ |
|
90 |
|
91 /**/ |
|
92 int strin; |
|
93 |
|
94 /* total # of characters waiting to be read. */ |
|
95 |
|
96 /**/ |
|
97 mod_export int inbufct; |
|
98 |
|
99 /* the flags controlling the input routines in input.c: see INP_* in zsh.h */ |
|
100 |
|
101 /**/ |
|
102 int inbufflags; |
|
103 |
|
104 static char *inbuf; /* Current input buffer */ |
|
105 static char *inbufptr; /* Pointer into input buffer */ |
|
106 static char *inbufpush; /* Character at which to re-push alias */ |
|
107 static int inbufleft; /* Characters left in current input |
|
108 stack element */ |
|
109 |
|
110 |
|
111 /* Input must be stacked since the input queue is used by |
|
112 * various different parts of the shell. |
|
113 */ |
|
114 |
|
115 struct instacks { |
|
116 char *buf, *bufptr; |
|
117 Alias alias; |
|
118 int bufleft, bufct, flags; |
|
119 }; |
|
120 static struct instacks *instack, *instacktop; |
|
121 /* |
|
122 * Input stack size. We need to push the stack for aliases, history |
|
123 * expansion, and reading from internal strings: only if these operations |
|
124 * are nested do we need more than one extra level. Thus we shouldn't need |
|
125 * too much space as a rule. Initially, INSTACK_INITIAL is allocated; if |
|
126 * more is required, an extra INSTACK_EXPAND is added each time. |
|
127 */ |
|
128 #define INSTACK_INITIAL 4 |
|
129 #define INSTACK_EXPAND 4 |
|
130 |
|
131 static int instacksz = INSTACK_INITIAL; |
|
132 |
|
133 /* Read a line from bshin. Convert tokens and * |
|
134 * null characters to Meta c^32 character pairs. */ |
|
135 |
|
136 /**/ |
|
137 mod_export char * |
|
138 shingetline(void) |
|
139 { |
|
140 char *line = NULL; |
|
141 int ll = 0; |
|
142 int c; |
|
143 char buf[BUFSIZ]; |
|
144 char *p; |
|
145 |
|
146 p = buf; |
|
147 for (;;) { |
|
148 do { |
|
149 errno = 0; |
|
150 c = fgetc(bshin); |
|
151 } while (c < 0 && errno == EINTR); |
|
152 if (c < 0 || c == '\n') { |
|
153 if (c == '\n') |
|
154 *p++ = '\n'; |
|
155 if (p > buf) { |
|
156 *p++ = '\0'; |
|
157 line = zrealloc(line, ll + (p - buf)); |
|
158 memcpy(line + ll, buf, p - buf); |
|
159 } |
|
160 return line; |
|
161 } |
|
162 if (imeta(c)) { |
|
163 *p++ = Meta; |
|
164 *p++ = c ^ 32; |
|
165 } else |
|
166 *p++ = c; |
|
167 if (p >= buf + BUFSIZ - 1) { |
|
168 line = zrealloc(line, ll + (p - buf) + 1); |
|
169 memcpy(line + ll, buf, p - buf); |
|
170 ll += p - buf; |
|
171 line[ll] = '\0'; |
|
172 p = buf; |
|
173 } |
|
174 } |
|
175 } |
|
176 |
|
177 /* Get the next character from the input. |
|
178 * Will call inputline() to get a new line where necessary. |
|
179 */ |
|
180 |
|
181 /**/ |
|
182 int |
|
183 ingetc(void) |
|
184 { |
|
185 int lastc; |
|
186 |
|
187 if (lexstop) |
|
188 return ' '; |
|
189 for (;;) { |
|
190 if (inbufleft) { |
|
191 inbufleft--; |
|
192 inbufct--; |
|
193 if (itok(lastc = STOUC(*inbufptr++))) |
|
194 continue; |
|
195 if (((inbufflags & INP_LINENO) || !strin) && lastc == '\n') |
|
196 lineno++; |
|
197 return lastc; |
|
198 } |
|
199 |
|
200 /* If the next element down the input stack is a continuation of |
|
201 * this, use it. |
|
202 */ |
|
203 if (inbufflags & INP_CONT) { |
|
204 inpoptop(); |
|
205 continue; |
|
206 } |
|
207 /* |
|
208 * Otherwise, see if we have reached the end of input |
|
209 * (due to an error, or to reading from a single string). |
|
210 */ |
|
211 if (strin || errflag) { |
|
212 lexstop = 1; |
|
213 return ' '; |
|
214 } |
|
215 /* As a last resort, get some more input */ |
|
216 if (inputline()) |
|
217 return ' '; |
|
218 } |
|
219 } |
|
220 |
|
221 /* Read a line from the current command stream and store it as input */ |
|
222 |
|
223 /**/ |
|
224 static int |
|
225 inputline(void) |
|
226 { |
|
227 char *ingetcline, **ingetcpmptl = NULL, **ingetcpmptr = NULL; |
|
228 int context = ZLCON_LINE_START; |
|
229 |
|
230 /* If reading code interactively, work out the prompts. */ |
|
231 if (interact && isset(SHINSTDIN)) { |
|
232 if (!isfirstln) { |
|
233 ingetcpmptl = &prompt2; |
|
234 if (rprompt2) |
|
235 ingetcpmptr = &rprompt2; |
|
236 context = ZLCON_LINE_CONT; |
|
237 } |
|
238 else { |
|
239 ingetcpmptl = &prompt; |
|
240 if (rprompt) |
|
241 ingetcpmptr = &rprompt; |
|
242 } |
|
243 } |
|
244 if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) { |
|
245 /* |
|
246 * If not using zle, read the line straight from the input file. |
|
247 * Possibly we don't get the whole line at once: in that case, |
|
248 * we get another chunk with the next call to inputline(). |
|
249 */ |
|
250 |
|
251 if (interact && isset(SHINSTDIN)) { |
|
252 /* |
|
253 * We may still be interactive (e.g. running under emacs), |
|
254 * so output a prompt if necessary. We don't know enough |
|
255 * about the input device to be able to handle an rprompt, |
|
256 * though. |
|
257 */ |
|
258 char *pptbuf; |
|
259 int pptlen; |
|
260 pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL, |
|
261 0, NULL, NULL), &pptlen); |
|
262 write(1, (WRITE_ARG_2_T)pptbuf, pptlen); |
|
263 free(pptbuf); |
|
264 } |
|
265 ingetcline = shingetline(); |
|
266 } else { |
|
267 /* |
|
268 * Since we may have to read multiple lines before getting |
|
269 * a complete piece of input, we tell zle not to restore the |
|
270 * original tty settings after reading each chunk. Instead, |
|
271 * this is done when the history mechanism for the current input |
|
272 * terminates, which is not until we have the whole input. |
|
273 * This is supposed to minimise problems on systems that clobber |
|
274 * typeahead when the terminal settings are altered. |
|
275 * pws 1998/03/12 |
|
276 */ |
|
277 int flags = ZLRF_HISTORY|ZLRF_NOSETTY; |
|
278 if (isset(IGNOREEOF)) |
|
279 flags |= ZLRF_IGNOREEOF; |
|
280 ingetcline = (char *)zleread(ingetcpmptl, ingetcpmptr, flags, |
|
281 context); |
|
282 histdone |= HISTFLAG_SETTY; |
|
283 } |
|
284 if (!ingetcline) { |
|
285 return lexstop = 1; |
|
286 } |
|
287 if (errflag) { |
|
288 free(ingetcline); |
|
289 return lexstop = errflag = 1; |
|
290 } |
|
291 if (isset(VERBOSE)) { |
|
292 /* Output the whole line read so far. */ |
|
293 zputs(ingetcline, stderr); |
|
294 fflush(stderr); |
|
295 } |
|
296 if (*ingetcline && ingetcline[strlen(ingetcline) - 1] == '\n' && |
|
297 interact && isset(SUNKEYBOARDHACK) && isset(SHINSTDIN) && |
|
298 SHTTY != -1 && *ingetcline && ingetcline[1] && |
|
299 ingetcline[strlen(ingetcline) - 2] == '`') { |
|
300 /* Junk an unmatched "`" at the end of the line. */ |
|
301 int ct; |
|
302 char *ptr; |
|
303 |
|
304 for (ct = 0, ptr = ingetcline; *ptr; ptr++) |
|
305 if (*ptr == '`') |
|
306 ct++; |
|
307 if (ct & 1) { |
|
308 ptr[-2] = '\n'; |
|
309 ptr[-1] = '\0'; |
|
310 } |
|
311 } |
|
312 isfirstch = 1; |
|
313 /* Put this into the input channel. */ |
|
314 inputsetline(ingetcline, INP_FREE); |
|
315 |
|
316 return 0; |
|
317 } |
|
318 |
|
319 /* |
|
320 * Put a string in the input queue: |
|
321 * inbuf is only freeable if the flags include INP_FREE. |
|
322 */ |
|
323 |
|
324 /**/ |
|
325 static void |
|
326 inputsetline(char *str, int flags) |
|
327 { |
|
328 if ((inbufflags & INP_FREE) && inbuf) { |
|
329 free(inbuf); |
|
330 } |
|
331 inbuf = inbufptr = str; |
|
332 inbufleft = strlen(inbuf); |
|
333 |
|
334 /* |
|
335 * inbufct must reflect the total number of characters left, |
|
336 * as it used by other parts of the shell, so we need to take account |
|
337 * of whether the input stack continues, and whether there |
|
338 * is an extra space to add on at the end. |
|
339 */ |
|
340 if (flags & INP_CONT) |
|
341 inbufct += inbufleft; |
|
342 else |
|
343 inbufct = inbufleft; |
|
344 inbufflags = flags; |
|
345 } |
|
346 |
|
347 /* |
|
348 * Backup one character of the input. |
|
349 * The last character can always be backed up, provided we didn't just |
|
350 * expand an alias or a history reference. |
|
351 * In fact, the character is ignored and the previous character is used. |
|
352 * (If that's wrong, the bug is in the calling code. Use the #ifdef DEBUG |
|
353 * code to check.) |
|
354 */ |
|
355 |
|
356 /**/ |
|
357 void |
|
358 inungetc(int c) |
|
359 { |
|
360 if (!lexstop) { |
|
361 if (inbufptr != inbuf) { |
|
362 #ifdef DEBUG |
|
363 /* Just for debugging: enable only if foul play suspected. */ |
|
364 if (inbufptr[-1] != (char) c) |
|
365 fprintf(stderr, "Warning: backing up wrong character.\n"); |
|
366 #endif |
|
367 /* Just decrement the pointer: if it's not the same |
|
368 * character being pushed back, we're in trouble anyway. |
|
369 */ |
|
370 inbufptr--; |
|
371 inbufct++; |
|
372 inbufleft++; |
|
373 if (((inbufflags & INP_LINENO) || !strin) && c == '\n') |
|
374 lineno--; |
|
375 } |
|
376 #ifdef DEBUG |
|
377 else if (!(inbufflags & INP_CONT)) { |
|
378 /* Just for debugging */ |
|
379 fprintf(stderr, "Attempt to inungetc() at start of input.\n"); |
|
380 } |
|
381 #endif |
|
382 else { |
|
383 /* |
|
384 * The character is being backed up from a previous input stack |
|
385 * layer. However, there was an expansion in the middle, so we |
|
386 * can't back up where we want to. Instead, we just push it |
|
387 * onto the input stack as an extra character. |
|
388 */ |
|
389 char *cback = (char *)zshcalloc(2); |
|
390 cback[0] = (char) c; |
|
391 inpush(cback, INP_FREE|INP_CONT, NULL); |
|
392 } |
|
393 /* If we are back at the start of a segment, |
|
394 * we may need to restore an alias popped from the stack. |
|
395 * Note this may be a dummy (history expansion) entry. |
|
396 */ |
|
397 if (inbufptr == inbufpush && inbufflags & INP_ALCONT) { |
|
398 /* |
|
399 * Go back up the stack over all entries which were alias |
|
400 * expansions and were pushed with nothing remaining to read. |
|
401 */ |
|
402 do { |
|
403 if (instacktop->alias) |
|
404 instacktop->alias->inuse = 1; |
|
405 instacktop++; |
|
406 } while ((instacktop->flags & INP_ALCONT) && !instacktop->bufleft); |
|
407 inbufflags = INP_CONT|INP_ALIAS; |
|
408 inbufleft = 0; |
|
409 inbuf = inbufptr = ""; |
|
410 } |
|
411 } |
|
412 } |
|
413 |
|
414 /* stuff a whole file into the input queue and print it */ |
|
415 |
|
416 /**/ |
|
417 int |
|
418 stuff(char *fn) |
|
419 { |
|
420 FILE *in; |
|
421 char *buf; |
|
422 off_t len; |
|
423 |
|
424 if (!(in = fopen(unmeta(fn), "r"))) { |
|
425 zerr("can't open %s", fn, 0); |
|
426 return 1; |
|
427 } |
|
428 fseek(in, 0, 2); |
|
429 len = ftell(in); |
|
430 fseek(in, 0, 0); |
|
431 buf = (char *)zalloc(len + 1); |
|
432 if (!(fread(buf, len, 1, in))) { |
|
433 zerr("read error on %s", fn, 0); |
|
434 fclose(in); |
|
435 zfree(buf, len + 1); |
|
436 return 1; |
|
437 } |
|
438 fclose(in); |
|
439 buf[len] = '\0'; |
|
440 fwrite(buf, len, 1, stderr); |
|
441 fflush(stderr); |
|
442 #ifndef __SYMBIAN32__ |
|
443 inputsetline(metafy(buf, len, META_REALLOC), INP_FREE); |
|
444 #endif |
|
445 return 0; |
|
446 } |
|
447 |
|
448 /* flush input queue */ |
|
449 |
|
450 /**/ |
|
451 void |
|
452 inerrflush(void) |
|
453 { |
|
454 while (!lexstop && inbufct) |
|
455 ingetc(); |
|
456 } |
|
457 |
|
458 /* Set some new input onto a new element of the input stack */ |
|
459 |
|
460 /**/ |
|
461 mod_export void |
|
462 inpush(char *str, int flags, Alias inalias) |
|
463 { |
|
464 if (!instack) { |
|
465 /* Initial stack allocation */ |
|
466 instack = (struct instacks *)zalloc(instacksz*sizeof(struct instacks)); |
|
467 instacktop = instack; |
|
468 } |
|
469 |
|
470 instacktop->buf = inbuf; |
|
471 instacktop->bufptr = inbufptr; |
|
472 instacktop->bufleft = inbufleft; |
|
473 instacktop->bufct = inbufct; |
|
474 inbufflags &= ~INP_ALCONT; |
|
475 if (flags & (INP_ALIAS|INP_HIST)) { |
|
476 /* |
|
477 * Text is expansion for history or alias, so continue |
|
478 * back to old level when done. Also mark stack top |
|
479 * as alias continuation so as to back up if necessary, |
|
480 * and mark alias as in use. |
|
481 */ |
|
482 flags |= INP_CONT|INP_ALIAS; |
|
483 instacktop->flags = inbufflags | INP_ALCONT; |
|
484 if ((instacktop->alias = inalias)) |
|
485 inalias->inuse = 1; |
|
486 } else { |
|
487 /* If we are continuing an alias expansion, record the alias |
|
488 * expansion in new set of flags (do we need this?) |
|
489 */ |
|
490 if (((instacktop->flags = inbufflags) & INP_ALIAS) && |
|
491 (flags & INP_CONT)) |
|
492 flags |= INP_ALIAS; |
|
493 } |
|
494 |
|
495 instacktop++; |
|
496 if (instacktop == instack + instacksz) { |
|
497 /* Expand the stack */ |
|
498 instack = (struct instacks *) |
|
499 realloc(instack, |
|
500 (instacksz + INSTACK_EXPAND)*sizeof(struct instacks)); |
|
501 instacktop = instack + instacksz; |
|
502 instacksz += INSTACK_EXPAND; |
|
503 } |
|
504 /* |
|
505 * We maintain the entry above the highest one with real |
|
506 * text as a flag to inungetc() that it can stop re-pushing the stack. |
|
507 */ |
|
508 instacktop->flags = 0; |
|
509 |
|
510 inbufpush = inbuf = NULL; |
|
511 |
|
512 inputsetline(str, flags); |
|
513 } |
|
514 |
|
515 /* Remove the top element of the stack */ |
|
516 |
|
517 /**/ |
|
518 static void |
|
519 inpoptop(void) |
|
520 { |
|
521 if (inbuf && (inbufflags & INP_FREE)) |
|
522 free(inbuf); |
|
523 |
|
524 instacktop--; |
|
525 |
|
526 inbuf = instacktop->buf; |
|
527 inbufptr = inbufpush = instacktop->bufptr; |
|
528 inbufleft = instacktop->bufleft; |
|
529 inbufct = instacktop->bufct; |
|
530 inbufflags = instacktop->flags; |
|
531 |
|
532 if (!(inbufflags & INP_ALCONT)) |
|
533 return; |
|
534 |
|
535 if (instacktop->alias) { |
|
536 char *t = instacktop->alias->text; |
|
537 /* a real alias: mark it as unused. */ |
|
538 instacktop->alias->inuse = 0; |
|
539 if (*t && t[strlen(t) - 1] == ' ') { |
|
540 inalmore = 1; |
|
541 histbackword(); |
|
542 } |
|
543 } |
|
544 } |
|
545 |
|
546 /* Remove the top element of the stack and all its continuations. */ |
|
547 |
|
548 /**/ |
|
549 mod_export void |
|
550 inpop(void) |
|
551 { |
|
552 int remcont; |
|
553 |
|
554 do { |
|
555 remcont = inbufflags & INP_CONT; |
|
556 |
|
557 inpoptop(); |
|
558 } while (remcont); |
|
559 } |
|
560 |
|
561 /* |
|
562 * Expunge any aliases from the input stack; they shouldn't appear |
|
563 * in the history and need to be flushed explicitly when we encounter |
|
564 * an error. |
|
565 */ |
|
566 |
|
567 /**/ |
|
568 void |
|
569 inpopalias(void) |
|
570 { |
|
571 while (inbufflags & INP_ALIAS) |
|
572 inpoptop(); |
|
573 } |