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
   8: static char *sccsid = "@(#)ex_cmds2.c	7.4 (Berkeley) 6/7/85";
   9: #endif not lint
  10: 
  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: 
  17: extern bool pflag, nflag;       /* mjm: extern; also in ex_cmds.c */
  18: extern int  poffset;        /* mjm: extern; also in ex_cmds.c */
  19: 
  20: /*
  21:  * Subroutines for major command loop.
  22:  */
  23: 
  24: /*
  25:  * Is there a single letter indicating a named buffer next?
  26:  */
  27: cmdreg()
  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:  */
  40: endcmd(ch)
  41:     int ch;
  42: {
  43:     switch (ch) {
  44: 
  45:     case '\n':
  46:     case EOF:
  47:         endline = 1;
  48:         return (1);
  49: 
  50:     case '|':
  51:     case '"':
  52:         endline = 0;
  53:         return (1);
  54:     }
  55:     return (0);
  56: }
  57: 
  58: /*
  59:  * Insist on the end of the command.
  60:  */
  61: eol()
  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*/
  74: error(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);
  85:     if (writing) {
  86:         serror(" [Warning - %s is incomplete]", file);
  87:         writing = 0;
  88:     }
  89:     error1(str);
  90: }
  91: 
  92: /*
  93:  * Rewind the argument list.
  94:  */
  95: erewind()
  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:  */
 116: error0()
 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();
 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);
 145:         /* ostop should be doing this
 146: 		putpad(VE);
 147: 		putpad(KE);
 148: 		*/
 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:  */
 163: error1(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 */
 173:     inappend = inglobal = 0;
 174:     globp = vglobp = vmacp = 0;
 175:     if (vcatch && !die) {
 176:         inopen = 1;
 177:         vcatch = 0;
 178:         if (str)
 179:             noonl();
 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');
 190:     while (lastchar() != '\n' && lastchar() != EOF)
 191:         ignchar();
 192:     ungetchar(0);
 193:     endline = 1;
 194:     reset();
 195: }
 196: 
 197: fixol()
 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:  */
 215: exclam()
 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:  */
 228: makargs()
 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:  */
 241: next()
 242: {
 243:     extern short isalt; /* defined in ex_io.c */
 244: 
 245:     if (argc == 0)
 246:         error("No more files@to edit");
 247:     morargc = argc;
 248:     isalt = (strcmp(altfile, args)==0) + 1;
 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:  */
 260: newline()
 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: 
 294:         case '"':
 295:             comment();
 296:             setflav();
 297:             return;
 298: 
 299:         default:
 300:             if (!endcmd(c))
 301: serror("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:  */
 315: nomore()
 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:  */
 329: quickly()
 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:  */
 347: resetflav()
 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:  */
 363: serror(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:  */
 383: setflav()
 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:  */
 396: skipend()
 397: {
 398: 
 399:     pastwh();
 400:     return (endcmd(peekchar()) && peekchar() != '"');
 401: }
 402: 
 403: /*
 404:  * Set the command name for non-word commands.
 405:  */
 406: tailspec(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:  */
 419: tail(comm)
 420:     char *comm;
 421: {
 422: 
 423:     tailprim(comm, 1, 0);
 424: }
 425: 
 426: tail2of(comm)
 427:     char *comm;
 428: {
 429: 
 430:     tailprim(comm, 2, 0);
 431: }
 432: 
 433: char    tcommand[20];
 434: 
 435: tailprim(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:     }
 466: ret:
 467:     *cp = 0;
 468: }
 469: 
 470: /*
 471:  * Continue after a : command from open/visual.
 472:  */
 473: vcontin(ask)
 474:     bool ask;
 475: {
 476: 
 477:     if (vcnt > 0)
 478:         vcnt = -vcnt;
 479:     if (inopen) {
 480:         if (state != VISUAL) {
 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:             }
 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) {
 509: #ifdef EATQS
 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());
 516: #endif
 517:             if(getkey() == ':') {
 518:                 /* Ugh. Extra newlines, but no other way */
 519:                 putch('\n');
 520:                 outline = WECHO;
 521:                 ungetkey(':');
 522:             }
 523:         }
 524:         vclrech(1);
 525:         if (Peekkey != ':') {
 526:             putpad(TI);
 527:             tostart();
 528:             /* replaced by ostart.
 529: 			putpad(VS);
 530: 			putpad(KS);
 531: 			*/
 532:         }
 533:     }
 534: }
 535: 
 536: /*
 537:  * Put out a newline (before a shell escape)
 538:  * if in open/visual.
 539:  */
 540: vnfl()
 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);
 550:         tostop();
 551:         /* replaced by the ostop above
 552: 		putpad(VE);
 553: 		putpad(KE);
 554: 		*/
 555:     }
 556:     flush();
 557: }

Defined functions

cmdreg defined in line 27; used 3 times
erewind defined in line 95; used 3 times
error defined in line 74; used 3 times
error0 defined in line 116; used 2 times
error1 defined in line 163; used 2 times
exclam defined in line 215; used 15 times
fixol defined in line 197; used 2 times
makargs defined in line 228; used 1 times
next defined in line 241; used 2 times
nomore defined in line 315; used 1 times
quickly defined in line 329; used 5 times
resetflav defined in line 347; used 4 times
setflav defined in line 383; used 3 times
tail defined in line 419; used 36 times
tail2of defined in line 426; used 12 times
tailprim defined in line 435; used 5 times
tailspec defined in line 406; used 1 times
vcontin defined in line 473; used 3 times

Defined variables

sccsid defined in line 8; never used
tcommand defined in line 433; used 6 times
Last modified: 1985-06-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2181
Valid CSS Valid XHTML 1.0 Strict