Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 7u83 1
/*
2
 * This code contains changes by
3
 *      Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved.
4
 *
5
 * Conditions 1, 2, and 4 and the no-warranty notice below apply
6
 * to these changes.
7
 *
8
 *
9
 * Copyright (c) 1980, 1993
10
 * 	The Regents of the University of California.  All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions
14
 * are met:
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions and the following disclaimer.
17
 * 2. Redistributions in binary form must reproduce the above copyright
18
 *    notice, this list of conditions and the following disclaimer in the
19
 *    documentation and/or other materials provided with the distribution.
20
 * 3. All advertising materials mentioning features or use of this software
21
 *    must display the following acknowledgement:
22
 * 	This product includes software developed by the University of
23
 * 	California, Berkeley and its contributors.
24
 * 4. Neither the name of the University nor the names of its contributors
25
 *    may be used to endorse or promote products derived from this software
26
 *    without specific prior written permission.
27
 *
28
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38
 * SUCH DAMAGE.
39
 *
40
 *
41
 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
42
 *
43
 * Redistribution and use in source and binary forms, with or without
44
 * modification, are permitted provided that the following conditions
45
 * are met:
46
 *   Redistributions of source code and documentation must retain the
47
 *    above copyright notice, this list of conditions and the following
48
 *    disclaimer.
49
 *   Redistributions in binary form must reproduce the above copyright
50
 *    notice, this list of conditions and the following disclaimer in the
51
 *    documentation and/or other materials provided with the distribution.
52
 *   All advertising materials mentioning features or use of this software
53
 *    must display the following acknowledgement:
54
 *      This product includes software developed or owned by Caldera
55
 *      International, Inc.
56
 *   Neither the name of Caldera International, Inc. nor the names of
57
 *    other contributors may be used to endorse or promote products
58
 *    derived from this software without specific prior written permission.
59
 *
60
 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
61
 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
62
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64
 * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
65
 * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
66
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
67
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
68
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
69
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
70
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
71
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72
 */
73
 
74
#ifndef	lint
75
#ifdef	DOSCCS
76
static char sccsid[] = "@(#)ex_cmds.c	1.22 (gritter) 2/18/05";
77
#endif
78
#endif
79
 
80
/* from ex_cmds.c	7.10.1 (2.11BSD) 1996/11/23 */
81
 
82
#include "ex.h"
83
#include "ex_argv.h"
84
#include "ex_temp.h"
85
#include "ex_tty.h"
86
#include "ex_vis.h"
87
 
88
bool	pflag, nflag;
89
int	poffset;
90
 
91
#define	nochng()	lchng = chng
92
 
93
/*
94
 * Main loop for command mode command decoding.
95
 * A few commands are executed here, but main function
96
 * is to strip command addresses, do a little address oriented
97
 * processing and call command routines to do the real work.
98
 */
99
void 
100
commands(int noprompt, int _exitoneof)
101
{
102
	register line *addr;
103
	register int c;
104
	register int lchng;
105
	int given;
106
	int seensemi;
107
	int cnt;
108
	bool hadpr = 0;
109
 
110
	resetflav();
111
	nochng();
112
	for (;;) {
113
		exitoneof = _exitoneof;
114
		/*
115
		 * If dot at last command
116
		 * ended up at zero, advance to one if there is a such.
117
		 */
118
		if (dot <= zero) {
119
			dot = zero;
120
			if (dol > zero)
121
				dot = one;
122
		}
123
		shudclob = 0;
124
 
125
		/*
126
		 * If autoprint or trailing print flags,
127
		 * print the line at the specified offset
128
		 * before the next command.
129
		 */
130
		if (pflag ||
131
		    lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline) {
132
			pflag = 0;
133
			nochng();
134
			if (dol != zero) {
135
				addr1 = addr2 = dot + poffset;
136
				if (addr1 < one || addr1 > dol)
137
error(catgets(catd, 1, 17,
138
		"Offset out-of-bounds|Offset after command too large"));
139
				setdot1();
140
				goto print;
141
			}
142
		}
143
		nochng();
144
 
145
		/*
146
		 * Print prompt if appropriate.
147
		 * If not in global flush output first to prevent
148
		 * going into pfast mode unreasonably.
149
		 */
150
		if (inglobal == 0) {
151
			flush();
152
			if (!hush && value(PROMPT) && !globp && !noprompt && endline) {
153
				putchar(':');
154
				hadpr = 1;
155
			}
156
			TSYNC();
157
		}
158
 
159
		/*
160
		 * Gobble up the address.
161
		 * Degenerate addresses yield ".".
162
		 */
163
		addr2 = 0;
164
		given = seensemi = 0;
165
		do {
166
			addr1 = addr2;
167
			addr = address(0);
168
			c = getcd();
169
			if (addr == 0)
170
				if (c == ',')
171
					addr = dot;
172
				else if (addr1 != 0) {
173
					addr2 = dot;
174
					break;
175
				} else
176
					break;
177
			addr2 = addr;
178
			given++;
179
			if (c == ';') {
180
				c = ',';
181
				dot = addr;
182
				seensemi = 1;
183
			}
184
		} while (c == ',');
185
		if (c == '%') {
186
			/* %: same as 1,$ */
187
			addr1 = one;
188
			addr2 = dol;
189
			given = 2;
190
			c = getchar();
191
		}
192
		if (addr1 == 0)
193
			addr1 = addr2;
194
		if (c == ':')
195
			c = getchar();
196
 
197
		/*
198
		 * Set command name for special character commands.
199
		 */
200
		tailspec(c);
201
 
202
		/*
203
		 * If called via : escape from open or visual, limit
204
		 * the set of available commands here to save work below.
205
		 */
206
		if (inopen) {
207
			if (c=='\n' || c=='\r' || c==CTRL('d') || c==EOF) {
208
				if (addr2)
209
					dot = addr2;
210
				if (c == EOF)
211
					return;
212
				continue;
213
			}
214
			if (any(c, "o"))
215
notinvis:
216
				tailprim(Command, 1, 1);
217
		}
218
/* choice: */
219
		switch (c) {
220
 
221
		case 'a':
222
 
223
			switch(peekchar()) {
224
			case 'b':
225
/* abbreviate */
226
				tail("abbreviate");
227
				setnoaddr();
228
				mapcmd(0, 1);
229
				anyabbrs = 1;
230
				continue;
231
			case 'r':
232
/* args */
233
				tail("args");
234
				setnoaddr();
235
				eol();
236
				pargs();
237
				continue;
238
			}
239
 
240
/* append */
241
			if (inopen)
242
				goto notinvis;
243
			tail("append");
244
			setdot();
245
			aiflag = exclam();
246
			newline();
247
			vmacchng(0);
248
			deletenone();
249
			setin(addr2);
250
			inappend = 1;
251
			ignore(append(gettty, addr2));
252
			inappend = 0;
253
			nochng();
254
			continue;
255
 
256
		case 'c':
257
			switch (peekchar()) {
258
 
259
/* copy */
260
			case 'o':
261
				tail("copy");
262
				vmacchng(0);
263
				move();
264
				continue;
265
 
266
#ifdef CHDIR
267
/* cd */
268
			case 'd':
269
				tail("cd");
270
				goto changdir;
271
 
272
/* chdir */
273
			case 'h':
274
				ignchar();
275
				if (peekchar() == 'd') {
276
					register char *p;
277
					tail2of("chdir");
278
changdir:
279
					if (savedfile[0] == '/' || !value(WARN))
280
						ignore(exclam());
281
					else
282
						ignore(quickly());
283
					if (skipend()) {
284
						p = getenv("HOME");
285
						if (p == NULL)
286
							error(catgets(catd, 1,
287
						18, "Home directory unknown"));
288
					} else
289
						getone(), p = file;
290
					eol();
291
					if (chdir(p) < 0)
292
						filioerr(p);
293
					if (savedfile[0] != '/')
294
						edited = 0;
295
					continue;
296
				}
297
				if (inopen)
298
					tailprim("change", 2, 1);
299
				tail2of("change");
300
				break;
301
 
302
#endif
303
			default:
304
				if (inopen)
305
					goto notinvis;
306
				tail("change");
307
				break;
308
			}
309
/* change */
310
			aiflag = exclam();
311
			setCNL();
312
			vmacchng(0);
313
			setin(addr1);
314
			delete(0);
315
			inappend = 1;
316
			ignore(append(gettty, addr1 - 1));
317
			inappend = 0;
318
			nochng();
319
			continue;
320
 
321
/* delete */
322
		case 'd':
323
			/*
324
			 * Caution: dp and dl have special meaning already.
325
			 */
326
			tail("delete");
327
			c = cmdreg();
328
			setCNL();
329
			vmacchng(0);
330
			if (c)
331
				YANKreg(c);
332
			delete(0);
333
			appendnone();
334
			vkillDEL();
335
			continue;
336
 
337
/* edit */
338
/* ex */
339
		case 'e':
340
			tail(peekchar() == 'x' ? "ex" : "edit");
341
editcmd:
342
			if (!exclam() && chng)
343
				c = 'E';
344
			filename(c);
345
			if (c == 'E') {
346
				ungetchar(lastchar());
347
				ignore(quickly());
348
			}
349
			setnoaddr();
350
doecmd:
351
			init();
352
			addr2 = zero;
353
			laste++;
354
			synced();
355
			rop(c);
356
#ifdef INCORB
357
			tlaste();
358
#endif
359
			laste = 0;
360
			synced();
361
			nochng();
362
			continue;
363
 
364
/* file */
365
		case 'f':
366
			tail("file");
367
			setnoaddr();
368
			filename(c);
369
			noonl();
370
/*
371
			synctmp();
372
*/
373
			continue;
374
 
375
/* global */
376
		case 'g':
377
			tail("global");
378
			global(!exclam());
379
			nochng();
380
			continue;
381
 
382
/* insert */
383
		case 'i':
384
			if (inopen)
385
				goto notinvis;
386
			tail("insert");
387
			setdot();
388
			nonzero();
389
			aiflag = exclam();
390
			newline();
391
			vmacchng(0);
392
			deletenone();
393
			setin(addr2);
394
			inappend = 1;
395
			ignore(append(gettty, addr2 - 1));
396
			inappend = 0;
397
			if (dot == zero && dol > zero)
398
				dot = one;
399
			nochng();
400
			continue;
401
 
402
/* join */
403
		case 'j':
404
			tail("join");
405
			c = exclam();
406
			setcount();
407
			nonzero();
408
			newline();
409
			vmacchng(0);
410
			if (given < 2 && addr2 != dol)
411
				addr2++;
412
			join(c);
413
			continue;
414
 
415
/* k */
416
		case 'k':
417
casek:
418
			pastwh();
419
			c = getchar();
420
			if (endcmd(c))
421
				serror(catgets(catd, 1, 19,
422
		"Mark what?|%s requires following letter"), Command);
423
			newline();
424
			if (!islower(c))
425
				error(catgets(catd, 1, 20,
426
				"Bad mark|Mark must specify a letter"));
427
			setdot();
428
			nonzero();
429
			names[c - 'a'] = *addr2 &~ 01;
430
			anymarks = 1;
431
			continue;
432
 
433
/* list */
434
		case 'l':
435
			tail("list");
436
			setCNL();
437
			ignorf(setlist(1));
438
			pflag = 0;
439
			goto print;
440
 
441
		case 'm':
442
			if (peekchar() == 'a') {
443
				ignchar();
444
				if (peekchar() == 'p') {
445
/* map */
446
					tail2of("map");
447
					setnoaddr();
448
					mapcmd(0, 0);
449
					continue;
450
				}
451
/* mark */
452
				tail2of("mark");
453
				goto casek;
454
			}
455
/* move */
456
			tail("move");
457
			vmacchng(0);
458
			move();
459
			continue;
460
 
461
		case 'n':
462
			if (peekchar() == 'u') {
463
				tail("number");
464
				goto numberit;
465
			}
466
/* next */
467
			tail("next");
468
			setnoaddr();
469
			if (!exclam())
470
				ckaw();
471
			ignore(quickly());
472
			if (getargs())
473
				makargs();
474
			next();
475
			c = 'e';
476
			filename(c);
477
			if (recov)
478
				goto recovnext;
479
			goto doecmd;
480
 
481
/* open */
482
		case 'o':
483
			tail("open");
484
			oop();
485
			pflag = 0;
486
			nochng();
487
			continue;
488
 
489
		case 'p':
490
		case 'P':
491
			switch (peekchar()) {
492
 
493
/* put */
494
			case 'u':
495
				tail("put");
496
				setdot();
497
				c = cmdreg();
498
				eol();
499
				vmacchng(0);
500
				if (c)
501
					putreg(c);
502
				else
503
					put(0);
504
				continue;
505
 
506
			case 'r':
507
				ignchar();
508
				if (peekchar() == 'e') {
509
/* preserve */
510
					tail2of("preserve");
511
					eol();
512
					if (preserve() == 0)
513
						error(catgets(catd, 1, 21,
514
							"Preserve failed!"));
515
					else
516
						error(catgets(catd, 1, 22,
517
							"File preserved."));
518
				}
519
				tail2of("print");
520
				break;
521
 
522
			default:
523
				tail("print");
524
				break;
525
			}
526
/* print */
527
			setCNL();
528
			pflag = 0;
529
print:
530
			nonzero();
531
			if (CL && span() > TLINES) {
532
				flush1();
533
				vclear();
534
			}
535
			plines(addr1, addr2, 1);
536
			continue;
537
 
538
/* quit */
539
		case 'q':
540
			tail("quit");
541
			setnoaddr();
542
			c = quickly();
543
			eol();
544
			if (!c)
545
quit:
546
				nomore();
547
			if (inopen) {
548
				vgoto(WECHO, 0);
549
				if (!ateopr())
550
					vnfl();
551
				else {
552
					tostop();
553
				}
554
				flush();
555
				setty(normf);
556
			}
557
			cleanup(1);
558
			exitex(0);
559
 
560
		case 'r':
561
			if (peekchar() == 'e') {
562
				ignchar();
563
				switch (peekchar()) {
564
 
565
/* rewind */
566
				case 'w':
567
					tail2of("rewind");
568
					setnoaddr();
569
					if (!exclam()) {
570
						ckaw();
571
						if (chng && dol > zero)
572
							error(catgets(catd,
573
		1, 23, "No write@since last change (:rewind! overrides)"));
574
					}
575
					eol();
576
					erewind();
577
					next();
578
					c = 'e';
579
					ungetchar(lastchar());
580
					filename(c);
581
					goto doecmd;
582
 
583
/* recover */
584
				case 'c':
585
					tail2of("recover");
586
					setnoaddr();
587
					c = 'e';
588
					if (!exclam() && chng)
589
						c = 'E';
590
					filename(c);
591
					if (c == 'E') {
592
						ungetchar(lastchar());
593
						ignore(quickly());
594
					}
595
recovnext:
596
					init();
597
					addr2 = zero;
598
					laste++;
599
					synced();
600
					recover();
601
					rop2();
602
					revocer();
603
					if (status == 0)
604
						rop3(c);
605
					if (dol != zero)
606
						change();
607
#ifdef INCORB
608
					tlaste();
609
#endif
610
					laste = 0;
611
					nochng();
612
					continue;
613
				}
614
				tail2of("read");
615
			} else
616
				tail("read");
617
/* read */
618
			if (savedfile[0] == 0 && dol == zero)
619
				c = 'e';
620
			pastwh();
621
			vmacchng(0);
622
			if (peekchar() == '!') {
623
				setdot();
624
				ignchar();
625
				unix0(0);
626
				filter(0);
627
				continue;
628
			}
629
			filename(c);
630
			rop(c);
631
			nochng();
632
			if (inopen && endline && addr1 > zero && addr1 < dol)
633
				dot = addr1 + 1;
634
			continue;
635
 
636
		case 's':
637
			switch (peekchar()) {
638
			/*
639
			 * Caution: 2nd char cannot be c, g, or r
640
			 * because these have meaning to substitute.
641
			 */
642
 
643
/* set */
644
			case 'e':
645
				tail("set");
646
				setnoaddr();
647
				set();
648
				continue;
649
 
650
/* shell */
651
			case 'h':
652
				tail("shell");
653
				setNAEOL();
654
				vnfl();
655
				putpad(TE);
656
				flush();
657
				unixwt(1, unixex("-i", (char *) 0, 0, 0));
658
				vcontin(0);
659
				continue;
660
 
661
/* source */
662
			case 'o':
663
#ifdef notdef
664
				if (inopen)
665
					goto notinvis;
666
#endif
667
				tail("source");
668
				setnoaddr();
669
				getone();
670
				eol();
671
				source(file, 0);
672
				continue;
673
#ifdef SIGTSTP
674
/* stop, suspend */
675
			case 't':
676
				tail("stop");
677
				goto suspend;
678
			case 'u':
679
				getchar();
680
				if (peekchar() == 'b') {
681
					tail2of("substitute");
682
					goto substitute;
683
				}
684
				tail2of("suspend");
685
suspend:
686
				if (!ldisc)
687
					error(catgets(catd, 1, 24,
688
			"Old tty driver|Not using new tty driver/shell"));
689
				c = exclam();
690
				eol();
691
				if (!c)
692
					ckaw();
693
#ifdef	SIGTSTP
694
				onsusp(SIGTSTP);
695
#endif
696
				continue;
697
#endif
698
 
699
			}
700
			/* fall into ... */
701
 
702
/* & */
703
/* ~ */
704
/* substitute */
705
		case '&':
706
	 	case '~':
707
			Command = "substitute";
708
			if (c == 's')
709
				tail(Command);
710
substitute:
711
			vmacchng(0);
712
			if (!substitute(c))
713
				pflag = 0;
714
			continue;
715
 
716
/* t */
717
		case 't':
718
			if (peekchar() == 'a') {
719
				tail("tag");
720
				tagfind(exclam());
721
				if (!inopen)
722
					lchng = chng - 1;
723
				else
724
					nochng();
725
				continue;
726
			}
727
			tail("t");
728
			vmacchng(0);
729
			move();
730
			continue;
731
 
732
		case 'u':
733
			if (peekchar() == 'n') {
734
				ignchar();
735
				switch(peekchar()) {
736
/* unmap */
737
				case 'm':
738
					tail2of("unmap");
739
					setnoaddr();
740
					mapcmd(1, 0);
741
					continue;
742
/* unabbreviate */
743
				case 'a':
744
					tail2of("unabbreviate");
745
					setnoaddr();
746
					mapcmd(1, 1);
747
					anyabbrs = 1;
748
					continue;
749
				}
750
/* undo */
751
				tail2of("undo");
752
			} else
753
				tail("undo");
754
			setnoaddr();
755
			markDOT();
756
			c = exclam();
757
			newline();
758
			undo(c);
759
			continue;
760
 
761
		case 'v':
762
			switch (peekchar()) {
763
 
764
			case 'e':
765
/* version */
766
				tail("version");
767
				setNAEOL();
768
				printver();
769
				noonl();
770
				continue;
771
 
772
/* visual */
773
			case 'i':
774
				tail("visual");
775
				if (inopen) {
776
					c = 'e';
777
					goto editcmd;
778
				}
779
				vop();
780
				pflag = 0;
781
				nochng();
782
				continue;
783
			}
784
/* v */
785
			tail("v");
786
			global(0);
787
			nochng();
788
			continue;
789
 
790
/* write */
791
		case 'w':
792
			c = peekchar();
793
			tail(c == 'q' ? "wq" : "write");
794
wq:
795
			if (skipwh() && peekchar() == '!') {
796
				pofix();
797
				ignchar();
798
				setall();
799
				unix0(0);
800
				filter(1);
801
			} else {
802
				setall();
803
				wop(1);
804
				nochng();
805
			}
806
			if (c == 'q')
807
				goto quit;
808
			continue;
809
 
810
/* xit */
811
		case 'x':
812
			tail("xit");
813
			if (!chng)
814
				goto quit;
815
			c = 'q';
816
			goto wq;
817
 
818
/* yank */
819
		case 'y':
820
			tail("yank");
821
			c = cmdreg();
822
			setcount();
823
			eol();
824
			vmacchng(0);
825
			if (c)
826
				YANKreg(c);
827
			else
828
				yank(0);
829
			vkillDEL();
830
			continue;
831
 
832
/* z */
833
		case 'z':
834
			zop(0);
835
			pflag = 0;
836
			continue;
837
 
838
/* * */
839
/* @ */
840
		case '*':
841
		case '@':
842
			c = getchar();
843
			if (c=='\n' || c=='\r')
844
				ungetchar(c);
845
			if (any(c, "@*\n\r")) {
846
				c = lastmac;
847
				if (c == 0)
848
					failed = 1;
849
			}
850
			if (isupper(c))
851
				c = tolower(c);
852
			if (!islower(c))
853
				error(catgets(catd, 1, 25, "Bad register"));
854
			newline();
855
			setdot();
856
			cmdmac(c);
857
			continue;
858
 
859
/* | */
860
		case '|':
861
			endline = 0;
862
			goto caseline;
863
 
864
/* \n */
865
		case '\n':
866
			endline = 1;
867
caseline:
868
			notempty();
869
			if (addr2 == 0) {
870
				if (UP != NOSTR && c == '\n' && !inglobal)
871
					c = CTRL('k');
872
				if (inglobal)
873
					addr1 = addr2 = dot;
874
				else {
875
					if (dot == dol)
876
						error(catgets(catd, 1, 26,
877
						"At EOF|At end-of-file"));
878
					addr1 = addr2 = dot + 1;
879
				}
880
			}
881
			setdot();
882
			nonzero();
883
			if (seensemi)
884
				addr1 = addr2;
885
			getline(*addr1);
886
			if (c == CTRL('k')) {
887
				flush1();
888
				destline--;
889
				if (hadpr)
890
					shudclob = 1;
891
			}
892
			plines(addr1, addr2, 1);
893
			continue;
894
 
895
/* " */
896
		case '"':
897
			comment();
898
			continue;
899
 
900
/* # */
901
		case '#':
902
numberit:
903
			setCNL();
904
			ignorf(setnumb(1));
905
			pflag = 0;
906
			goto print;
907
 
908
/* = */
909
		case '=':
910
			newline();
911
			setall();
912
			if (inglobal == 2)
913
				pofix();
914
			printf("%d", lineno(addr2));
915
			noonl();
916
			continue;
917
 
918
/* ! */
919
		case '!':
920
			if (addr2 != 0) {
921
				vmacchng(0);
922
				unix0(0);
923
				setdot();
924
				filter(2);
925
			} else {
926
				unix0(1);
927
				pofix();
928
				putpad(TE);
929
				flush();
930
				unixwt(1, unixex("-c", uxb, 0, 0));
931
				vclrech(1);	/* vcontin(0); */
932
				nochng();
933
			}
934
			continue;
935
 
936
/* < */
937
/* > */
938
		case '<':
939
		case '>':
940
			for (cnt = 1; peekchar() == c; cnt++)
941
				ignchar();
942
			setCNL();
943
			vmacchng(0);
944
			shift(c, cnt);
945
			continue;
946
 
947
/* ^D */
948
/* EOF */
949
		case CTRL('d'):
950
		case EOF:
951
			if (exitoneof) {
952
				if (addr2 != 0)
953
					dot = addr2;
954
				return;
955
			}
956
			if (!isatty(0)) {
957
				if (intty)
958
					/*
959
					 * Chtty sys call at UCB may cause a
960
					 * input which was a tty to suddenly be
961
					 * turned into /dev/null.
962
					 */
963
					onhup(SIGHUP);
964
				return;
965
			}
966
			if (addr2 != 0) {
967
				setlastchar('\n');
968
				putnl();
969
			}
970
			if (dol == zero) {
971
				if (addr2 == 0)
972
					putnl();
973
				notempty();
974
			}
975
			ungetchar(EOF);
976
			zop(hadpr);
977
			continue;
978
 
979
		default:
980
			if (!isalpha(c) && (c&0200) == 0)
981
				break;
982
			ungetchar(c);
983
			tailprim("", 0, 0);
984
		}
985
		error(catgets(catd, 1, 27,
986
				"What?|Unknown command character '%c'"), c);
987
	}
988
}