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