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

Defined functions

cmdreg defined in line 18; used 3 times
erewind defined in line 82; used 3 times
error defined in line 65; used 3 times
error0 defined in line 103; used 2 times
error1 defined in line 151; used 2 times
exclam defined in line 204; used 12 times
fixol defined in line 184; used 2 times
makargs defined in line 217; used 1 times
next defined in line 230; used 2 times
nomore defined in line 302; used 1 times
quickly defined in line 316; used 6 times
resetflav defined in line 334; used 4 times
setflav defined in line 370; used 3 times
tail defined in line 406; used 34 times
tail2of defined in line 413; used 7 times
tailprim defined in line 422; used 5 times
tailspec defined in line 393; used 1 times
vcontin defined in line 458; used 3 times

Defined variables

nflag defined in line 8; used 3 times
pflag defined in line 8; used 2 times
poffset defined in line 9; used 3 times
tcommand defined in line 420; used 5 times
Last modified: 1980-09-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1591
Valid CSS Valid XHTML 1.0 Strict