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

Defined functions

cmdreg defined in line 19; used 3 times
erewind defined in line 87; used 3 times
error defined in line 66; used 3 times
error0 defined in line 108; used 2 times
error1 defined in line 162; used 2 times
exclam defined in line 214; used 15 times
fixol defined in line 196; used 2 times
makargs defined in line 227; used 1 times
next defined in line 240; used 2 times
nomore defined in line 314; used 1 times
quickly defined in line 328; used 5 times
resetflav defined in line 346; used 4 times
setflav defined in line 382; used 3 times
tail defined in line 418; used 36 times
tail2of defined in line 425; used 12 times
tailprim defined in line 434; used 5 times
tailspec defined in line 405; used 1 times
vcontin defined in line 472; used 3 times

Defined variables

sccsid defined in line 2; never used
tcommand defined in line 432; used 6 times
Last modified: 1981-07-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1788
Valid CSS Valid XHTML 1.0 Strict