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