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