1 /*
2 * input.c - read and store lines of input
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1992-1997 Paul Falstad
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30
31 /*
32 * This file deals with input buffering, supplying characters to the
33 * history expansion code a character at a time. Input is stored on a
34 * stack, which allows insertion of strings into the input, possibly with
35 * flags marking the end of alias expansion, with minimal copying of
36 * strings. The same stack is used to record the fact that the input
37 * is a history or alias expansion and to store the alias while it is in use.
38 *
39 * Input is taken either from zle, if appropriate, or read directly from
40 * the input file, or may be supplied by some other part of the shell (such
41 * as `eval' or $(...) substitution). In the last case, it should be
42 * supplied by pushing a new level onto the stack, via inpush(input_string,
43 * flag, alias); if the current input really needs to be altered, use
44 * inputsetline(input_string, flag). `Flag' can include or's of INP_FREE
45 * (if the input string is to be freed when used), INP_CONT (if the input
46 * is to continue onto what's already in the input queue), INP_ALIAS
47 * (push supplied alias onto stack) or INP_HIST (ditto, but used to
48 * mark history expansion). `alias' is ignored unless INP_ALIAS or
49 * INP_HIST is supplied. INP_ALIAS is always set if INP_HIST is.
50 *
51 * Note that the input string is itself used as the input buffer: it is not
52 * copied, nor is it every written back to, so using a constant string
53 * should work. Consequently, when passing areas of memory from the heap
54 * it is necessary that that heap last as long as the operation of reading
55 * the string. After the string is read, the stack should be popped with
56 * inpop(), which effectively flushes any unread input as well as restoring
57 * the previous input state.
58 *
59 * The internal flags INP_ALCONT and INP_HISTCONT show that the stack
60 * element was pushed by an alias or history expansion; they should not
61 * be needed elsewhere.
62 *
63 * The global variable inalmore is set to indicate aliases should
64 * continue to be expanded because the last alias expansion ended
65 * in a space. It is only reset after a complete word was read
66 * without expanding a new alias, in exalias().
67 *
68 * PWS 1996/12/10
69 */
70
71 #ifdef HAVE_STDIO_H
72 #include <stdio.h>
73 #endif
74
75 #include "zsh.mdh"
76 #include "input.pro"
77
78 /* the shell input fd */
79
80 /**/
81 int SHIN;
82
83 /* != 0 means we are reading input from a string */
84
85 /**/
86 int strin;
87
88 /* total # of characters waiting to be read. */
89
90 /**/
91 mod_export int inbufct;
92
93 /* the flags controlling the input routines in input.c: see INP_* in zsh.h */
94
95 /**/
96 int inbufflags;
97
98 static char *inbuf; /* Current input buffer */
99 static char *inbufptr; /* Pointer into input buffer */
100 static char *inbufpush; /* Character at which to re-push alias */
101 static int inbufleft; /* Characters left in current input
102 stack element */
103
104
105 /* Input must be stacked since the input queue is used by
106 * various different parts of the shell.
107 */
108
109 struct instacks {
110 char *buf, *bufptr;
111 Alias alias;
112 int bufleft, bufct, flags;
113 };
114 static struct instacks *instack, *instacktop;
115 /*
116 * Input stack size. We need to push the stack for aliases, history
117 * expansion, and reading from internal strings: only if these operations
118 * are nested do we need more than one extra level. Thus we shouldn't need
119 * too much space as a rule. Initially, INSTACK_INITIAL is allocated; if
120 * more is required, an extra INSTACK_EXPAND is added each time.
121 */
122 #define INSTACK_INITIAL 4
123 #define INSTACK_EXPAND 4
124
125 static int instacksz = INSTACK_INITIAL;
126
127 /* Size of buffer for non-interactive command input */
128
129 #define SHINBUFSIZE 8192
130
131 /* Input buffer for non-interactive command input */
132 static char *shinbuffer;
133
134 /* Pointer into shinbuffer */
135 static char *shinbufptr;
136
137 /* End of contents read into shinbuffer */
138 static char *shinbufendptr;
139
140 /* Entry on SHIN buffer save stack */
141 struct shinsaveentry {
142 /* Next entry on stack */
143 struct shinsaveentry *next;
144 /* Saved shinbuffer */
145 char *buffer;
146 /* Saved shinbufptr */
147 char *ptr;
148 /* Saved shinbufendptr */
149 char *endptr;
150 };
151
152 /* SHIN buffer save stack */
153 static struct shinsaveentry *shinsavestack;
154
155 /* Reset the input buffer for SHIN, discarding any pending input */
156
157 /**/
158 void
shinbufreset(void)159 shinbufreset(void)
160 {
161 shinbufendptr = shinbufptr = shinbuffer;
162 }
163
164 /* Allocate a new shinbuffer
165 *
166 * Only called at shell initialisation and when saving on the stack.
167 */
168
169 /**/
170 void
shinbufalloc(void)171 shinbufalloc(void)
172 {
173 shinbuffer = zalloc(SHINBUFSIZE);
174 shinbufreset();
175 }
176
177 /* Save entry on SHIN buffer save stack */
178
179 /**/
180 void
shinbufsave(void)181 shinbufsave(void)
182 {
183 struct shinsaveentry *entry =
184 (struct shinsaveentry *)zalloc(sizeof(struct shinsaveentry));
185
186 entry->next = shinsavestack;
187 entry->buffer = shinbuffer;
188 entry->ptr = shinbufptr;
189 entry->endptr = shinbufendptr;
190
191 shinsavestack = entry;
192
193 shinbufalloc();
194 }
195
196 /* Restore entry from SHIN buffer save stack */
197
198 /**/
199 void
shinbufrestore(void)200 shinbufrestore(void)
201 {
202 struct shinsaveentry *entry = shinsavestack;
203
204 zfree(shinbuffer, SHINBUFSIZE);
205
206 shinbuffer = entry->buffer;
207 shinbufptr = entry->ptr;
208 shinbufendptr = entry->endptr;
209
210 shinsavestack = entry->next;
211 zfree(entry, sizeof(struct shinsaveentry));
212 }
213
214 /* Get a character from SHIN, -1 if none available */
215
216 /**/
217 static int
shingetchar(void)218 shingetchar(void)
219 {
220 int nread;
221
222 if (shinbufptr < shinbufendptr)
223 return STOUC(*shinbufptr++);
224
225 shinbufreset();
226 do {
227 errno = 0;
228 nread = read(SHIN, shinbuffer, SHINBUFSIZE);
229 } while (nread < 0 && errno == EINTR);
230 if (nread <= 0)
231 return -1;
232 shinbufendptr = shinbuffer + nread;
233 return STOUC(*shinbufptr++);
234 }
235
236 /* Read a line from SHIN. Convert tokens and *
237 * null characters to Meta c^32 character pairs. */
238
239 /**/
240 mod_export char *
shingetline(void)241 shingetline(void)
242 {
243 char *line = NULL;
244 int ll = 0;
245 int c;
246 char buf[BUFSIZ];
247 char *p;
248 int q = queue_signal_level();
249
250 p = buf;
251 winch_unblock();
252 dont_queue_signals();
253 for (;;) {
254 c = shingetchar();
255 if (c < 0 || c == '\n') {
256 winch_block();
257 restore_queue_signals(q);
258 if (c == '\n')
259 *p++ = '\n';
260 if (p > buf) {
261 *p++ = '\0';
262 line = zrealloc(line, ll + (p - buf));
263 memcpy(line + ll, buf, p - buf);
264 }
265 return line;
266 }
267 if (imeta(c)) {
268 *p++ = Meta;
269 *p++ = c ^ 32;
270 } else
271 *p++ = c;
272 if (p >= buf + BUFSIZ - 1) {
273 winch_block();
274 queue_signals();
275 line = zrealloc(line, ll + (p - buf) + 1);
276 memcpy(line + ll, buf, p - buf);
277 ll += p - buf;
278 line[ll] = '\0';
279 p = buf;
280 winch_unblock();
281 dont_queue_signals();
282 }
283 }
284 }
285
286 /* Get the next character from the input.
287 * Will call inputline() to get a new line where necessary.
288 */
289
290 /**/
291 int
ingetc(void)292 ingetc(void)
293 {
294 int lastc = ' ';
295
296 if (lexstop)
297 return ' ';
298 for (;;) {
299 if (inbufleft) {
300 inbufleft--;
301 inbufct--;
302 if (itok(lastc = STOUC(*inbufptr++)))
303 continue;
304 if (((inbufflags & INP_LINENO) || !strin) && lastc == '\n')
305 lineno++;
306 break;
307 }
308
309 /*
310 * See if we have reached the end of input
311 * (due to an error, or to reading from a single string).
312 * Check the remaining characters left, since if there aren't
313 * any we don't want to pop the stack---it'll mark any aliases
314 * as not in use before we've finished processing.
315 */
316 if (!inbufct && (strin || errflag)) {
317 lexstop = 1;
318 break;
319 }
320 /* If the next element down the input stack is a continuation of
321 * this, use it.
322 */
323 if (inbufflags & INP_CONT) {
324 inpoptop();
325 continue;
326 }
327 /* As a last resort, get some more input */
328 if (inputline())
329 break;
330 }
331 if (!lexstop)
332 zshlex_raw_add(lastc);
333 return lastc;
334 }
335
336 /* Read a line from the current command stream and store it as input */
337
338 /**/
339 static int
inputline(void)340 inputline(void)
341 {
342 char *ingetcline, **ingetcpmptl = NULL, **ingetcpmptr = NULL;
343 int context = ZLCON_LINE_START;
344
345 /* If reading code interactively, work out the prompts. */
346 if (interact && isset(SHINSTDIN)) {
347 if (!isfirstln) {
348 ingetcpmptl = &prompt2;
349 if (rprompt2)
350 ingetcpmptr = &rprompt2;
351 context = ZLCON_LINE_CONT;
352 }
353 else {
354 ingetcpmptl = &prompt;
355 if (rprompt)
356 ingetcpmptr = &rprompt;
357 }
358 }
359 if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
360 /*
361 * If not using zle, read the line straight from the input file.
362 * Possibly we don't get the whole line at once: in that case,
363 * we get another chunk with the next call to inputline().
364 */
365
366 if (interact && isset(SHINSTDIN)) {
367 /*
368 * We may still be interactive (e.g. running under emacs),
369 * so output a prompt if necessary. We don't know enough
370 * about the input device to be able to handle an rprompt,
371 * though.
372 */
373 char *pptbuf;
374 int pptlen;
375 pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL,
376 0, NULL, NULL, NULL), &pptlen);
377 write_loop(2, pptbuf, pptlen);
378 free(pptbuf);
379 }
380 ingetcline = shingetline();
381 } else {
382 /*
383 * Since we may have to read multiple lines before getting
384 * a complete piece of input, we tell zle not to restore the
385 * original tty settings after reading each chunk. Instead,
386 * this is done when the history mechanism for the current input
387 * terminates, which is not until we have the whole input.
388 * This is supposed to minimise problems on systems that clobber
389 * typeahead when the terminal settings are altered.
390 * pws 1998/03/12
391 */
392 int flags = ZLRF_HISTORY|ZLRF_NOSETTY;
393 if (isset(IGNOREEOF))
394 flags |= ZLRF_IGNOREEOF;
395 ingetcline = zleentry(ZLE_CMD_READ, ingetcpmptl, ingetcpmptr,
396 flags, context);
397 histdone |= HISTFLAG_SETTY;
398 }
399 if (!ingetcline) {
400 return lexstop = 1;
401 }
402 if (errflag) {
403 free(ingetcline);
404 errflag |= ERRFLAG_ERROR;
405 return lexstop = 1;
406 }
407 if (isset(VERBOSE)) {
408 /* Output the whole line read so far. */
409 zputs(ingetcline, stderr);
410 fflush(stderr);
411 }
412 if (keyboardhackchar && *ingetcline &&
413 ingetcline[strlen(ingetcline) - 1] == '\n' &&
414 interact && isset(SHINSTDIN) &&
415 SHTTY != -1 && ingetcline[1])
416 {
417 char *stripptr = ingetcline + strlen(ingetcline) - 2;
418 if (*stripptr == keyboardhackchar) {
419 /* Junk an unwanted character at the end of the line.
420 (key too close to return key) */
421 int ct = 1; /* force odd */
422 char *ptr;
423
424 if (keyboardhackchar == '\'' || keyboardhackchar == '"' ||
425 keyboardhackchar == '`') {
426 /*
427 * for the chars above, also require an odd count before
428 * junking
429 */
430 for (ct = 0, ptr = ingetcline; *ptr; ptr++)
431 if (*ptr == keyboardhackchar)
432 ct++;
433 }
434 if (ct & 1) {
435 stripptr[0] = '\n';
436 stripptr[1] = '\0';
437 }
438 }
439 }
440 isfirstch = 1;
441 if ((inbufflags & INP_APPEND) && inbuf) {
442 /*
443 * We need new input but need to be able to back up
444 * over the old input, so append this line.
445 * Pushing the line onto the stack doesn't have the right
446 * effect.
447 *
448 * This is quite a simple and inefficient fix, but currently
449 * we only need it when backing up over a multi-line $((...
450 * that turned out to be a command substitution rather than
451 * a math substitution, which is a very special case.
452 * So it's not worth rewriting.
453 */
454 char *oinbuf = inbuf;
455 int newlen = strlen(ingetcline);
456 int oldlen = (int)(inbufptr - inbuf) + inbufleft;
457 if (inbufflags & INP_FREE) {
458 inbuf = realloc(inbuf, oldlen + newlen + 1);
459 } else {
460 inbuf = zalloc(oldlen + newlen + 1);
461 memcpy(inbuf, oinbuf, oldlen);
462 }
463 inbufptr += inbuf - oinbuf;
464 strcpy(inbuf + oldlen, ingetcline);
465 free(ingetcline);
466 inbufleft += newlen;
467 inbufct += newlen;
468 inbufflags |= INP_FREE;
469 } else {
470 /* Put this into the input channel. */
471 inputsetline(ingetcline, INP_FREE);
472 }
473
474 return 0;
475 }
476
477 /*
478 * Put a string in the input queue:
479 * inbuf is only freeable if the flags include INP_FREE.
480 */
481
482 /**/
483 static void
inputsetline(char * str,int flags)484 inputsetline(char *str, int flags)
485 {
486 queue_signals();
487
488 if ((inbufflags & INP_FREE) && inbuf) {
489 free(inbuf);
490 }
491 inbuf = inbufptr = str;
492 inbufleft = strlen(inbuf);
493
494 /*
495 * inbufct must reflect the total number of characters left,
496 * as it used by other parts of the shell, so we need to take account
497 * of whether the input stack continues, and whether there
498 * is an extra space to add on at the end.
499 */
500 if (flags & INP_CONT)
501 inbufct += inbufleft;
502 else
503 inbufct = inbufleft;
504 inbufflags = flags;
505
506 unqueue_signals();
507 }
508
509 /*
510 * Backup one character of the input.
511 * The last character can always be backed up, provided we didn't just
512 * expand an alias or a history reference.
513 * In fact, the character is ignored and the previous character is used.
514 * (If that's wrong, the bug is in the calling code. Use the #ifdef DEBUG
515 * code to check.)
516 */
517
518 /**/
519 void
inungetc(int c)520 inungetc(int c)
521 {
522 if (!lexstop) {
523 if (inbufptr != inbuf) {
524 #ifdef DEBUG
525 /* Just for debugging: enable only if foul play suspected. */
526 if (inbufptr[-1] != (char) c)
527 fprintf(stderr, "Warning: backing up wrong character.\n");
528 #endif
529 /* Just decrement the pointer: if it's not the same
530 * character being pushed back, we're in trouble anyway.
531 */
532 inbufptr--;
533 inbufct++;
534 inbufleft++;
535 if (((inbufflags & INP_LINENO) || !strin) && c == '\n')
536 lineno--;
537 }
538 else if (!(inbufflags & INP_CONT)) {
539 #ifdef DEBUG
540 /* Just for debugging */
541 fprintf(stderr, "Attempt to inungetc() at start of input.\n");
542 #endif
543 zerr("Garbled input at %c (binary file as commands?)", c);
544 return;
545 }
546 else {
547 /*
548 * The character is being backed up from a previous input stack
549 * layer. However, there was an expansion in the middle, so we
550 * can't back up where we want to. Instead, we just push it
551 * onto the input stack as an extra character.
552 */
553 char *cback = (char *)zshcalloc(2);
554 cback[0] = (char) c;
555 inpush(cback, INP_FREE|INP_CONT, NULL);
556 }
557 /* If we are back at the start of a segment,
558 * we may need to restore an alias popped from the stack.
559 * Note this may be a dummy (history expansion) entry.
560 */
561 if (inbufptr == inbufpush &&
562 (inbufflags & (INP_ALCONT|INP_HISTCONT))) {
563 /*
564 * Go back up the stack over all entries which were alias
565 * expansions and were pushed with nothing remaining to read.
566 */
567 do {
568 if (instacktop->alias)
569 instacktop->alias->inuse = 1;
570 instacktop++;
571 } while ((instacktop->flags & (INP_ALCONT|INP_HISTCONT))
572 && !instacktop->bufleft);
573 if (inbufflags & INP_HISTCONT)
574 inbufflags = INP_CONT|INP_ALIAS|INP_HIST;
575 else
576 inbufflags = INP_CONT|INP_ALIAS;
577 inbufleft = 0;
578 inbuf = inbufptr = "";
579 }
580 zshlex_raw_back();
581 }
582 }
583
584 /* stuff a whole file into the input queue and print it */
585
586 /**/
587 int
stuff(char * fn)588 stuff(char *fn)
589 {
590 FILE *in;
591 char *buf;
592 off_t len;
593
594 if (!(in = fopen(unmeta(fn), "r"))) {
595 zerr("can't open %s", fn);
596 return 1;
597 }
598 fseek(in, 0, 2);
599 len = ftell(in);
600 fseek(in, 0, 0);
601 buf = (char *)zalloc(len + 1);
602 if (!(fread(buf, len, 1, in))) {
603 zerr("read error on %s", fn);
604 fclose(in);
605 zfree(buf, len + 1);
606 return 1;
607 }
608 fclose(in);
609 buf[len] = '\0';
610 fwrite(buf, len, 1, stderr);
611 fflush(stderr);
612 inputsetline(metafy(buf, len, META_REALLOC), INP_FREE);
613 return 0;
614 }
615
616 /* flush input queue */
617
618 /**/
619 void
inerrflush(void)620 inerrflush(void)
621 {
622 while (!lexstop && inbufct)
623 ingetc();
624 }
625
626 /* Set some new input onto a new element of the input stack */
627
628 /**/
629 mod_export void
inpush(char * str,int flags,Alias inalias)630 inpush(char *str, int flags, Alias inalias)
631 {
632 if (!instack) {
633 /* Initial stack allocation */
634 instack = (struct instacks *)zalloc(instacksz*sizeof(struct instacks));
635 instacktop = instack;
636 }
637
638 instacktop->buf = inbuf;
639 instacktop->bufptr = inbufptr;
640 instacktop->bufleft = inbufleft;
641 instacktop->bufct = inbufct;
642 inbufflags &= ~(INP_ALCONT|INP_HISTCONT);
643 if (flags & (INP_ALIAS|INP_HIST)) {
644 /*
645 * Text is expansion for history or alias, so continue
646 * back to old level when done. Also mark stack top
647 * as alias continuation so as to back up if necessary,
648 * and mark alias as in use.
649 */
650 flags |= INP_CONT|INP_ALIAS;
651 if (flags & INP_HIST)
652 instacktop->flags = inbufflags | INP_HISTCONT;
653 else
654 instacktop->flags = inbufflags | INP_ALCONT;
655 if ((instacktop->alias = inalias))
656 inalias->inuse = 1;
657 } else {
658 instacktop->alias = NULL;
659 /* If we are continuing an alias expansion, record the alias
660 * expansion in new set of flags (do we need this?)
661 */
662 if (((instacktop->flags = inbufflags) & INP_ALIAS) &&
663 (flags & INP_CONT))
664 flags |= INP_ALIAS;
665 }
666
667 instacktop++;
668 if (instacktop == instack + instacksz) {
669 /* Expand the stack */
670 instack = (struct instacks *)
671 realloc(instack,
672 (instacksz + INSTACK_EXPAND)*sizeof(struct instacks));
673 instacktop = instack + instacksz;
674 instacksz += INSTACK_EXPAND;
675 }
676 /*
677 * We maintain the entry above the highest one with real
678 * text as a flag to inungetc() that it can stop re-pushing the stack.
679 */
680 instacktop->flags = 0;
681
682 inbufpush = inbuf = NULL;
683
684 inputsetline(str, flags);
685 }
686
687 /* Remove the top element of the stack */
688
689 /**/
690 static void
inpoptop(void)691 inpoptop(void)
692 {
693 if (!lexstop) {
694 inbufflags &= ~(INP_ALCONT|INP_HISTCONT);
695 while (inbufptr > inbuf) {
696 inbufptr--;
697 inbufct++;
698 inbufleft++;
699 /*
700 * As elsewhere in input and history mechanisms:
701 * unwinding aliases and unwinding history have different
702 * implications as aliases are after the lexer while
703 * history is before, but they're both pushed onto
704 * the input stack.
705 */
706 if ((inbufflags & (INP_ALIAS|INP_HIST|INP_RAW_KEEP)) == INP_ALIAS)
707 zshlex_raw_back();
708 }
709 }
710
711 if (inbuf && (inbufflags & INP_FREE))
712 free(inbuf);
713
714 instacktop--;
715
716 inbuf = instacktop->buf;
717 inbufptr = inbufpush = instacktop->bufptr;
718 inbufleft = instacktop->bufleft;
719 inbufct = instacktop->bufct;
720 inbufflags = instacktop->flags;
721
722 if (!(inbufflags & (INP_ALCONT|INP_HISTCONT)))
723 return;
724
725 if (instacktop->alias) {
726 char *t = instacktop->alias->text;
727 /* a real alias: mark it as unused. */
728 instacktop->alias->inuse = 0;
729 if (*t && t[strlen(t) - 1] == ' ') {
730 inalmore = 1;
731 histbackword();
732 }
733 }
734 }
735
736 /* Remove the top element of the stack and all its continuations. */
737
738 /**/
739 mod_export void
inpop(void)740 inpop(void)
741 {
742 int remcont;
743
744 do {
745 remcont = inbufflags & INP_CONT;
746
747 inpoptop();
748 } while (remcont);
749 }
750
751 /*
752 * Expunge any aliases from the input stack; they shouldn't appear
753 * in the history and need to be flushed explicitly when we encounter
754 * an error.
755 */
756
757 /**/
758 void
inpopalias(void)759 inpopalias(void)
760 {
761 while (inbufflags & INP_ALIAS)
762 inpoptop();
763 }
764
765
766 /*
767 * Get pointer to remaining string to read.
768 */
769
770 /**/
771 char *
ingetptr(void)772 ingetptr(void)
773 {
774 return inbufptr;
775 }
776
777 /*
778 * Check if the current input line, including continuations, is
779 * expanding an alias. This does not detect alias expansions that
780 * have been fully processed and popped from the input stack.
781 * If there is an alias, the most recently expanded is returned,
782 * else NULL.
783 */
784
785 /**/
input_hasalias(void)786 char *input_hasalias(void)
787 {
788 int flags = inbufflags;
789 struct instacks *instackptr = instacktop;
790
791 for (;;)
792 {
793 if (!(flags & INP_CONT))
794 break;
795 DPUTS(instackptr == instack, "BUG: continuation at bottom of instack");
796 instackptr--;
797 if (instackptr->alias)
798 return instackptr->alias->node.nam;
799 flags = instackptr->flags;
800 }
801
802 return NULL;
803 }
804