Commit | Line | Data |
---|---|---|
2791ff57 | 1 | /*- |
799abc32 KB |
2 | * Copyright (c) 1980, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
2791ff57 KB |
4 | * |
5 | * %sccs.include.proprietary.c% | |
19d73a0e DF |
6 | */ |
7 | ||
8 | #ifndef lint | |
799abc32 | 9 | static char sccsid[] = "@(#)ex_cmds.c 8.1 (Berkeley) %G%"; |
2791ff57 | 10 | #endif /* not lint */ |
19d73a0e | 11 | |
d9fbdd64 MH |
12 | #include "ex.h" |
13 | #include "ex_argv.h" | |
14 | #include "ex_temp.h" | |
15 | #include "ex_tty.h" | |
714bf4c2 | 16 | #include "ex_vis.h" |
d9fbdd64 MH |
17 | |
18 | bool pflag, nflag; | |
19 | int poffset; | |
20 | ||
21 | #define nochng() lchng = chng | |
22 | ||
23 | /* | |
24 | * Main loop for command mode command decoding. | |
25 | * A few commands are executed here, but main function | |
26 | * is to strip command addresses, do a little address oriented | |
27 | * processing and call command routines to do the real work. | |
28 | */ | |
29 | commands(noprompt, exitoneof) | |
30 | bool noprompt, exitoneof; | |
31 | { | |
32 | register line *addr; | |
33 | register int c; | |
34 | register int lchng; | |
35 | int given; | |
36 | int seensemi; | |
37 | int cnt; | |
38 | bool hadpr; | |
39 | ||
40 | resetflav(); | |
41 | nochng(); | |
42 | for (;;) { | |
43 | /* | |
44 | * If dot at last command | |
45 | * ended up at zero, advance to one if there is a such. | |
46 | */ | |
47 | if (dot <= zero) { | |
48 | dot = zero; | |
49 | if (dol > zero) | |
50 | dot = one; | |
51 | } | |
52 | shudclob = 0; | |
53 | ||
54 | /* | |
55 | * If autoprint or trailing print flags, | |
56 | * print the line at the specified offset | |
57 | * before the next command. | |
58 | */ | |
59 | if (pflag || | |
60 | lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline) { | |
61 | pflag = 0; | |
62 | nochng(); | |
63 | if (dol != zero) { | |
64 | addr1 = addr2 = dot + poffset; | |
65 | if (addr1 < one || addr1 > dol) | |
66 | error("Offset out-of-bounds|Offset after command too large"); | |
67 | setdot1(); | |
68 | goto print; | |
69 | } | |
70 | } | |
71 | nochng(); | |
72 | ||
73 | /* | |
74 | * Print prompt if appropriate. | |
75 | * If not in global flush output first to prevent | |
76 | * going into pfast mode unreasonably. | |
77 | */ | |
78 | if (inglobal == 0) { | |
79 | flush(); | |
80 | if (!hush && value(PROMPT) && !globp && !noprompt && endline) { | |
5a6c967e | 81 | ex_putchar(':'); |
d9fbdd64 MH |
82 | hadpr = 1; |
83 | } | |
84 | TSYNC(); | |
85 | } | |
86 | ||
87 | /* | |
88 | * Gobble up the address. | |
89 | * Degenerate addresses yield ".". | |
90 | */ | |
91 | addr2 = 0; | |
92 | given = seensemi = 0; | |
93 | do { | |
94 | addr1 = addr2; | |
5a6c967e | 95 | addr = address((char *) 0); |
d9fbdd64 MH |
96 | c = getcd(); |
97 | if (addr == 0) | |
98 | if (c == ',') | |
99 | addr = dot; | |
100 | else if (addr1 != 0) { | |
101 | addr2 = dot; | |
102 | break; | |
103 | } else | |
104 | break; | |
105 | addr2 = addr; | |
106 | given++; | |
107 | if (c == ';') { | |
108 | c = ','; | |
109 | dot = addr; | |
110 | seensemi = 1; | |
111 | } | |
112 | } while (c == ','); | |
113 | if (c == '%') { | |
114 | /* %: same as 1,$ */ | |
115 | addr1 = one; | |
116 | addr2 = dol; | |
117 | given = 2; | |
5a6c967e | 118 | c = ex_getchar(); |
d9fbdd64 MH |
119 | } |
120 | if (addr1 == 0) | |
121 | addr1 = addr2; | |
122 | if (c == ':') | |
5a6c967e | 123 | c = ex_getchar(); |
d9fbdd64 MH |
124 | |
125 | /* | |
126 | * Set command name for special character commands. | |
127 | */ | |
128 | tailspec(c); | |
129 | ||
130 | /* | |
131 | * If called via : escape from open or visual, limit | |
132 | * the set of available commands here to save work below. | |
133 | */ | |
134 | if (inopen) { | |
65bacefd | 135 | if (c=='\n' || c=='\r' || c==CTRL('d') || c==EOF) { |
d9fbdd64 MH |
136 | if (addr2) |
137 | dot = addr2; | |
138 | if (c == EOF) | |
139 | return; | |
140 | continue; | |
141 | } | |
142 | if (any(c, "o")) | |
143 | notinvis: | |
144 | tailprim(Command, 1, 1); | |
145 | } | |
d9fbdd64 MH |
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 | 239 | setin(addr1); |
5a6c967e | 240 | ex_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); | |
5a6c967e | 258 | ex_delete(0); |
d9fbdd64 MH |
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++; | |
5a6c967e | 279 | ex_sync(); |
d9fbdd64 | 280 | rop(c); |
79086561 RC |
281 | #ifdef VMUNIX |
282 | tlaste(); | |
283 | #endif | |
284 | laste = 0; | |
5a6c967e | 285 | ex_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(); | |
5a6c967e | 344 | c = ex_getchar(); |
d9fbdd64 MH |
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(); | |
5a6c967e | 473 | ignore(setty(normf)); |
d9fbdd64 MH |
474 | } |
475 | cleanup(1); | |
5a6c967e | 476 | ex_exit(0); |
d9fbdd64 MH |
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++; | |
5a6c967e | 515 | ex_sync(); |
d9fbdd64 MH |
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 | c = exclam(); |
598 | eol(); | |
599 | if (!c) | |
600 | ckaw(); | |
d266c416 MH |
601 | onsusp(); |
602 | continue; | |
603 | #endif | |
604 | ||
d9fbdd64 MH |
605 | } |
606 | /* fall into ... */ | |
607 | ||
608 | /* & */ | |
609 | /* ~ */ | |
610 | /* substitute */ | |
611 | case '&': | |
612 | case '~': | |
613 | Command = "substitute"; | |
614 | if (c == 's') | |
615 | tail(Command); | |
d266c416 | 616 | vmacchng(0); |
d9fbdd64 MH |
617 | if (!substitute(c)) |
618 | pflag = 0; | |
619 | continue; | |
620 | ||
621 | /* t */ | |
622 | case 't': | |
623 | if (peekchar() == 'a') { | |
624 | tail("tag"); | |
625 | tagfind(exclam()); | |
626 | if (!inopen) | |
627 | lchng = chng - 1; | |
628 | else | |
629 | nochng(); | |
630 | continue; | |
631 | } | |
632 | tail("t"); | |
d266c416 | 633 | vmacchng(0); |
d9fbdd64 MH |
634 | move(); |
635 | continue; | |
636 | ||
637 | case 'u': | |
638 | if (peekchar() == 'n') { | |
d9fbdd64 | 639 | ignchar(); |
d266c416 MH |
640 | switch(peekchar()) { |
641 | /* unmap */ | |
642 | case 'm': | |
d9fbdd64 MH |
643 | tail2of("unmap"); |
644 | setnoaddr(); | |
d266c416 MH |
645 | mapcmd(1, 0); |
646 | continue; | |
647 | /* unabbreviate */ | |
648 | case 'a': | |
649 | tail2of("unabbreviate"); | |
650 | setnoaddr(); | |
651 | mapcmd(1, 1); | |
652 | anyabbrs = 1; | |
d9fbdd64 MH |
653 | continue; |
654 | } | |
655 | /* undo */ | |
656 | tail2of("undo"); | |
657 | } else | |
658 | tail("undo"); | |
659 | setnoaddr(); | |
660 | markDOT(); | |
661 | c = exclam(); | |
662 | newline(); | |
663 | undo(c); | |
664 | continue; | |
665 | ||
666 | case 'v': | |
667 | switch (peekchar()) { | |
668 | ||
669 | case 'e': | |
670 | /* version */ | |
671 | tail("version"); | |
672 | setNAEOL(); | |
5a6c967e | 673 | ex_printf("@(#) Version 3.7, 6/7/85."+5); |
d9fbdd64 MH |
674 | noonl(); |
675 | continue; | |
676 | ||
677 | /* visual */ | |
678 | case 'i': | |
679 | tail("visual"); | |
d266c416 MH |
680 | if (inopen) { |
681 | c = 'e'; | |
682 | goto editcmd; | |
683 | } | |
d9fbdd64 MH |
684 | vop(); |
685 | pflag = 0; | |
686 | nochng(); | |
687 | continue; | |
688 | } | |
689 | /* v */ | |
690 | tail("v"); | |
691 | global(0); | |
692 | nochng(); | |
693 | continue; | |
694 | ||
695 | /* write */ | |
696 | case 'w': | |
697 | c = peekchar(); | |
698 | tail(c == 'q' ? "wq" : "write"); | |
887e3e0d | 699 | wq: |
d9fbdd64 | 700 | if (skipwh() && peekchar() == '!') { |
887e3e0d | 701 | pofix(); |
d9fbdd64 MH |
702 | ignchar(); |
703 | setall(); | |
704 | unix0(0); | |
705 | filter(1); | |
706 | } else { | |
707 | setall(); | |
708 | wop(1); | |
709 | nochng(); | |
710 | } | |
711 | if (c == 'q') | |
712 | goto quit; | |
713 | continue; | |
714 | ||
887e3e0d MH |
715 | /* xit */ |
716 | case 'x': | |
717 | tail("xit"); | |
718 | if (!chng) | |
719 | goto quit; | |
720 | c = 'q'; | |
721 | goto wq; | |
722 | ||
d9fbdd64 MH |
723 | /* yank */ |
724 | case 'y': | |
725 | tail("yank"); | |
726 | c = cmdreg(); | |
727 | setcount(); | |
728 | eol(); | |
d266c416 | 729 | vmacchng(0); |
d9fbdd64 MH |
730 | if (c) |
731 | YANKreg(c); | |
732 | else | |
733 | yank(); | |
734 | continue; | |
735 | ||
736 | /* z */ | |
737 | case 'z': | |
738 | zop(0); | |
739 | pflag = 0; | |
740 | continue; | |
741 | ||
742 | /* * */ | |
743 | /* @ */ | |
744 | case '*': | |
745 | case '@': | |
5a6c967e | 746 | c = ex_getchar(); |
d9fbdd64 MH |
747 | if (c=='\n' || c=='\r') |
748 | ungetchar(c); | |
749 | if (any(c, "@*\n\r")) | |
750 | c = lastmac; | |
751 | if (isupper(c)) | |
752 | c = tolower(c); | |
753 | if (!islower(c)) | |
754 | error("Bad register"); | |
755 | newline(); | |
756 | setdot(); | |
757 | cmdmac(c); | |
758 | continue; | |
759 | ||
760 | /* | */ | |
761 | case '|': | |
762 | endline = 0; | |
763 | goto caseline; | |
764 | ||
765 | /* \n */ | |
766 | case '\n': | |
767 | endline = 1; | |
768 | caseline: | |
769 | notempty(); | |
770 | if (addr2 == 0) { | |
d9fbdd64 | 771 | if (UP != NOSTR && c == '\n' && !inglobal) |
65bacefd | 772 | c = CTRL('k'); |
d9fbdd64 MH |
773 | if (inglobal) |
774 | addr1 = addr2 = dot; | |
887e3e0d MH |
775 | else { |
776 | if (dot == dol) | |
777 | error("At EOF|At end-of-file"); | |
d9fbdd64 | 778 | addr1 = addr2 = dot + 1; |
887e3e0d | 779 | } |
d9fbdd64 MH |
780 | } |
781 | setdot(); | |
782 | nonzero(); | |
783 | if (seensemi) | |
784 | addr1 = addr2; | |
785 | getline(*addr1); | |
65bacefd | 786 | if (c == CTRL('k')) { |
d9fbdd64 MH |
787 | flush1(); |
788 | destline--; | |
789 | if (hadpr) | |
790 | shudclob = 1; | |
791 | } | |
792 | plines(addr1, addr2, 1); | |
793 | continue; | |
794 | ||
d266c416 MH |
795 | /* " */ |
796 | case '"': | |
797 | comment(); | |
798 | continue; | |
799 | ||
d9fbdd64 MH |
800 | /* # */ |
801 | case '#': | |
802 | numberit: | |
803 | setCNL(); | |
804 | ignorf(setnumb(1)); | |
805 | pflag = 0; | |
806 | goto print; | |
807 | ||
808 | /* = */ | |
809 | case '=': | |
810 | newline(); | |
811 | setall(); | |
887e3e0d MH |
812 | if (inglobal == 2) |
813 | pofix(); | |
5a6c967e | 814 | ex_printf("%d", lineno(addr2)); |
d9fbdd64 MH |
815 | noonl(); |
816 | continue; | |
817 | ||
818 | /* ! */ | |
819 | case '!': | |
820 | if (addr2 != 0) { | |
d266c416 | 821 | vmacchng(0); |
d9fbdd64 MH |
822 | unix0(0); |
823 | setdot(); | |
824 | filter(2); | |
825 | } else { | |
826 | unix0(1); | |
887e3e0d | 827 | pofix(); |
d9fbdd64 MH |
828 | putpad(TE); |
829 | flush(); | |
830 | unixwt(1, unixex("-c", uxb, 0, 0)); | |
d266c416 | 831 | vclrech(1); /* vcontin(0); */ |
d9fbdd64 MH |
832 | nochng(); |
833 | } | |
834 | continue; | |
835 | ||
836 | /* < */ | |
837 | /* > */ | |
838 | case '<': | |
839 | case '>': | |
840 | for (cnt = 1; peekchar() == c; cnt++) | |
841 | ignchar(); | |
842 | setCNL(); | |
d266c416 | 843 | vmacchng(0); |
d9fbdd64 MH |
844 | shift(c, cnt); |
845 | continue; | |
846 | ||
847 | /* ^D */ | |
848 | /* EOF */ | |
65bacefd | 849 | case CTRL('d'): |
d9fbdd64 MH |
850 | case EOF: |
851 | if (exitoneof) { | |
852 | if (addr2 != 0) | |
853 | dot = addr2; | |
854 | return; | |
855 | } | |
856 | if (!isatty(0)) { | |
857 | if (intty) | |
858 | /* | |
859 | * Chtty sys call at UCB may cause a | |
860 | * input which was a tty to suddenly be | |
861 | * turned into /dev/null. | |
862 | */ | |
863 | onhup(); | |
864 | return; | |
865 | } | |
866 | if (addr2 != 0) { | |
867 | setlastchar('\n'); | |
868 | putnl(); | |
869 | } | |
870 | if (dol == zero) { | |
871 | if (addr2 == 0) | |
872 | putnl(); | |
873 | notempty(); | |
874 | } | |
875 | ungetchar(EOF); | |
876 | zop(hadpr); | |
877 | continue; | |
878 | ||
879 | default: | |
880 | if (!isalpha(c)) | |
881 | break; | |
882 | ungetchar(c); | |
883 | tailprim("", 0, 0); | |
884 | } | |
885 | error("What?|Unknown command character '%c'", c); | |
886 | } | |
887 | } |