148255Sbostic /*-
2*63046Sbostic * Copyright (c) 1980, 1993
3*63046Sbostic * The Regents of the University of California. All rights reserved.
448255Sbostic *
548255Sbostic * %sccs.include.proprietary.c%
621655Sdist */
721655Sdist
821655Sdist #ifndef lint
9*63046Sbostic static char sccsid[] = "@(#)ex_cmds.c 8.1 (Berkeley) 06/09/93";
1048255Sbostic #endif /* not lint */
1121655Sdist
12431Smark #include "ex.h"
13431Smark #include "ex_argv.h"
14431Smark #include "ex_temp.h"
15431Smark #include "ex_tty.h"
1621680Sdist #include "ex_vis.h"
17431Smark
18431Smark bool pflag, nflag;
19431Smark int poffset;
20431Smark
21431Smark #define nochng() lchng = chng
22431Smark
23431Smark /*
24431Smark * Main loop for command mode command decoding.
25431Smark * A few commands are executed here, but main function
26431Smark * is to strip command addresses, do a little address oriented
27431Smark * processing and call command routines to do the real work.
28431Smark */
commands(noprompt,exitoneof)29431Smark commands(noprompt, exitoneof)
30431Smark bool noprompt, exitoneof;
31431Smark {
32431Smark register line *addr;
33431Smark register int c;
34431Smark register int lchng;
35431Smark int given;
36431Smark int seensemi;
37431Smark int cnt;
38431Smark bool hadpr;
39431Smark
40431Smark resetflav();
41431Smark nochng();
42431Smark for (;;) {
43431Smark /*
44431Smark * If dot at last command
45431Smark * ended up at zero, advance to one if there is a such.
46431Smark */
47431Smark if (dot <= zero) {
48431Smark dot = zero;
49431Smark if (dol > zero)
50431Smark dot = one;
51431Smark }
52431Smark shudclob = 0;
53431Smark
54431Smark /*
55431Smark * If autoprint or trailing print flags,
56431Smark * print the line at the specified offset
57431Smark * before the next command.
58431Smark */
59431Smark if (pflag ||
60431Smark lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline) {
61431Smark pflag = 0;
62431Smark nochng();
63431Smark if (dol != zero) {
64431Smark addr1 = addr2 = dot + poffset;
65431Smark if (addr1 < one || addr1 > dol)
66431Smark error("Offset out-of-bounds|Offset after command too large");
67431Smark setdot1();
68431Smark goto print;
69431Smark }
70431Smark }
71431Smark nochng();
72431Smark
73431Smark /*
74431Smark * Print prompt if appropriate.
75431Smark * If not in global flush output first to prevent
76431Smark * going into pfast mode unreasonably.
77431Smark */
78431Smark if (inglobal == 0) {
79431Smark flush();
80431Smark if (!hush && value(PROMPT) && !globp && !noprompt && endline) {
8130596Sconrad ex_putchar(':');
82431Smark hadpr = 1;
83431Smark }
84431Smark TSYNC();
85431Smark }
86431Smark
87431Smark /*
88431Smark * Gobble up the address.
89431Smark * Degenerate addresses yield ".".
90431Smark */
91431Smark addr2 = 0;
92431Smark given = seensemi = 0;
93431Smark do {
94431Smark addr1 = addr2;
9530596Sconrad addr = address((char *) 0);
96431Smark c = getcd();
97431Smark if (addr == 0)
98431Smark if (c == ',')
99431Smark addr = dot;
100431Smark else if (addr1 != 0) {
101431Smark addr2 = dot;
102431Smark break;
103431Smark } else
104431Smark break;
105431Smark addr2 = addr;
106431Smark given++;
107431Smark if (c == ';') {
108431Smark c = ',';
109431Smark dot = addr;
110431Smark seensemi = 1;
111431Smark }
112431Smark } while (c == ',');
113431Smark if (c == '%') {
114431Smark /* %: same as 1,$ */
115431Smark addr1 = one;
116431Smark addr2 = dol;
117431Smark given = 2;
11830596Sconrad c = ex_getchar();
119431Smark }
120431Smark if (addr1 == 0)
121431Smark addr1 = addr2;
122431Smark if (c == ':')
12330596Sconrad c = ex_getchar();
124431Smark
125431Smark /*
126431Smark * Set command name for special character commands.
127431Smark */
128431Smark tailspec(c);
129431Smark
130431Smark /*
131431Smark * If called via : escape from open or visual, limit
132431Smark * the set of available commands here to save work below.
133431Smark */
134431Smark if (inopen) {
13533222Sbostic if (c=='\n' || c=='\r' || c==CTRL('d') || c==EOF) {
136431Smark if (addr2)
137431Smark dot = addr2;
138431Smark if (c == EOF)
139431Smark return;
140431Smark continue;
141431Smark }
142431Smark if (any(c, "o"))
143431Smark notinvis:
144431Smark tailprim(Command, 1, 1);
145431Smark }
146431Smark switch (c) {
147431Smark
148431Smark case 'a':
149431Smark
150512Smark switch(peekchar()) {
151512Smark case 'b':
152512Smark /* abbreviate */
153512Smark tail("abbreviate");
154512Smark setnoaddr();
155512Smark mapcmd(0, 1);
156512Smark anyabbrs = 1;
157512Smark continue;
158512Smark case 'r':
159431Smark /* args */
160431Smark tail("args");
161431Smark setnoaddr();
162431Smark eol();
163431Smark pargs();
164431Smark continue;
165431Smark }
166431Smark
167431Smark /* append */
168431Smark if (inopen)
169431Smark goto notinvis;
170431Smark tail("append");
171431Smark setdot();
172431Smark aiflag = exclam();
173431Smark newline();
174512Smark vmacchng(0);
175431Smark deletenone();
176431Smark setin(addr2);
177512Smark inappend = 1;
178431Smark ignore(append(gettty, addr2));
179512Smark inappend = 0;
180431Smark nochng();
181431Smark continue;
182431Smark
183431Smark case 'c':
184431Smark switch (peekchar()) {
185431Smark
186431Smark /* copy */
187431Smark case 'o':
188431Smark tail("copy");
189512Smark vmacchng(0);
190431Smark move();
191431Smark continue;
192431Smark
193431Smark #ifdef CHDIR
194431Smark /* cd */
195431Smark case 'd':
196431Smark tail("cd");
197431Smark goto changdir;
198431Smark
199431Smark /* chdir */
200431Smark case 'h':
201431Smark ignchar();
202431Smark if (peekchar() == 'd') {
203431Smark register char *p;
204431Smark tail2of("chdir");
205431Smark changdir:
206431Smark if (savedfile[0] == '/' || !value(WARN))
207431Smark ignore(exclam());
208431Smark else
209431Smark ignore(quickly());
210431Smark if (skipend()) {
211431Smark p = getenv("HOME");
212431Smark if (p == NULL)
213431Smark error("Home directory unknown");
214431Smark } else
215431Smark getone(), p = file;
216431Smark eol();
217431Smark if (chdir(p) < 0)
218431Smark filioerr(p);
219431Smark if (savedfile[0] != '/')
220431Smark edited = 0;
221431Smark continue;
222431Smark }
223431Smark if (inopen)
224431Smark tailprim("change", 2, 1);
225431Smark tail2of("change");
226431Smark break;
227431Smark
228431Smark #endif
229431Smark default:
230431Smark if (inopen)
231431Smark goto notinvis;
232431Smark tail("change");
233431Smark break;
234431Smark }
235431Smark /* change */
236431Smark aiflag = exclam();
237431Smark setCNL();
238512Smark vmacchng(0);
239431Smark setin(addr1);
24030596Sconrad ex_delete(0);
241512Smark inappend = 1;
242431Smark ignore(append(gettty, addr1 - 1));
243512Smark inappend = 0;
244431Smark nochng();
245431Smark continue;
246431Smark
247431Smark /* delete */
248431Smark case 'd':
249431Smark /*
250431Smark * Caution: dp and dl have special meaning already.
251431Smark */
252431Smark tail("delete");
253431Smark c = cmdreg();
254431Smark setCNL();
255512Smark vmacchng(0);
256431Smark if (c)
257431Smark YANKreg(c);
25830596Sconrad ex_delete(0);
259431Smark appendnone();
260431Smark continue;
261431Smark
262431Smark /* edit */
263431Smark /* ex */
264431Smark case 'e':
265431Smark tail(peekchar() == 'x' ? "ex" : "edit");
266512Smark editcmd:
267431Smark if (!exclam() && chng)
268431Smark c = 'E';
269431Smark filename(c);
270431Smark if (c == 'E') {
271431Smark ungetchar(lastchar());
272431Smark ignore(quickly());
273431Smark }
274431Smark setnoaddr();
275431Smark doecmd:
276431Smark init();
277431Smark addr2 = zero;
278431Smark laste++;
27930596Sconrad ex_sync();
280431Smark rop(c);
28121680Sdist #ifdef VMUNIX
28221680Sdist tlaste();
28321680Sdist #endif
28421680Sdist laste = 0;
28530596Sconrad ex_sync();
286431Smark nochng();
287431Smark continue;
288431Smark
289431Smark /* file */
290431Smark case 'f':
291431Smark tail("file");
292431Smark setnoaddr();
293431Smark filename(c);
294431Smark noonl();
295469Smark /*
296431Smark synctmp();
297469Smark */
298431Smark continue;
299431Smark
300431Smark /* global */
301431Smark case 'g':
302431Smark tail("global");
303431Smark global(!exclam());
304431Smark nochng();
305431Smark continue;
306431Smark
307431Smark /* insert */
308431Smark case 'i':
309431Smark if (inopen)
310431Smark goto notinvis;
311431Smark tail("insert");
312431Smark setdot();
313431Smark nonzero();
314431Smark aiflag = exclam();
315431Smark newline();
316512Smark vmacchng(0);
317431Smark deletenone();
318431Smark setin(addr2);
319512Smark inappend = 1;
320431Smark ignore(append(gettty, addr2 - 1));
321512Smark inappend = 0;
322431Smark if (dot == zero && dol > zero)
323431Smark dot = one;
324431Smark nochng();
325431Smark continue;
326431Smark
327431Smark /* join */
328431Smark case 'j':
329431Smark tail("join");
330431Smark c = exclam();
331431Smark setcount();
332431Smark nonzero();
333431Smark newline();
334512Smark vmacchng(0);
335431Smark if (given < 2 && addr2 != dol)
336431Smark addr2++;
337431Smark join(c);
338431Smark continue;
339431Smark
340431Smark /* k */
341431Smark case 'k':
342431Smark casek:
343431Smark pastwh();
34430596Sconrad c = ex_getchar();
345431Smark if (endcmd(c))
346431Smark serror("Mark what?|%s requires following letter", Command);
347431Smark newline();
348431Smark if (!islower(c))
349431Smark error("Bad mark|Mark must specify a letter");
350431Smark setdot();
351431Smark nonzero();
352431Smark names[c - 'a'] = *addr2 &~ 01;
353431Smark anymarks = 1;
354431Smark continue;
355431Smark
356431Smark /* list */
357431Smark case 'l':
358431Smark tail("list");
359431Smark setCNL();
360431Smark ignorf(setlist(1));
361431Smark pflag = 0;
362431Smark goto print;
363431Smark
364431Smark case 'm':
365431Smark if (peekchar() == 'a') {
366431Smark ignchar();
367431Smark if (peekchar() == 'p') {
368431Smark /* map */
369431Smark tail2of("map");
370431Smark setnoaddr();
371512Smark mapcmd(0, 0);
372431Smark continue;
373431Smark }
374431Smark /* mark */
375431Smark tail2of("mark");
376431Smark goto casek;
377431Smark }
378431Smark /* move */
379431Smark tail("move");
380512Smark vmacchng(0);
381431Smark move();
382431Smark continue;
383431Smark
384431Smark case 'n':
385431Smark if (peekchar() == 'u') {
386431Smark tail("number");
387431Smark goto numberit;
388431Smark }
389431Smark /* next */
390431Smark tail("next");
391431Smark setnoaddr();
392431Smark ckaw();
393431Smark ignore(quickly());
394431Smark if (getargs())
395431Smark makargs();
396431Smark next();
397431Smark c = 'e';
398431Smark filename(c);
399431Smark goto doecmd;
400431Smark
401431Smark /* open */
402431Smark case 'o':
403431Smark tail("open");
404431Smark oop();
405431Smark pflag = 0;
406431Smark nochng();
407431Smark continue;
408431Smark
409431Smark case 'p':
410431Smark case 'P':
411431Smark switch (peekchar()) {
412431Smark
413431Smark /* put */
414431Smark case 'u':
415431Smark tail("put");
416431Smark setdot();
417431Smark c = cmdreg();
418431Smark eol();
419512Smark vmacchng(0);
420431Smark if (c)
421431Smark putreg(c);
422431Smark else
423431Smark put();
424431Smark continue;
425431Smark
426431Smark case 'r':
427431Smark ignchar();
428431Smark if (peekchar() == 'e') {
429431Smark /* preserve */
430431Smark tail2of("preserve");
431431Smark eol();
432431Smark if (preserve() == 0)
433431Smark error("Preserve failed!");
434431Smark else
435431Smark error("File preserved.");
436431Smark }
437431Smark tail2of("print");
438431Smark break;
439431Smark
440431Smark default:
441431Smark tail("print");
442431Smark break;
443431Smark }
444431Smark /* print */
445431Smark setCNL();
446431Smark pflag = 0;
447431Smark print:
448431Smark nonzero();
449431Smark if (CL && span() > LINES) {
450431Smark flush1();
451431Smark vclear();
452431Smark }
453431Smark plines(addr1, addr2, 1);
454431Smark continue;
455431Smark
456431Smark /* quit */
457431Smark case 'q':
458431Smark tail("quit");
459431Smark setnoaddr();
460431Smark c = quickly();
461431Smark eol();
462431Smark if (!c)
463431Smark quit:
464431Smark nomore();
465431Smark if (inopen) {
466431Smark vgoto(WECHO, 0);
467431Smark if (!ateopr())
468431Smark vnfl();
469431Smark else {
470512Smark tostop();
471431Smark }
472431Smark flush();
47330596Sconrad ignore(setty(normf));
474431Smark }
475431Smark cleanup(1);
47630596Sconrad ex_exit(0);
477431Smark
478431Smark case 'r':
479431Smark if (peekchar() == 'e') {
480431Smark ignchar();
481431Smark switch (peekchar()) {
482431Smark
483431Smark /* rewind */
484431Smark case 'w':
485431Smark tail2of("rewind");
486431Smark setnoaddr();
487811Smark if (!exclam()) {
488811Smark ckaw();
489811Smark if (chng && dol > zero)
490811Smark error("No write@since last chage (:rewind! overrides)");
491811Smark }
492512Smark eol();
493431Smark erewind();
494431Smark next();
495431Smark c = 'e';
496431Smark ungetchar(lastchar());
497431Smark filename(c);
498431Smark goto doecmd;
499431Smark
500431Smark /* recover */
501431Smark case 'c':
502431Smark tail2of("recover");
503431Smark setnoaddr();
504431Smark c = 'e';
505431Smark if (!exclam() && chng)
506431Smark c = 'E';
507431Smark filename(c);
508431Smark if (c == 'E') {
509431Smark ungetchar(lastchar());
510431Smark ignore(quickly());
511431Smark }
512431Smark init();
513431Smark addr2 = zero;
514431Smark laste++;
51530596Sconrad ex_sync();
516431Smark recover();
517431Smark rop2();
518431Smark revocer();
519431Smark if (status == 0)
520431Smark rop3(c);
521431Smark if (dol != zero)
522431Smark change();
52321680Sdist #ifdef VMUNIX
52421680Sdist tlaste();
52521680Sdist #endif
52621680Sdist laste = 0;
527431Smark nochng();
528431Smark continue;
529431Smark }
530431Smark tail2of("read");
531431Smark } else
532431Smark tail("read");
533431Smark /* read */
534431Smark if (savedfile[0] == 0 && dol == zero)
535431Smark c = 'e';
536431Smark pastwh();
537512Smark vmacchng(0);
538431Smark if (peekchar() == '!') {
539431Smark setdot();
540431Smark ignchar();
541431Smark unix0(0);
542431Smark filter(0);
543431Smark continue;
544431Smark }
545431Smark filename(c);
546431Smark rop(c);
547431Smark nochng();
548431Smark if (inopen && endline && addr1 > zero && addr1 < dol)
549431Smark dot = addr1 + 1;
550431Smark continue;
551431Smark
552431Smark case 's':
553431Smark switch (peekchar()) {
554431Smark /*
555431Smark * Caution: 2nd char cannot be c, g, or r
556431Smark * because these have meaning to substitute.
557431Smark */
558431Smark
559431Smark /* set */
560431Smark case 'e':
561431Smark tail("set");
562431Smark setnoaddr();
563431Smark set();
564431Smark continue;
565431Smark
566431Smark /* shell */
567431Smark case 'h':
568431Smark tail("shell");
569431Smark setNAEOL();
570431Smark vnfl();
571431Smark putpad(TE);
572431Smark flush();
573431Smark unixwt(1, unixex("-i", (char *) 0, 0, 0));
574431Smark vcontin(0);
575431Smark continue;
576431Smark
577431Smark /* source */
578431Smark case 'o':
57921680Sdist #ifdef notdef
580431Smark if (inopen)
581431Smark goto notinvis;
58221680Sdist #endif
583431Smark tail("source");
584431Smark setnoaddr();
585431Smark getone();
586431Smark eol();
587431Smark source(file, 0);
588431Smark continue;
589865Smark #ifdef SIGTSTP
59021680Sdist /* stop, suspend */
591512Smark case 't':
592512Smark tail("stop");
59321680Sdist goto suspend;
59421680Sdist case 'u':
59521680Sdist tail("suspend");
59621680Sdist suspend:
597512Smark c = exclam();
598512Smark eol();
599512Smark if (!c)
600512Smark ckaw();
601512Smark onsusp();
602512Smark continue;
603512Smark #endif
604512Smark
605431Smark }
606431Smark /* fall into ... */
607431Smark
608431Smark /* & */
609431Smark /* ~ */
610431Smark /* substitute */
611431Smark case '&':
612431Smark case '~':
613431Smark Command = "substitute";
614431Smark if (c == 's')
615431Smark tail(Command);
616512Smark vmacchng(0);
617431Smark if (!substitute(c))
618431Smark pflag = 0;
619431Smark continue;
620431Smark
621431Smark /* t */
622431Smark case 't':
623431Smark if (peekchar() == 'a') {
624431Smark tail("tag");
625431Smark tagfind(exclam());
626431Smark if (!inopen)
627431Smark lchng = chng - 1;
628431Smark else
629431Smark nochng();
630431Smark continue;
631431Smark }
632431Smark tail("t");
633512Smark vmacchng(0);
634431Smark move();
635431Smark continue;
636431Smark
637431Smark case 'u':
638431Smark if (peekchar() == 'n') {
639512Smark ignchar();
640512Smark switch(peekchar()) {
641431Smark /* unmap */
642512Smark case 'm':
643431Smark tail2of("unmap");
644431Smark setnoaddr();
645512Smark mapcmd(1, 0);
646431Smark continue;
647512Smark /* unabbreviate */
648512Smark case 'a':
649512Smark tail2of("unabbreviate");
650512Smark setnoaddr();
651512Smark mapcmd(1, 1);
652512Smark anyabbrs = 1;
653512Smark continue;
654431Smark }
655431Smark /* undo */
656431Smark tail2of("undo");
657431Smark } else
658431Smark tail("undo");
659431Smark setnoaddr();
660431Smark markDOT();
661431Smark c = exclam();
662431Smark newline();
663431Smark undo(c);
664431Smark continue;
665431Smark
666431Smark case 'v':
667431Smark switch (peekchar()) {
668431Smark
669431Smark case 'e':
670431Smark /* version */
671431Smark tail("version");
672431Smark setNAEOL();
67330596Sconrad ex_printf("@(#) Version 3.7, 6/7/85."+5);
674431Smark noonl();
675431Smark continue;
676431Smark
677431Smark /* visual */
678431Smark case 'i':
679431Smark tail("visual");
680512Smark if (inopen) {
681512Smark c = 'e';
682512Smark goto editcmd;
683512Smark }
684431Smark vop();
685431Smark pflag = 0;
686431Smark nochng();
687431Smark continue;
688431Smark }
689431Smark /* v */
690431Smark tail("v");
691431Smark global(0);
692431Smark nochng();
693431Smark continue;
694431Smark
695431Smark /* write */
696431Smark case 'w':
697431Smark c = peekchar();
698431Smark tail(c == 'q' ? "wq" : "write");
699487Smark wq:
700431Smark if (skipwh() && peekchar() == '!') {
701487Smark pofix();
702431Smark ignchar();
703431Smark setall();
704431Smark unix0(0);
705431Smark filter(1);
706431Smark } else {
707431Smark setall();
708431Smark wop(1);
709431Smark nochng();
710431Smark }
711431Smark if (c == 'q')
712431Smark goto quit;
713431Smark continue;
714431Smark
715487Smark /* xit */
716487Smark case 'x':
717487Smark tail("xit");
718487Smark if (!chng)
719487Smark goto quit;
720487Smark c = 'q';
721487Smark goto wq;
722487Smark
723431Smark /* yank */
724431Smark case 'y':
725431Smark tail("yank");
726431Smark c = cmdreg();
727431Smark setcount();
728431Smark eol();
729512Smark vmacchng(0);
730431Smark if (c)
731431Smark YANKreg(c);
732431Smark else
733431Smark yank();
734431Smark continue;
735431Smark
736431Smark /* z */
737431Smark case 'z':
738431Smark zop(0);
739431Smark pflag = 0;
740431Smark continue;
741431Smark
742431Smark /* * */
743431Smark /* @ */
744431Smark case '*':
745431Smark case '@':
74630596Sconrad c = ex_getchar();
747431Smark if (c=='\n' || c=='\r')
748431Smark ungetchar(c);
749431Smark if (any(c, "@*\n\r"))
750431Smark c = lastmac;
751431Smark if (isupper(c))
752431Smark c = tolower(c);
753431Smark if (!islower(c))
754431Smark error("Bad register");
755431Smark newline();
756431Smark setdot();
757431Smark cmdmac(c);
758431Smark continue;
759431Smark
760431Smark /* | */
761431Smark case '|':
762431Smark endline = 0;
763431Smark goto caseline;
764431Smark
765431Smark /* \n */
766431Smark case '\n':
767431Smark endline = 1;
768431Smark caseline:
769431Smark notempty();
770431Smark if (addr2 == 0) {
771431Smark if (UP != NOSTR && c == '\n' && !inglobal)
77233222Sbostic c = CTRL('k');
773431Smark if (inglobal)
774431Smark addr1 = addr2 = dot;
775487Smark else {
776487Smark if (dot == dol)
777487Smark error("At EOF|At end-of-file");
778431Smark addr1 = addr2 = dot + 1;
779487Smark }
780431Smark }
781431Smark setdot();
782431Smark nonzero();
783431Smark if (seensemi)
784431Smark addr1 = addr2;
785431Smark getline(*addr1);
78633222Sbostic if (c == CTRL('k')) {
787431Smark flush1();
788431Smark destline--;
789431Smark if (hadpr)
790431Smark shudclob = 1;
791431Smark }
792431Smark plines(addr1, addr2, 1);
793431Smark continue;
794431Smark
795512Smark /* " */
796512Smark case '"':
797512Smark comment();
798512Smark continue;
799512Smark
800431Smark /* # */
801431Smark case '#':
802431Smark numberit:
803431Smark setCNL();
804431Smark ignorf(setnumb(1));
805431Smark pflag = 0;
806431Smark goto print;
807431Smark
808431Smark /* = */
809431Smark case '=':
810431Smark newline();
811431Smark setall();
812487Smark if (inglobal == 2)
813487Smark pofix();
81430596Sconrad ex_printf("%d", lineno(addr2));
815431Smark noonl();
816431Smark continue;
817431Smark
818431Smark /* ! */
819431Smark case '!':
820431Smark if (addr2 != 0) {
821512Smark vmacchng(0);
822431Smark unix0(0);
823431Smark setdot();
824431Smark filter(2);
825431Smark } else {
826431Smark unix0(1);
827487Smark pofix();
828431Smark putpad(TE);
829431Smark flush();
830431Smark unixwt(1, unixex("-c", uxb, 0, 0));
831512Smark vclrech(1); /* vcontin(0); */
832431Smark nochng();
833431Smark }
834431Smark continue;
835431Smark
836431Smark /* < */
837431Smark /* > */
838431Smark case '<':
839431Smark case '>':
840431Smark for (cnt = 1; peekchar() == c; cnt++)
841431Smark ignchar();
842431Smark setCNL();
843512Smark vmacchng(0);
844431Smark shift(c, cnt);
845431Smark continue;
846431Smark
847431Smark /* ^D */
848431Smark /* EOF */
84933222Sbostic case CTRL('d'):
850431Smark case EOF:
851431Smark if (exitoneof) {
852431Smark if (addr2 != 0)
853431Smark dot = addr2;
854431Smark return;
855431Smark }
856431Smark if (!isatty(0)) {
857431Smark if (intty)
858431Smark /*
859431Smark * Chtty sys call at UCB may cause a
860431Smark * input which was a tty to suddenly be
861431Smark * turned into /dev/null.
862431Smark */
863431Smark onhup();
864431Smark return;
865431Smark }
866431Smark if (addr2 != 0) {
867431Smark setlastchar('\n');
868431Smark putnl();
869431Smark }
870431Smark if (dol == zero) {
871431Smark if (addr2 == 0)
872431Smark putnl();
873431Smark notempty();
874431Smark }
875431Smark ungetchar(EOF);
876431Smark zop(hadpr);
877431Smark continue;
878431Smark
879431Smark default:
880431Smark if (!isalpha(c))
881431Smark break;
882431Smark ungetchar(c);
883431Smark tailprim("", 0, 0);
884431Smark }
885431Smark error("What?|Unknown command character '%c'", c);
886431Smark }
887431Smark }
888