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