delete decryption for the foreign sites
[unix-history] / usr / src / usr.bin / ex / ex_cmds2.c
CommitLineData
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 8static char *sccsid = "@(#)ex_cmds2.c 7.4 (Berkeley) %G%";
19d73a0e
DF
9#endif not lint
10
7df0b7cf
MH
11#include "ex.h"
12#include "ex_argv.h"
13#include "ex_temp.h"
14#include "ex_tty.h"
15#include "ex_vis.h"
16
299f2784
MH
17extern bool pflag, nflag; /* mjm: extern; also in ex_cmds.c */
18extern int poffset; /* mjm: extern; also in ex_cmds.c */
7df0b7cf
MH
19
20/*
21 * Subroutines for major command loop.
22 */
23
24/*
25 * Is there a single letter indicating a named buffer next?
26 */
27cmdreg()
28{
29 register int c = 0;
30 register int wh = skipwh();
31
32 if (wh && isalpha(peekchar()))
33 c = getchar();
34 return (c);
35}
36
37/*
38 * Tell whether the character ends a command
39 */
40endcmd(ch)
41 int ch;
42{
43 switch (ch) {
44
45 case '\n':
46 case EOF:
47 endline = 1;
48 return (1);
49
50 case '|':
d266c416 51 case '"':
7df0b7cf
MH
52 endline = 0;
53 return (1);
54 }
55 return (0);
56}
57
58/*
59 * Insist on the end of the command.
60 */
61eol()
62{
63
64 if (!skipend())
65 error("Extra chars|Extra characters at end of command");
66 ignnEOF();
67}
68
69/*
70 * Print out the message in the error message file at str,
71 * with i an integer argument to printf.
72 */
73/*VARARGS2*/
74error(str, i)
75#ifdef lint
76 register char *str;
77#else
78 register int str;
79#endif
80 int i;
81{
82
83 error0();
84 merror(str, i);
04379bab
MH
85 if (writing) {
86 serror(" [Warning - %s is incomplete]", file);
87 writing = 0;
88 }
7df0b7cf
MH
89 error1(str);
90}
91
92/*
93 * Rewind the argument list.
94 */
95erewind()
96{
97
98 argc = argc0;
99 argv = argv0;
100 args = args0;
101 if (argc > 1 && !hush) {
102 printf(mesg("%d files@to edit"), argc);
103 if (inopen)
104 putchar(' ');
105 else
106 putNFL();
107 }
108}
109
110/*
111 * Guts of the pre-printing error processing.
112 * If in visual and catching errors, then we dont mung up the internals,
113 * just fixing up the echo area for the print.
114 * Otherwise we reset a number of externals, and discard unused input.
115 */
116error0()
117{
118
119 if (vcatch) {
120 if (splitw == 0)
121 fixech();
122 if (!SO || !SE)
123 dingdong();
124 return;
125 }
126 if (input) {
127 input = strend(input) - 1;
128 if (*input == '\n')
129 setlastchar('\n');
130 input = 0;
131 }
132 setoutt();
133 flush();
134 resetflav();
7df0b7cf
MH
135 if (!SO || !SE)
136 dingdong();
137 if (inopen) {
138 /*
139 * We are coming out of open/visual ungracefully.
140 * Restore COLUMNS, undo, and fix tty mode.
141 */
142 COLUMNS = OCOLUMNS;
143 undvis();
144 ostop(normf);
d266c416 145 /* ostop should be doing this
7df0b7cf
MH
146 putpad(VE);
147 putpad(KE);
d266c416 148 */
7df0b7cf
MH
149 putnl();
150 }
151 inopen = 0;
152 holdcm = 0;
153}
154
155/*
156 * Post error printing processing.
157 * Close the i/o file if left open.
158 * If catching in visual then throw to the visual catch,
159 * else if a child after a fork, then exit.
160 * Otherwise, in the normal command mode error case,
161 * finish state reset, and throw to top.
162 */
163error1(str)
164 char *str;
165{
166 bool die;
167
168 if (io > 0) {
169 close(io);
170 io = -1;
171 }
172 die = (getpid() != ppid); /* Only children die */
d266c416 173 inappend = inglobal = 0;
887e3e0d 174 globp = vglobp = vmacp = 0;
7df0b7cf 175 if (vcatch && !die) {
7df0b7cf
MH
176 inopen = 1;
177 vcatch = 0;
887e3e0d
MH
178 if (str)
179 noonl();
7df0b7cf
MH
180 fixol();
181 longjmp(vreslab,1);
182 }
183 if (str && !vcatch)
184 putNFL();
185 if (die)
186 exit(1);
187 lseek(0, 0L, 2);
188 if (inglobal)
189 setlastchar('\n');
7df0b7cf
MH
190 while (lastchar() != '\n' && lastchar() != EOF)
191 ignchar();
192 ungetchar(0);
193 endline = 1;
194 reset();
195}
196
197fixol()
198{
199 if (Outchar != vputchar) {
200 flush();
201 if (state == ONEOPEN || state == HARDOPEN)
202 outline = destline = 0;
203 Outchar = vputchar;
204 vcontin(1);
205 } else {
206 if (destcol)
207 vclreol();
208 vclean();
209 }
210}
211
212/*
213 * Does an ! character follow in the command stream?
214 */
215exclam()
216{
217
218 if (peekchar() == '!') {
219 ignchar();
220 return (1);
221 }
222 return (0);
223}
224
225/*
226 * Make an argument list for e.g. next.
227 */
228makargs()
229{
230
231 glob(&frob);
232 argc0 = frob.argc0;
233 argv0 = frob.argv;
234 args0 = argv0[0];
235 erewind();
236}
237
238/*
239 * Advance to next file in argument list.
240 */
241next()
242{
d266c416 243 extern short isalt; /* defined in ex_io.c */
7df0b7cf
MH
244
245 if (argc == 0)
246 error("No more files@to edit");
247 morargc = argc;
d266c416 248 isalt = (strcmp(altfile, args)==0) + 1;
7df0b7cf
MH
249 if (savedfile[0])
250 CP(altfile, savedfile);
251 CP(savedfile, args);
252 argc--;
253 args = argv ? *++argv : strend(args) + 1;
254}
255
256/*
257 * Eat trailing flags and offsets after a command,
258 * saving for possible later post-command prints.
259 */
260newline()
261{
262 register int c;
263
264 resetflav();
265 for (;;) {
266 c = getchar();
267 switch (c) {
268
269 case '^':
270 case '-':
271 poffset--;
272 break;
273
274 case '+':
275 poffset++;
276 break;
277
278 case 'l':
279 listf++;
280 break;
281
282 case '#':
283 nflag++;
284 break;
285
286 case 'p':
287 listf = 0;
288 break;
289
290 case ' ':
291 case '\t':
292 continue;
293
d266c416
MH
294 case '"':
295 comment();
296 setflav();
297 return;
298
7df0b7cf
MH
299 default:
300 if (!endcmd(c))
301serror("Extra chars|Extra characters at end of \"%s\" command", Command);
302 if (c == EOF)
303 ungetchar(c);
304 setflav();
305 return;
306 }
307 pflag++;
308 }
309}
310
311/*
312 * Before quit or respec of arg list, check that there are
313 * no more files in the arg list.
314 */
315nomore()
316{
317
318 if (argc == 0 || morargc == argc)
319 return;
320 morargc = argc;
321 merror("%d more file", argc);
322 serror("%s@to edit", plural((long) argc));
323}
324
325/*
326 * Before edit of new file check that either an ! follows
327 * or the file has not been changed.
328 */
329quickly()
330{
331
332 if (exclam())
333 return (1);
334 if (chng && dol > zero) {
335/*
336 chng = 0;
337*/
338 xchng = 0;
339 error("No write@since last change (:%s! overrides)", Command);
340 }
341 return (0);
342}
343
344/*
345 * Reset the flavor of the output to print mode with no numbering.
346 */
347resetflav()
348{
349
350 if (inopen)
351 return;
352 listf = 0;
353 nflag = 0;
354 pflag = 0;
355 poffset = 0;
356 setflav();
357}
358
359/*
360 * Print an error message with a %s type argument to printf.
361 * Message text comes from error message file.
362 */
363serror(str, cp)
364#ifdef lint
365 register char *str;
366#else
367 register int str;
368#endif
369 char *cp;
370{
371
372 error0();
373 smerror(str, cp);
374 error1(str);
375}
376
377/*
378 * Set the flavor of the output based on the flags given
379 * and the number and list options to either number or not number lines
380 * and either use normally decoded (ARPAnet standard) characters or list mode,
381 * where end of lines are marked and tabs print as ^I.
382 */
383setflav()
384{
385
386 if (inopen)
387 return;
388 setnumb(nflag || value(NUMBER));
389 setlist(listf || value(LIST));
390 setoutt();
391}
392
393/*
394 * Skip white space and tell whether command ends then.
395 */
396skipend()
397{
398
399 pastwh();
d266c416 400 return (endcmd(peekchar()) && peekchar() != '"');
7df0b7cf
MH
401}
402
403/*
404 * Set the command name for non-word commands.
405 */
406tailspec(c)
407 int c;
408{
409 static char foocmd[2];
410
411 foocmd[0] = c;
412 Command = foocmd;
413}
414
415/*
416 * Try to read off the rest of the command word.
417 * If alphabetics follow, then this is not the command we seek.
418 */
419tail(comm)
420 char *comm;
421{
422
423 tailprim(comm, 1, 0);
424}
425
426tail2of(comm)
427 char *comm;
428{
429
430 tailprim(comm, 2, 0);
431}
432
433char tcommand[20];
434
435tailprim(comm, i, notinvis)
436 register char *comm;
437 int i;
438 bool notinvis;
439{
440 register char *cp;
441 register int c;
442
443 Command = comm;
444 for (cp = tcommand; i > 0; i--)
445 *cp++ = *comm++;
446 while (*comm && peekchar() == *comm)
447 *cp++ = getchar(), comm++;
448 c = peekchar();
449 if (notinvis || isalpha(c)) {
450 /*
451 * Of the trailing lp funny business, only dl and dp
452 * survive the move from ed to ex.
453 */
454 if (tcommand[0] == 'd' && any(c, "lp"))
455 goto ret;
456 if (tcommand[0] == 's' && any(c, "gcr"))
457 goto ret;
458 while (cp < &tcommand[19] && isalpha(peekchar()))
459 *cp++ = getchar();
460 *cp = 0;
461 if (notinvis)
462 serror("What?|%s: No such command from open/visual", tcommand);
463 else
464 serror("What?|%s: Not an editor command", tcommand);
465 }
466ret:
467 *cp = 0;
468}
469
470/*
887e3e0d 471 * Continue after a : command from open/visual.
7df0b7cf
MH
472 */
473vcontin(ask)
474 bool ask;
475{
476
477 if (vcnt > 0)
478 vcnt = -vcnt;
479 if (inopen) {
480 if (state != VISUAL) {
887e3e0d
MH
481 /*
482 * We don't know what a shell command may have left on
483 * the screen, so we move the cursor to the right place
484 * and then put out a newline. But this makes an extra
485 * blank line most of the time so we only do it for :sh
486 * since the prompt gets left on the screen.
487 *
488 * BUG: :!echo longer than current line \\c
489 * will screw it up, but be reasonable!
490 */
491 if (state == CRTOPEN) {
492 termreset();
493 vgoto(WECHO, 0);
494 }
495 if (!ask) {
496 putch('\r');
497 putch('\n');
498 }
7df0b7cf
MH
499 return;
500 }
501 if (ask) {
502 merror("[Hit return to continue] ");
503 flush();
504 }
505#ifndef CBREAK
506 vraw();
507#endif
508 if (ask) {
887e3e0d 509#ifdef EATQS
7df0b7cf
MH
510 /*
511 * Gobble ^Q/^S since the tty driver should be eating
512 * them (as far as the user can see)
513 */
514 while (peekkey() == CTRL(Q) || peekkey() == CTRL(S))
515 ignore(getkey());
887e3e0d
MH
516#endif
517 if(getkey() == ':') {
518 /* Ugh. Extra newlines, but no other way */
519 putch('\n');
520 outline = WECHO;
7df0b7cf 521 ungetkey(':');
887e3e0d
MH
522 }
523 }
524 vclrech(1);
d266c416 525 if (Peekkey != ':') {
887e3e0d 526 putpad(TI);
d266c416
MH
527 tostart();
528 /* replaced by ostart.
887e3e0d
MH
529 putpad(VS);
530 putpad(KS);
d266c416 531 */
7df0b7cf 532 }
7df0b7cf
MH
533 }
534}
535
536/*
537 * Put out a newline (before a shell escape)
538 * if in open/visual.
539 */
540vnfl()
541{
542
543 if (inopen) {
544 if (state != VISUAL && state != CRTOPEN && destline <= WECHO)
545 vclean();
546 else
547 vmoveitup(1, 0);
548 vgoto(WECHO, 0);
549 vclrbyte(vtube[WECHO], WCOLS);
d266c416
MH
550 tostop();
551 /* replaced by the ostop above
7df0b7cf
MH
552 putpad(VE);
553 putpad(KE);
d266c416 554 */
7df0b7cf
MH
555 }
556 flush();
557}