1: static char Sccsid[] = "xed.c @(#)xed.c	1.1	10/1/82 Berkeley ";
   2: #
   3: 
   4: /*
   5:  *	V7.15 81/09/16 14:22	Fixed bug causing bus errors occasionally
   6:  *	V7.14 81/09/10 21:50	-B dynamically allocated line buffer
   7:  *	V7.13 81/07/25 22:51	added -O and "long" pointers
   8:  *
   9:  * Editor
  10:  *
  11:  *	Major additions beginning	77/04
  12:  *	Conversion to version 7		79/12
  13:  *	Conversion to VAX		80/11
  14:  *
  15:  *	Purdue University, Engineering Computer Network
  16:  *
  17:  *	Tgi -- Room 337A
  18:  *	Electrical Engineering Dept
  19:  *	Purdue University
  20:  *	West Lafayette, Indiana
  21:  *	47907
  22:  *	317/49-41592
  23:  */
  24: 
  25: #define XED     /* enable powerful stuff */
  26: #define V7      /* enable environment stuff for protocol */
  27: 
  28: /*
  29:  *	At the entry to a function (PDP-11) the following sequence
  30:  *	of instructions is executed:
  31:  *		func:	jsr	r5,csv
  32:  *		csv:	mov	r5,r0
  33:  *		csv+2:	mov	sp,r5
  34:  *	If a signal occurs between the first and second, or between the
  35:  *	second and third instructions, r5 will NOT contain a valid
  36:  *	stack address.  Hence, when longjmp() attempts to validate
  37:  *	the environment pointer (r5) links, an instruction will be
  38:  *	fetched instead of a valid pointer, and will generally cause
  39:  *	one of "memory fault", "bus error", or "illegal instruction"
  40:  *	resulting in the loss of the editing session.
  41:  *
  42:  *	Due to this wonderful feature of version 7 ingenuity, I have
  43:  *	reverted to using setexit/reset, since they are simpler and
  44:  *	do not assume that I do not know what I am doing.
  45:  *
  46:  *	80/11/10 V7.01 Tgi
  47:  */
  48: 
  49: #ifndef pdp11
  50: #include <setjmp.h>
  51: jmp_buf _env_rst;
  52: #define setexit() setjmp(_env_rst)
  53: #define reset() longjmp(_env_rst,1)
  54: #endif
  55: 
  56: #include <sys/types.h>
  57: #include <sys/stat.h>
  58: 
  59: /*
  60:  * Machine-dependent definitions
  61:  */
  62: 
  63: #ifdef pdp11
  64: # define BPB    8   /* bits per byte */
  65: # define BPW    (BPB*sizeof(int))/* bits per word */
  66: # define BPWC   4   /* log2(BPW) */
  67: # define BPWM   017 /* mask of BPWC bits */
  68:   typedef short block;
  69:   typedef short charac;
  70:   typedef short filedes;
  71:   typedef short flag;
  72:   typedef int   (*func)();
  73:   typedef short linep;
  74: #endif
  75: 
  76: #ifdef vax
  77: # define BPB    8   /* bits per byte */
  78: # define BPW    (BPB*sizeof(int))/* bits per word */
  79: # define BPWC   5   /* log2(BPW) */
  80: # define BPWM   037 /* mask of BPWC bits */
  81:   typedef long  block;
  82:   typedef int   charac;
  83:   typedef short filedes;
  84:   typedef char  flag;
  85:   typedef int   (*func)();
  86:   typedef long  linep;  /* NEW */
  87: #endif
  88: 
  89: /*
  90:  * conditional compilation
  91:  */
  92: 
  93: #ifdef XED
  94: # define AGAIN      /* enable "o" "again" command */
  95: # define ALLOC  1024    /* line buffer size */
  96: # define APLMAP     /* enable Apl character mapping */
  97: # define DEBUG      /* enable "du" command */
  98: # define DUMB   0   /* enable command to disable spcl chars */
  99: # define EOL        /* enable special eol stuff */
 100: # define EXTMARK    /* extended "k" capability */
 101: # define G_VFY      /* enable verifying on "g" command */
 102: # define HELP   "/etc/xed.doc"
 103: # ifdef pdp11       /* only needed on 16-bit machines */
 104: #  define HUGE      /* enable "huge" file stuff */
 105: # endif
 106: # define PAGE       /* enable proper line counting on ":" */
 107: # define PARENS     /* enable "b" suffix to count parentheses */
 108: # define PIPE       /* enable | command to pipe to process */
 109: # define PROMPT ">"
 110: # define STRLEN     /* enable string-length counting code */
 111: # define TABS   ((LBSIZE+sizeof(int)-1)/sizeof(int)) /* words for tab stops */
 112: # define TTL    "XED\tV7.15"
 113: /* #define TTL_NL	9	/* location of newline in TTL */
 114: # define UNDO       /* enable "u"ndo command */
 115: # define USE        /* enable "@" command */
 116: # define XDEL       /* enable undelete stuff */
 117: # define YINT       /* enable special interrupt processing */
 118: #endif
 119: 
 120: /*
 121:  * stuff for EED, instead of XED
 122:  */
 123: 
 124: #ifndef XED
 125: # define HELP   "/etc/eed.doc"
 126: # define PROMPT "*"
 127: # define TTL    "EED"
 128: #else
 129: # define EEDHELP    "/etc/eed.doc"
 130: # define EEDPROMPT "*"
 131: # define EEDTTL "EED"
 132: #endif
 133: 
 134: /*
 135:  * stuff normally enabled
 136:  */
 137: 
 138: #define CLEAR   "\33:\33H\33J\32\14"    /* HP-2640A, Lear ADM-3A */
 139: #define CMDS    "edsav" /* all commands written if exists */
 140: #ifndef DUMB
 141: # define DUMB   1   /* enable command to disable spcl chars */
 142: #endif
 143: 
 144: /*
 145:  * special stuff, occasionally enabled
 146:  */
 147: 
 148: #define LOG "/a/tgi/etc/xed.log"    /* feature use logging */
 149: 
 150: /*
 151:  * data #defines
 152:  */
 153: 
 154: #define BAK 4   /* file.bak - backup() */
 155: #define BLKSIZE 512 /* disk block size (bytes) */
 156: #define BS1 0100000 /* stty() */
 157: #define CBACK   14  /* back-reference: \(blah\)more\1 */
 158: #define CBRA    1   /* \( */
 159: #define CCHR    2   /* literal character */
 160: #define CCL 6   /* character class [x...y] */
 161: #define CCOUNT  (80-1)  /* terminal width */
 162: #define CDOL    10  /* ...$ */
 163: #define CDOT    4   /*  .  */
 164: #define CEOF    11  /* end of pattern */
 165: #define CKET    12  /* \) */
 166: #define EOF -1  /* end of file */
 167: #define ESIZE   128 /* regular expression size */
 168: #define FILE    0   /* no extension - backup() */
 169: #define FNSIZE  64  /* max size of pathname to file */
 170: #define GBSIZE  256 /* max global command length */
 171: #define HUP 3   /* file.hup - backup() */
 172: #define INT 2   /* file.int - backup() */
 173: #define LBSIZE  512 /* max line length */
 174: #define LMASK   077 /* mask for "locked" file */
 175: #define LMODE   (MODE&~LMASK)   /* mode for "locked" file */
 176: #define MODCNT  35  /* default mod count before auto-write */
 177: #define MODE    0666    /* mode for normal files */
 178: #define NBRA    9   /* number of \( \) pairs */
 179: #define NCCL    8   /* not in character class: [^x...y] */
 180: #define PAGSIZ  22  /* page size for ":" command */
 181: #define READ    0   /* getblock: read function */
 182: #define SIGBUS  10  /* Bus error */
 183: #define SIGEMT  7   /* EMT trap */
 184: #define SIGFPE  8   /* Floating Point Exception */
 185: #define SIGHUP  1   /* Hangup signal */
 186: #define SIGILL  4   /* Illegal instruction */
 187: #define SIGINT  2   /* Interrupt signal */
 188: #define SIGIOT  6   /* IOT trap */
 189: #define SIGPIP  13  /* Broken pipe for ! stuff */
 190: #define SIGQIT  3   /* Quit signal */
 191: #define SIGSEGV 11  /* Memory fault */
 192: #define SIGSYS  12  /* Bad system call */
 193: #define SIGTRC  5   /* Trace/BPT for mail stuff */
 194: #define SIGTRM  15  /* Termination */
 195: #define STAR    1   /*  *  */
 196: #define TABFILL '\t'    /* fill character for tab expansion */
 197: #define TMP 1   /* file.edt - backup() */
 198: #define TRM 5   /* file.trm - backup() */
 199: #define TTSIZE  (512+4) /* terminal output buffer size */
 200: #define WRITE   1   /* getblock: write function */
 201: #define ever    (;;)
 202: 
 203: #define error   errfunc
 204: #define ctrl(x) ((x)&037)
 205: 
 206: #ifdef AGAIN
 207: char    agbuf[GBSIZE],  /* save area for "again" command */
 208:     *agp    = 0;    /* "again" command pointer */
 209: flag    agf = 0;    /* "again" flag  (executing the command) */
 210: #endif
 211: 
 212: #ifdef ALLOC
 213: int lbsize  = LBSIZE;/* line buffer size */
 214: #endif
 215: 
 216: #ifdef APLMAP
 217: flag    aplmap  = 0;    /* Apl character mapping */
 218: #include "aplmap.h" /* apl ADM-3A char set mapping tables */
 219: #endif
 220: 
 221: #ifdef CKPT
 222: char    *cfname = "/tmp/ce00000";/* filename for checkpoint */
 223: int recovry = 0,    /* non-zero to recover checkpointed session */
 224:     tfnum;      /* index into tfname for "00000" string */
 225: #endif
 226: 
 227: #ifdef CLEAR
 228: char    *clears = CLEAR;/* screen-clear sequence */
 229: flag    zflg    = 0;    /* if "stty bs1" not set */
 230:             /* bs1 displays ctrl-z as ^Z on tty */
 231: #endif
 232: 
 233: #ifdef CMDS
 234: filedes cmd = 0;    /* file des for command-save file */
 235: char    cmdfil[] = CMDS;/* command-save file */
 236: #endif
 237: 
 238: #ifdef DEBUG
 239: flag    tflg    = 0;    /* tracing flag */
 240: #endif
 241: 
 242: #ifdef DUMB
 243: flag    dumbf   = DUMB; /* 1 = disable special chars in patterns */
 244: #endif
 245: 
 246: #ifdef EOL
 247: charac  eol = 0;    /* "end-of-line" char for multiple commands */
 248:             /*   per line */
 249: flag    prompt3 = 1;    /* disable prompts for "eol" stuff */
 250: #endif
 251: 
 252: #ifdef G_VFY
 253: flag    gaskf   = 0;    /* verify mode on global command */
 254: #endif
 255: 
 256: #ifdef HELP
 257: filedes doc = 0;    /* "help" file descriptor */
 258: char    *help   = HELP; /* "help" file name */
 259: #endif
 260: 
 261: #ifdef LOG
 262: char    logfile[]= LOG; /* logging use of features */
 263: filedes lfile   = 0;    /* logging file descriptor */
 264: short   logamp;     /* since s/x/&/ may be done many times */
 265: struct logstat {
 266:     short   l_uid;  /* user id of caller */
 267:     char    l_xed,      /* 1 if xed, 0 if eed, 2 if apled */
 268:         l_inter;    /* 1 if interactive */
 269: /* command features */
 270:     short   lc_shell,   /*  !  */
 271:         lc_pipe,    /*  |  */
 272:         lc_piplus,  /*  |+  */
 273:         lc_piminus, /*  |-  */
 274:         lc_dpipe,   /*  ||  */
 275:         lc_pfrom,   /*  |<  */
 276:         lc_pto,     /*  |>  */
 277:         lc_at,      /*  @  */
 278:         lc_colon,   /*  :  */
 279:         lc_star,    /*  *  */
 280:         lc_clnminus,    /*  :-  */
 281:         lc_comment, /*  : stuff  or  * stuff  */
 282:         lc_append,  /*  a  */
 283:         lc_abort,   /*  abort  */
 284:         lc_aspace,  /*  a line  */
 285:         lc_aslash,  /*  a/string/  */
 286:         lc_browse,  /*  bN  */
 287:         lc_change,  /*  c  */
 288:         lc_cslash,  /*  c/s1/s2/  */
 289:         lc_copy,    /*  coNN  */
 290:         lc_delete,  /*  d  */
 291:         lc_depth,   /*  d=NN  */
 292:         lc_directory,   /*  d path  */
 293:         lc_edit,    /*  e file  */
 294:         lc_eol,     /*  e=C  */
 295:         lc_errmsg,  /*  eNN  */
 296:         lc_exp,     /*  exp  */
 297:         lc_eplus,   /*  e+  */
 298:         lc_eminus,  /*  e-  */
 299:         lc_fshow,   /*  f  */
 300:         lc_fset,    /*  f file  */
 301:         lc_fillset, /*  f=C  */
 302:         lc_global,  /*  g/str/cmd  */
 303:         lc_gvfy,    /*  g/str/vcmd  */
 304:         lc_header,  /*  h  */
 305:         lc_help,    /*  help  */
 306:         lc_insert,  /*  i  */
 307:         lc_islash,  /*  i/string/  */
 308:         lc_join,    /*  j  */
 309:         lc_jglue,   /*  j/glue/  */
 310:         lc_klist,   /*  k  */
 311:         lc_kset,    /*  kC  */
 312:         lc_list,    /*  l  */
 313:         lc_move,    /*  mNN  */
 314:         lc_moove,   /*  moNN  */
 315:         lc_magic,   /*  m  */
 316:         lc_numbers, /*  n  */
 317:         lc_numinus, /*  n-  */
 318:         lc_numplus, /*  n+  */
 319:         lc_o,       /*  o ^Q  */
 320:         lc_print,   /*  p  */
 321:         lc_pprint,  /*  pp  */
 322:         lc_quit,    /*  q  */
 323:         lc_qimm,    /*  qi  */
 324:         lc_quote,   /*  q=C  */
 325:         lc_read,    /*  r  */
 326:         lc_substitute,  /*  s/s1/s2/  */
 327:         lc_stop,    /*  s  */
 328:         lc_savecount,   /*  saNN  */
 329:         lc_tablist, /*  t  */
 330:         lc_tabset,  /*  t,NN  */
 331:         lc_tabchar, /*  t=C  */
 332:         lc_transfer,    /*  tNN  */
 333:         lc_undo,    /*  u  */
 334:         lc_vglobal, /*  v/str/cmd  */
 335:         lc_write,   /*  w  */
 336:         lc_wonto,   /*  w>  */
 337:         lc_wimm,    /*  wi  */
 338:         lc_width,   /*  w=NN  */
 339:         lc_xundelete,   /*  x  */
 340:         lc_yintr,   /*  y  */
 341:         lc_yminus,  /*  y-  */
 342:         lc_yplus,   /*  y+  */
 343: /* address features */
 344:         la_dot,     /*  .  */
 345:         la_dotdot,  /*  ..  */
 346:         la_dol,     /*  $  */
 347:         la_num,     /*  NN  */
 348:         la_plus,    /*  +  */
 349:         la_minus,   /*  -  */
 350:         la_caret,   /*  ^  */
 351:         la_quote,   /*  'a  */
 352:         la_letter,  /*  A  */
 353:         la_slash,   /*  /str/  */
 354:         la_query,   /*  ?str?  */
 355:         la_equal,   /*  =  */
 356: /* pattern features */
 357:         lp_caret,   /*  ^  */
 358:         lp_dol,     /*  $  */
 359:         lp_dot,     /*  .  */
 360:         lp_star,    /*  *  */
 361:         lp_ccl,     /*  [ ]  */
 362:         lp_nccl,    /*  [^ ]  */
 363:         lp_paren,   /*  \( \)  */
 364:         lp_digit,   /*  \1 \2 \3 ...  */
 365: /* substitution features */
 366:         lp_amp,     /*  &  */
 367: /* miscellaneous features */
 368:         lm_quote,   /*  ...q  */
 369:         lm_bracket, /*  ...b  */
 370:         lm_overwrite;   /*  -O,wi  */
 371: /* resources */
 372:     long    lt_start,   /* starting time */
 373:         lt_end,     /* elapsed time */
 374:         lt_usercpu, /* user cpu time */
 375:         lt_syscpu,  /* system cpu time */
 376:         lt_kidscpu, /* total ! kids time */
 377:         lt_rlines,  /* total lines read */
 378:         lt_wlines;  /* total lines written */
 379: } logstats;
 380: #endif
 381: 
 382: #ifdef PAGE
 383: int ccount  = CCOUNT;/* terminal width */
 384: #endif
 385: 
 386: #ifdef PARENS
 387: int parenc[3] = {0, 0, 0};/* parentheses counts */
 388: flag    parenf  = 0;    /* count parentheses and brackets */
 389: #endif
 390: 
 391: #ifdef PIPE
 392: filedes pfile   = 0;    /* "pipe" file descriptor */
 393: char    *pfname = "/tmp/ep00000";/* for "double-piping" */
 394: flag    piperr  = 0,    /* pipe error flag - shell() */
 395:     pno = -1,   /* piping line numbering flag (default n-) */
 396:     strict  = 1;    /* strict exit status checking for | */
 397: #endif
 398: 
 399: #ifdef STRLEN
 400: charac  quotec  = '\0', /* quote character other than " or ' */
 401:     quotec2 = '\0'; /* closing quote */
 402: int quotef  = 0;    /* length of strings within " or ' chars */
 403: #endif
 404: 
 405: #ifdef TABS
 406: charac  tabfill = TABFILL,/* fill character */
 407:     tabc    = 0;    /* tab character - if 0 no tab processing */
 408: int maxtab  = -1,   /* last column number with tab stop */
 409:     tabs[TABS]; /* each bit on = tab stop */
 410: #endif
 411: 
 412: #ifdef UNDO
 413: linep   undo_oldp,  /* original line pointer */
 414:     undo_newp;  /* replacement line */
 415: #endif
 416: 
 417: #ifdef USE
 418: filedes alt = 0;    /* alternate command input file */
 419: char    altfile[FNSIZE];
 420: flag    eflg2   = 0;    /* another kludge */
 421: #endif
 422: 
 423: #ifdef XDEL
 424: linep   deleted = 0;    /* pointer to deleted line pointers */
 425: int ndeleted = 0;   /* number of lines */
 426: #endif
 427: 
 428: #ifdef YINT
 429: flag    yflg    = 0;    /* page upon interrupt */
 430: linep   *yplus  = 0;    /* page from this line - if zero, from dot */
 431: #endif
 432: 
 433: /*
 434:  * globals
 435:  */
 436: 
 437: block   iblock  = -1,   /* block number of input buffer */
 438:     oblock  = -1;   /* output buffer block number */
 439: 
 440: char    *braelist[NBRA],    /* bracket \( \) end list */
 441:     *braslist[NBRA],    /* bracket \( \) start list */
 442:     dotbak[] = ".bak",
 443:     dotedt[] = ".edt",  /* "file saved" file */
 444:     dothup[] = ".hup",
 445:     dotint[] = ".int",
 446:     dottrm[] = ".trm",
 447:     *dots[] = { dothup, dottrm, dotedt, dotint, 0 },
 448:     expbuf[ESIZE + 4],  /* expression buffer */
 449:     file[FNSIZE],       /* filename buffer */
 450: #ifndef ALLOC
 451:     genbuf[LBSIZE],     /* generated line buffer */
 452: #else
 453:     *genbuf,        /* generated line buffer pointer */
 454: #endif
 455:     ibuff[BLKSIZE],     /* input tmpfile buffer */
 456:     line[TTSIZE + 4],   /* terminal output buffer */
 457: #ifndef ALLOC
 458:     linebuf[LBSIZE],    /* line buffer for getline()/putline() */
 459: #else
 460:     *linebuf,       /* line buffer for getline()/putline() */
 461: #endif
 462:     no[]    = "no ",
 463:     null[]  = "",       /* "" */
 464:     obuff[BLKSIZE],     /* output tmpfile buffer */
 465:     off[]   = "off",
 466:     on[]    = "on",
 467:     prcntu[] = "%u\n",  /* %u */
 468:     quote_s[] = "s",    /* "s" */
 469:     rhsbuf[LBSIZE / 2], /* right-hand-side expression buffer */
 470:     savedfile[FNSIZE],  /* saved filename */
 471:     tempfile[FNSIZE],   /* scratch area for filename */
 472: 
 473:     *editor,    /* argv[0] */
 474:     *e_prompt = PROMPT,/* editor command prompt */
 475:     *fmtlno = "%7u=",/* format for line-number output */
 476:     *globp,     /* global command pointer */
 477:     *linp   = line, /* line pointer */
 478:     *linebp,
 479:     *loc1,      /* start pointer of & string */
 480:     *loc2,      /* end pointer of & string */
 481:     *locs,
 482:     *nextip,
 483:     *overfile,  /* filename mode was changed on */
 484:     *tfname = "/tmp/e00000",/* "buffer" name */
 485:     *ver    = TTL;  /* ID message */
 486: 
 487: charac  lastc   = 0,    /* peekc set to lastc on interrupt */
 488:     peekc   = 0;    /* one character pushback */
 489: 
 490: int brcount = 1,    /* number of lines to output on "newline" */
 491:     col = 0,    /* column counter for calculating line wraps */
 492:     line_num,   /* integer for line number on output */
 493:     modcount = MODCNT,/* number of mods before auto-write */
 494:     overmode,   /* mode of overridden file */
 495:     mods    = 0,    /* number of mods */
 496:     nbra    = 0,    /* count of currently defined \( \) pairs */
 497:     ninbuf,     /* bytes in tmpfile input buffer */
 498:     nleft,      /* bytes remaining in tmpfile output buffer */
 499:     num_reads = 0,  /* indicator to aid text_modified-- */
 500:             /* first read isn't really a modify */
 501:     pcount  = PAGSIZ-1,/* number of lines to display on ":" command */
 502:     s_cnt   = 0,    /* counter for "s/str1/str2/nn" */
 503:     s_tmp   = 0,    /* scratch var for same */
 504:     savf,       /* counter for auto-write stuff */
 505:     text_modified = 0;/* flag--on if text was modified */
 506: 
 507: filedes fout    = 1,    /* putchar() writes on this fildes */
 508:     io  = 0,    /* file descriptor for "r", "w", "e" */
 509:     tfile   = -1;   /* file des for "buffer" */
 510: 
 511: flag    aflg    = 0,    /* "apl mode" flag */
 512:     appflg  = 0,    /* append flag (if "w>file") */
 513:     badf    = 0,    /* bad read on temp file */
 514:     bflg    = 0,    /* "back-up" flag -- Generate back-up file */
 515:     bflg2   = 0,    /* Secondary "back-up" flag */
 516:     circfl,     /* reg expr started with ^ */
 517:     curt    = 0,    /* short error messages -- ie: '?' */
 518:     deltflg = 0,    /* don't delete .edt file upon exit */
 519:     eflg    = 0,    /* echo input flag */
 520:     eof = 0,    /* eof was last char typed */
 521:     fflg    = 0,    /* "create" flag */
 522:     globf2  = 0,    /* kludge for -f */
 523: #ifdef HUGE
 524:     hugef   = 0,    /* -h is process huge file */
 525:     hugef2  = 0,    /* getblock() conversion to huge */
 526: #endif
 527:     hupflag = 0,    /* hangup signal has been caught */
 528:     ichanged,   /* ibuf has been changed */
 529:     iflg    = 0,    /* file.int and exit on interrupt */
 530:     immflg  = 0,    /* immediate flag -- q and e */
 531:     io_w    = 0,    /* writing in progress */
 532:     listf   = 0,    /* list control chars explicitly */
 533:     noshell = 0,    /* true if no ! command allowed */
 534:     over    = 0,    /* override permissions on write if possible */
 535:     pflag,      /* print line after doing command */
 536:     pipef   = 0,    /* for talking to pipes */
 537:     prompt1 = 1,    /* flag--enable or disable line-num prompts */
 538:     prompt2 = 1,    /* flag--enable or disable ALL prompting */
 539:     reading = 0,    /* waiting on tty read */
 540:     seekf   = 0,    /* no seek to EOF on error on fd 0 */
 541:     termflg = 0;    /* if termination signal (15) occurred */
 542: 
 543: linep   *addr1,     /* lower line bound */
 544:     *addr2,     /* upper line bound */
 545:     *dol,       /* last line in file */
 546:     *dot,       /* "current" line */
 547:     *dotdot,    /* last different "dot" */
 548:     *endcore,   /* current end of memory */
 549:     *fendcore,  /* start of dynamic area */
 550:     *lastdot,   /* last "dot" */
 551:     names['z' - 'a' + 1],   /* "k" command markers */
 552: #ifdef EXTMARK
 553:     names2['z' - 'a' + 1],  /* "k" command markers */
 554: #endif
 555:     *old_a1,    /* previous address bounds */
 556:     *old_a2,
 557:     tline,      /* pointer to next available pos in tmpfile */
 558:     *zero;      /* anchor line for all other lines */
 559: 
 560: /*
 561:  * magic constants used in many places
 562:  */
 563: 
 564: #ifdef pdp11
 565: # define _1a     ~0377
 566: # define _2a      0400
 567: # define _3a      0377
 568: # define _4a      0774
 569: # define _5a       255
 570: # define _6a    077776
 571: # define _1b     ~0177
 572: # define _2b      0200
 573: # define _3b      0777
 574: # define _4b      0774
 575: # define _5b       511
 576: # define _6b    077777
 577: #endif
 578: 
 579: #ifdef vax
 580: # define _1a        ~0377
 581: # define _2a         0400
 582: # define _3a    077777777
 583: # define _4a         0774
 584: # define _5a        65535
 585: # define _6a    077777776
 586: #endif
 587: 
 588: #ifdef HUGE
 589: int _1[]    = { _1a, _1b }, /* tl &= _1; getline() */
 590:     _2[]    = { _2a, _2b }, /* tl += _2; getline()... */
 591:     _3[]    = { _3a, _3b }, /* bno = ... & _3; getblock() */
 592:     _4[]    = { _4a, _4b }, /* off = ... & _4; getblock() */
 593:     _5[]    = { _5a, _5b }, /* if (bno >= _5)... getblock() */
 594:     _6[]    = { _6a, _6b }; /* tline += ... & _6; */
 595: #else
 596: # define _1 _1a
 597: # define _2 _2a
 598: # define _3 _3a
 599: # define _4 _4a
 600: # define _5 _5a
 601: # define _6 _6a
 602: #endif
 603: 
 604: /*
 605:  * error messages
 606:  *
 607:  *	(there are more than these)
 608:  */
 609: 
 610: char    *errtext[] = {
 611:     /*  0 */    "syntax is k[a-z]",
 612:     /*  1 */    "illegal command format",
 613:     /*  2 */    "no command",
 614:     /*  3 */    "no tab character",
 615:     /*  4 */    "can't change filename",
 616:     /*  5 */    "file name syntax",
 617:     /*  6 */    "recursive \"@\" command",
 618:     /*  7 */    "null file name illegal",
 619:     /*  8 */    "unrecognized command",
 620:     /*  9 */    "no tabs set",
 621:     /* 10 */    "global command not allowed with huge file",
 622:     /* 11 */    "file name too long",
 623:     /* 12 */    "expanded line too long",
 624:     /* 13 */    "no such line",
 625:     /* 14 */    "can't fork",
 626:     /* 15 */    "can't write to process",
 627:     /* 16 */    "no lines",
 628:     /* 17 */    "backup(FILE) error (?)",
 629:     /* 18 */    "string not found",
 630:     /* 19 */    "  '  must be followed by [a-z]",
 631:     /* 20 */    "address syntax error",
 632:     /* 21 */    "lower address bound > upper one",
 633:     /* 22 */    "address illegal here",
 634:     /* 23 */    "non-existent line number",
 635:     /* 24 */    "bottom of file reached",
 636:     /* 25 */    "command syntax error",
 637:     /* 26 */    "\"advance\" error (?)",
 638:     /* 27 */    "null string illegal",
 639:     /* 28 */    "destination not found",
 640:     /* 29 */    "INTERRUPT!",
 641:     /* 30 */    "line too long",
 642:     /* 31 */    "missing destination address",
 643:     /* 32 */    "I/O error--file not saved!",
 644:     /* 33 */    "file overflows available memory",
 645:     /* 34 */    "file too large (TMPERR)",
 646:     /* 35 */    "I/O error on temp file (TMPERR)",
 647:     /* 36 */    "open error on temp file (TMPERR)",
 648:     /* 37 */    "recursive global command",
 649:     /* 38 */    "global command list too long",
 650:     /* 39 */    "substitute pattern not found",
 651:     /* 40 */    "missing substring",
 652:     /* 41 */    "string2 too long",
 653:     /* 42 */    "substring too long",
 654:     /* 43 */    "substituted string too long",
 655:     /* 44 */    "too many  \\(",
 656:     /* 45 */    "unbalanced  \\(  \\)",
 657:     /* 46 */    "\\n  illegal",
 658:     /* 47 */    "unimplemented feature",
 659:     /* 48 */    "[nothing written]",
 660:     /* 49 */    "pattern too complicated",
 661:     /* 50 */    "can't create temp file (TMPERR)",
 662:     /* 51 */    "bad directory",
 663:     /* 52 */    "no ! allowed",
 664:     /* 53 */    "can't read ",
 665:     /* 54 */    "can't create ",
 666:     /* 55 */    "%u line%s\n",
 667:     /* 56 */    "[file saved]",
 668:     /* 57 */    "\nHangup!\n",
 669:     /* 58 */    "\nTerminated...\n",
 670:     /* 59 */    "EOF illegal here",
 671:     /* 60 */    "can't join to line 0",
 672:     /* 61 */    "! not allowed with global command",
 673:     /* 62 */    "no filename specified",
 674:     /* 63 */    "not enough  \\( \\)  pairs",
 675:     /* 64 */    "can't create pipe file (PIPERR)",
 676:     /* 65 */    "open error on pipe file (PIPERR)",
 677:     /* 66 */    "can't checkpoint",
 678:     /* 67 */    "can't recover",
 679: };
 680: #define NERR    (sizeof errtext / sizeof errtext[0])
 681: 
 682: /*
 683:  * ! error strings
 684:  */
 685: 
 686: char *status[] = {
 687:     /*  0 */    0,
 688:     /*  1 */    "hangup",
 689:     /*  2 */    "interrupt",
 690:     /*  3 */    "quit",
 691:     /*  4 */    "illegal instruction",
 692:     /*  5 */    "bpt",
 693:     /*  6 */    "iot",
 694:     /*  7 */    "emt",
 695:     /*  8 */    "fpp",
 696:     /*  9 */    "killed",
 697:     /* 10 */    "bus error",
 698:     /* 11 */    "memory fault",
 699:     /* 12 */    "bad sys call",
 700:     /* 13 */    "broken pipe",
 701:     /* 14 */    "alarm",
 702:     /* 15 */    "terminated",
 703: #ifdef pdp11
 704:     /* 16 */    "time limit",
 705: #else
 706:     /* 16 */    0,
 707:     /* 17 */    "stopped",
 708:     /* 18 */    "terminal stop",
 709:     /* 19 */    "continue",
 710:     /* 20 */    "child status changed",
 711:     /* 21 */    "terminal input",
 712:     /* 22 */    "terminal output",
 713:     /* 23 */    "terminal input ready",
 714:     /* 24 */    "cpu timelimit exceeded",
 715:     /* 25 */    "filesize limit exceeded",
 716: #endif
 717: };
 718: #define NSTR    (sizeof status / sizeof status[0])
 719: 
 720: #define putsn(x) (puts2((x)),putchar('\n'))
 721: #define min(x,y) ((x)<(y)?(x):(y))
 722: #define max(x,y) ((x)>(y)?(x):(y))
 723: 
 724: /*
 725:  * function declarations
 726:  */
 727: 
 728: linep   *findmark();
 729: char    *getblock();
 730: long    lseek();
 731: func    signal();
 732: #ifndef CKPT
 733: int badsig(),
 734: #else
 735: int checkpoint(),
 736: #endif
 737:     hangup(),
 738:     mail(),
 739:     onintr(),
 740:     term();
 741: 
 742: /*
 743:  * signals
 744:  */
 745: 
 746: struct sigtab {
 747:     int s_sig,
 748:         s_func;
 749: } sigtab1[] = {
 750: #ifdef CKPT
 751:     SIGILL,     checkpoint,
 752:     SIGIOT,     checkpoint,
 753:     SIGEMT,     checkpoint,
 754:     SIGFPE,     checkpoint,
 755:     SIGBUS,     checkpoint,
 756:     SIGSEGV,    checkpoint,
 757:     SIGSYS,     checkpoint,
 758: #else
 759:     SIGILL,     badsig,
 760:     SIGIOT,     badsig,
 761:     SIGEMT,     badsig,
 762:     SIGFPE,     badsig,
 763:     SIGBUS,     badsig,
 764:     SIGSEGV,    badsig,
 765:     SIGSYS,     badsig,
 766: #endif
 767:     0,      0,
 768: }, sigtab2[] = {
 769:     SIGTRC,     mail,
 770:     SIGHUP,     hangup,
 771:     SIGTRM,     term,
 772:     SIGINT,     onintr,
 773:     0,      0,
 774: };
 775: 
 776: main(argc, argv)
 777: char **argv;
 778: {
 779: #ifdef CKPT
 780:     extern checkpoint();
 781: #else
 782:     extern badsig();
 783: #endif
 784:     extern onintr(), hangup(), mail(), term();
 785: #ifdef DEBUG
 786: #ifdef EXPDMP
 787:     extern expdmp();
 788: #endif
 789: #endif
 790:     register n;
 791:     register char *p1, *p2, *ep;
 792:     func savint;
 793: 
 794:     signal(SIGQIT, 1);
 795:     savint = signal(SIGINT, 1);
 796:     ep = *argv;
 797: #ifdef XED
 798:     p1 = ep;
 799:     p2 = p1;
 800:     while (*p1)
 801:         if (*p1++ == '/' && *p1 && *p1 != '/')
 802:             p2 = p1;
 803:     p1 = p2;
 804:     *argv = p2;
 805:     n = 0;
 806:     while (*p1)
 807:         if (*p1++ == 'x') { /* xed .vs. eed */
 808:             ++n;
 809:             break;
 810:         }
 811:     if (n == 0) {
 812:         e_prompt = EEDPROMPT;
 813:         ver = EEDTTL;
 814:         help = EEDHELP;
 815:         dumbf = 1;
 816:     }
 817: #ifdef LOG
 818:     logstats.l_xed = n;
 819: #endif
 820: #endif
 821:     prompt2 = istty(0);
 822: #ifdef V7
 823:     if (getenv("_OVERWRITE_"))
 824:         ++over;
 825: #endif
 826:     while (--argc)
 827:         if (**++argv == '-') {
 828:             while (*++*argv) {
 829:                 switch (**argv) {
 830:                 case '!':  /* no ! allowed */
 831:                     noshell = 1;
 832:                     break;
 833: #ifdef APLMAP
 834:                 case 'A':  /* apl char mapping */
 835:                     aplmap = 1;
 836:                     errtext[29] = "G interrupt G";
 837:                     p1 = ver;
 838:                     while (*p1) {
 839:                         if ('A' <= *p1 && *p1 <= 'Z')
 840:                             *p1 |= 040;
 841:                         ++p1;
 842:                     }
 843: #endif
 844:                 case 'a':  /* apl mode */
 845:                     aflg = 1;
 846:                     fmtlno = "[ %u ]\t";
 847: #ifdef DUMB
 848:                     dumbf = 1;
 849: #endif
 850: #ifdef XED
 851: #ifdef TTL_NL
 852:                     ver[TTL_NL] = 0;
 853: #endif
 854: #endif
 855:                     break;
 856:                 case 'b':  /* file.bak on entry */
 857:                     bflg = 1;
 858:                     bflg2 = 1;
 859:                     break;
 860: #ifdef PAGE
 861:                 case 'c':  /* crt depth in lines */
 862:                     ++*argv;
 863:                     n = argnum(argv);
 864:                     if (n >= 0)
 865:                         pcount = n;
 866:                     break;
 867: #endif
 868:                 case 'd':  /* don't delete .edt file */
 869:                     deltflg = 1;
 870:                     break;
 871:                 case 'e':  /* echo input commands */
 872:                     eflg = 1;
 873:                     break;
 874:                 case 'f':  /* create mode */
 875:                     fflg = 1;
 876:                     break;
 877: #ifdef HUGE
 878:                 case 'h':  /* edit "huge" file */
 879:                     hugef = 1;
 880:                     break;
 881: #endif
 882:                 case 'i':  /* file.int on interrupt */
 883:                     iflg = 1;
 884:                     break;
 885:                 case 'k':  /* kill verbose messages */
 886:                     curt = 1;
 887:                     break;
 888: #ifdef EOL
 889:                 case 'l':  /* set eol char to "x" */
 890:                     if (*++*argv)
 891:                         eol = **argv;
 892:                     else
 893:                         --*argv;
 894:                     break;
 895: #endif
 896:                 case 'm':  /* mod cnt for autosave */
 897:                     ++*argv;
 898:                     n = argnum(argv);
 899:                     if (n >= 0)
 900:                         modcount = n;
 901:                     break;
 902:                 case 'n':  /* no line num */
 903:                     prompt1 = 0;
 904:                     break;
 905:                 case 'o':  /* no seek to EOF on error */
 906:                     seekf = 1;
 907:                     break;
 908:                 case 'p':  /* force prompts for pipe */
 909:                     pipef = 1;
 910:                     prompt2 = 1;
 911:                     break;
 912:                 case 'q':  /* don't inhibit quits */
 913:                     signal(SIGQIT, 0);
 914:                     break;
 915: #ifdef DUMB
 916:                 case 'r':  /* spcl char meaning */
 917:                     dumbf ^= 01;
 918:                     break;
 919: #endif
 920:                 case 's':  /* silent mode */
 921:                     prompt2 = 0;
 922:                     break;
 923: #ifdef TABS
 924:                 case 't':  /* tab char */
 925:                     if (*++*argv)
 926:                         tabc = **argv;
 927:                     else
 928:                         --*argv;
 929:                     break;
 930: #endif
 931: #ifdef TABS
 932:                 case 'v':  /* tab fill char */
 933:                     if (*++*argv)
 934:                         tabfill = **argv;
 935:                     else
 936:                         --*argv;
 937:                     break;
 938: #endif
 939: #ifdef PAGE
 940:                 case 'w':  /* crt width */
 941:                     ++*argv;
 942:                     n = argnum(argv);
 943:                     if (--n >= 2)
 944:                         ccount = n;
 945:                     break;
 946: #endif
 947: #ifdef YINT
 948:                 case 'y':  /* page on interrupt */
 949:                     yflg = 1;
 950:                     break;
 951: #endif
 952: #ifdef USE
 953:                 case '@':  /* set "@" filename */
 954:                     p2 = altfile;
 955:                     p1 = ++*argv;
 956:                     while (*p1 && p2 < &altfile[FNSIZE - 2])
 957:                         *p2++ = *p1++;
 958:                     if (*p1) {
 959:                         p2 = altfile;
 960:                         putsn(errtext[11]);
 961:                     }
 962:                     *p2 = '\0';
 963:                     *argv = &p1[-1];
 964:                     break;
 965: #endif
 966: #ifdef ALLOC
 967:                 case 'B':  /* line buffer size */
 968:                     ++*argv;
 969:                     n = argnum(argv);
 970:                     if (n >= LBSIZE)
 971:                         lbsize = n;
 972:                     break;
 973: #endif
 974: #ifdef DEBUG
 975:                 case 'D':  /* trace mode -- debug */
 976:                     tflg = 1;
 977:                     break;
 978: #ifdef EXPDMP
 979:                 case 'Q':  /* show pattern on quit */
 980:                     signal(SIGQIT, expdmp);
 981:                     break;
 982: #endif
 983: #endif
 984: #ifdef XED
 985:                 case 'I':  /* suppress ID message */
 986:                     ver = 0;
 987:                     break;
 988:                 case 'P':  /* prompt */
 989:                     p1 = *argv;
 990:                     e_prompt = ++p1;
 991:                     while (*p1++);
 992:                     *argv = &p1[-2];
 993:                     break;
 994:                 case 'L':  /* line number prompt */
 995:                     p1 = *argv;
 996:                     fmtlno = ++p1;
 997:                     while (*p1++);
 998:                     *argv = &p1[-2];
 999:                     break;
1000:                 case 'C':  /* screen-clear */
1001:                     p1 = *argv;
1002:                     clears = ++p1;
1003:                     while (*p1++);
1004:                     *argv = &p1[-2];
1005:                     break;
1006: #ifdef CKPT
1007:                 case 'R':  /* recover */
1008:                     ++*argv;
1009:                     if ((recovry = argnum(argv)) == 0)
1010:                         recovry = 1;
1011:                     break;
1012: #endif
1013:                 case 'O':  /* over-ride write perm */
1014:                     over ^= 01;
1015:                     break;
1016:                 case 'T':  /* temp filename */
1017:                     p1 = *argv;
1018:                     tfname = ++p1;
1019: #ifdef PIPE
1020:                     while (*p1)
1021:                         if (*p1++ == ':') {
1022:                             p1[-1] = '\0';
1023:                             pfname = p1;
1024: #ifdef CKPT
1025:                             break;
1026: #endif
1027:                         }
1028: #endif
1029: #ifdef CKPT
1030:                     while (*p1)
1031:                         if (*p1++ == ':') {
1032:                             p1[-1] = '\0';
1033:                             cfname = p1;
1034:                         }
1035: #endif
1036:                     *argv = &p1[-1];
1037:                     break;
1038: #endif
1039:                 default:  /* tabs stops/illegals */
1040:                     if (!**argv || **argv == '-'
1041: #ifdef TABS
1042:                             || **argv == ','
1043: #endif
1044:                                     )
1045:                         break;
1046: #ifdef TABS
1047:                     if (**argv < '0' ||
1048:                         **argv > '9') {
1049: #endif
1050:                         printf("bad flag: -%c\n",
1051:                             **argv);
1052:                         exit(1);
1053: #ifdef TABS
1054:                     }
1055:                     n = argnum(argv);
1056:                     settab(n);
1057: #endif
1058:                 }
1059:             }
1060:         } else {
1061:             p1 = *argv;
1062:             p2 = savedfile;
1063:             while (*p2++ = *p1++)
1064:                 if (p2 >= &savedfile[FNSIZE - 2]) {
1065:                     putsn(errtext[11]);
1066:                     exit(1);
1067:                 }
1068:             globf2 = 1;
1069:             if (fflg)
1070:                 globp = "a\n";
1071:             else
1072:                 globp = "r\n";
1073:         }
1074: 
1075: 
1076: #ifdef YINT
1077:     if (iflg)
1078:         yflg = 0;
1079: #endif
1080: #ifdef ALLOC
1081:     linebuf = sbrk(lbsize);
1082:     genbuf = sbrk(lbsize);
1083: #endif
1084:     fendcore = sbrk(0);
1085: #ifdef CKPT
1086:     if ((n = recovry) == 0)
1087: #endif
1088:         n = getpid();
1089: #ifdef PIPE
1090:     tmpname(pfname, n);
1091: #endif
1092: #ifdef CKPT
1093:     tmpname(cfname, n);
1094: #endif
1095:     tmpname(tfname, n); /* MUST be last call to tmpname */
1096: #ifdef LOG
1097:     logstats.l_uid = getuid();
1098:     time(&logstats.lt_start);
1099:     if (prompt2)
1100:         ++logstats.l_inter;
1101:     if (aflg)
1102:         logstats.l_xed = 2; /* magic num for apled */
1103: #endif
1104: #ifdef CKPT
1105:     if (recovry)
1106:         recover();
1107: #endif
1108:     editor = ep;
1109:     if (prompt2) {
1110: #ifdef CMDS
1111:         if ((cmd = open(cmdfil, 1)) > 0)
1112:             lseek(cmd, 0L, 2);
1113:         else
1114:             cmd = 0;
1115: #endif
1116:         if (ver)
1117:             putsn(ver); /* XED V0.00 ... */
1118:         flush_buf();
1119:     } else
1120:         modcount = 0;
1121: #ifdef CMDS
1122:     if (cmd && *savedfile) {
1123:         write(cmd, "e,", 2);
1124:         p1 = savedfile;
1125:         while (*p1++);
1126:         write(cmd, savedfile, --p1 - savedfile);
1127:         write(cmd, "\n", 1);
1128:     }
1129: #endif
1130:     signals(sigtab1);
1131:     setexit();
1132:     if (((int)savint & 01) == 0)
1133:         signals(sigtab2);
1134: #ifdef YINT
1135:     else
1136:         yflg = 0;
1137: #endif
1138: #ifdef CKPT
1139:     if (!recovry)
1140: #endif
1141:         init();
1142:     setexit();
1143: cant:   do {
1144:         commands(0);
1145:     } while (are_you_sure());
1146:     if (immflg == 0) {
1147:         if (fflg)
1148:             if (backup(FILE))
1149:                 text_modified = 0;
1150:             else
1151:                 goto cant;
1152:         if (text_modified == 0)
1153:             backup(-TMP);
1154:         else if (modcount && eof)
1155:             if (backup(TMP) && prompt2)
1156:                 if (!curt)
1157:                     putsn(errtext[56]);
1158:     }
1159:     delexit(0);
1160: }
1161: 
1162: abort() {
1163:     register char *p;
1164:     register charac c;
1165: 
1166:     setnoaddr();
1167:     peekc = 0;
1168:     p = "ort\n";
1169:     while (*p)
1170:         if ((c = getchar()) != *p++) {
1171:             peekc = c;
1172:             errmsg(25);
1173:         }
1174: #ifdef LOG
1175:     ++logstats.lc_abort;
1176: #endif
1177:     delexit(1);
1178: }
1179: 
1180: linep *
1181: address() {
1182:     register minus;
1183:     register charac c;
1184:     register linep *a1, *start;
1185:     register n, relerr;
1186: 
1187:     minus = 0;
1188:     a1 = 0;
1189:     for ever {
1190:         c = getchar();
1191:         if ('0' <= c && c <= '9') {
1192:             peekc = c;
1193:             n = getnum();
1194:             if (a1 == 0) {
1195:                 a1 = zero;
1196:                 n += aflg;
1197: #ifdef LOG
1198:                 if (!globp)
1199:                     ++logstats.la_num;
1200: #endif
1201:             }
1202:             if (minus < 0)
1203:                 n = -n;
1204:             a1 += n;
1205:             minus = 0;
1206:             continue;
1207:         }
1208:         relerr = 0;
1209:         if (a1 || minus)
1210:             relerr++;
1211:         switch (c) {
1212:         case ' ':
1213:         case '\t':
1214:             continue;
1215: 
1216:         case '+':
1217:             minus += brcount;
1218:             if (a1 == 0)
1219:                 a1 = dot;
1220: #ifdef LOG
1221:             if (!globp)
1222:                 ++logstats.la_plus;
1223: #endif
1224:             continue;
1225: 
1226:         case '-':
1227:         case '^':   /* for upwards compatibility */
1228:             minus -= brcount;
1229:             if (a1 == 0)
1230:                 a1 = dot;
1231: #ifdef LOG
1232:             if (!globp)
1233:                 if (c == '^')
1234:                     ++logstats.la_caret;
1235:                 else
1236:                     ++logstats.la_minus;
1237: #endif
1238:             continue;
1239: 
1240:          /* search:	*/
1241:         case '?':
1242:             minus++;
1243:         case '/':
1244:             compile(c);
1245:             if (a1 == 0)
1246:                 a1 = dot;
1247:             if (a1 < zero)
1248:                 a1 = zero;
1249:             if (a1 > dol)
1250:                 a1 = dol;
1251:             start = a1;
1252: #ifdef LOG
1253:             if (!globp)
1254:                 if (minus)
1255:                     ++logstats.la_query;
1256:                 else
1257:                     ++logstats.la_slash;
1258: #endif
1259:             for ever {
1260:                 if (minus == 0) {
1261:                     if (++a1 > dol)
1262:                         a1 = zero;
1263:                 } else {
1264:                     if (--a1 < zero)
1265:                         a1 = dol;
1266:                 }
1267:                 if (execute(0, a1)) {
1268:                     minus = 0;
1269:                     relerr = 0;
1270:                     break;
1271:                 }
1272:                 if (a1 == start)
1273:                     errmsg(18);
1274:             }
1275:             break;
1276: 
1277:         case '$':
1278:             a1 = dol;
1279: #ifdef LOG
1280:             if (!globp)
1281:                 ++logstats.la_dol;
1282: #endif
1283:             break;
1284: 
1285:         case '.':
1286:             if ((peekc = getchar()) == '.') {
1287:                 peekc = 0;
1288:                 a1 = dotdot;
1289: #ifdef LOG
1290:                 if (!globp)
1291:                     ++logstats.la_dotdot;
1292: #endif
1293:             } else {
1294:                 a1 = dot;
1295: #ifdef LOG
1296:                 if (!globp)
1297:                     ++logstats.la_dot;
1298: #endif
1299:             }
1300:             break;
1301: 
1302:         case '\'':
1303:             if (((c = getchar()) | 040) < 'a' ||
1304:                 (c | 040) > 'z') {
1305:                 peekc = c;
1306:                 errmsg(19);
1307:             }
1308:             c |= 040;
1309: #ifdef LOG
1310:             if (!globp)
1311:                 ++logstats.la_quote;
1312: #endif
1313:         casemark:
1314: #ifdef EXTMARK
1315:             n = 3;
1316:             if ((peekc = getchar()) == '^') {
1317:                 n = 1;
1318:                 peekc = 0;
1319:             } else if (peekc == '$') {
1320:                 n = 2;
1321:                 if (names2[c - 'a'] == 0)
1322:                     n = 1;
1323:                 peekc = 0;
1324:             }
1325:             if (n & 01)
1326:                 if ((a1=findmark(names[c-'a'],0))==0) {
1327:                     a1 = dol;
1328:                     n = 0;
1329:                 }
1330:             if (n > 1 && names2[c - 'a']) {
1331:                 if (n == 3) {
1332:                     if (addr1 || addr2)
1333:                         errmsg(20);
1334:                     addr1 = a1;
1335:                 }
1336:                 a1 = findmark(names2[c - 'a'], dol);
1337:                 if (n == 2)
1338:                     break;
1339:                 addr2 = a1;
1340:                 return(0);
1341:             }
1342: #else
1343:             a1 = findmark(names[c - 'a'], dol);
1344: #endif
1345:             break;
1346: 
1347:         case '=':
1348: #ifdef LOG
1349:             if (!globp)
1350:                 ++logstats.la_equal;
1351: #endif
1352:             if ((peekc = getchar()) == '^')
1353:                 a1 = old_a1;
1354:             else if (peekc == '$')
1355:                 a1 = old_a2;
1356:             else {
1357:                 if (addr1 || addr2 || a1)
1358:                     errmsg(20);
1359:                 addr1 = old_a1;
1360:                 addr2 = old_a2;
1361:                 return(0);
1362:             }
1363:             peekc = 0;
1364:             break;
1365: 
1366:         default:
1367:             if ('A' <= c && c <= 'Z') {
1368:                 c |= 040;
1369: #ifdef LOG
1370:                 if (!globp)
1371:                     ++logstats.la_letter;
1372: #endif
1373:                 goto casemark;
1374:             }
1375:             peekc = c;
1376:             if (a1 == 0)
1377:                 if (c == ',' || c == ';')
1378:                     if (dot + 1 > dol)
1379:                         return(dol);
1380:                     else
1381:                         return(dot + 1);
1382:                 else
1383:                     return(0);
1384:             a1 += minus;
1385:             if (a1 < zero)
1386:                 a1 = zero + (zero != dol);
1387:             else if (a1 > dol)
1388:                 a1 = dol;
1389:             return(a1);
1390:         }
1391:         if (relerr)
1392:             errmsg(20);
1393:     }
1394: }
1395: 
1396: advance(alp, aep) {
1397:     register char *lp, *ep, *curlp;
1398:     register s_sav, i;
1399: 
1400:     lp = alp;
1401:     ep = aep;
1402:     for ever switch (*ep++) {
1403: 
1404:     case CCHR:
1405:         if (*ep++ == *lp++)
1406:             continue;
1407:         return(0);
1408: 
1409:     case CDOT:
1410:         if (*lp++)
1411:             continue;
1412:         return(0);
1413: 
1414:     case CDOL:
1415:         if (*lp == 0)
1416:             continue;
1417:         return(0);
1418: 
1419:     case CEOF:
1420:         loc2 = lp;
1421:         if (--s_tmp > 0)
1422:             return(0);
1423:         return(1);
1424: 
1425:     case CCL:
1426:     case NCCL:
1427:         if (cclass(ep, *lp++, ep[-1] == CCL)) {
1428:             ep += *ep;
1429:             continue;
1430:         }
1431:         return(0);
1432: 
1433:     case CBRA:
1434:         braslist[*ep++] = lp;
1435:         continue;
1436: 
1437:     case CKET:
1438:         braelist[*ep++] = lp;
1439:         continue;
1440: 
1441:     case CBACK:
1442:         if (braelist[i = *ep++] == 0)
1443:             errmsg(63);
1444:         if (backref(i, lp)) {
1445:             lp += braelist[i] - braslist[i];
1446:             continue;
1447:         }
1448:         return(0);
1449: 
1450:     case CBACK | STAR:
1451:         if (braelist[i = *ep++] == 0)
1452:             errmsg(63);
1453:         curlp = lp;
1454:         while (backref(i, lp))
1455:             lp += braelist[i] - braslist[i];
1456:         while (lp >= curlp) {
1457:             if (advance(lp, ep))
1458:                 return(1);
1459:             lp -= braelist[i] - braslist[i];
1460:         }
1461:         continue;
1462: 
1463:     case CDOT | STAR:
1464:         curlp = lp;
1465:         while (*lp++);
1466:         goto star;
1467: 
1468:     case CCHR | STAR:
1469:         curlp = lp;
1470:         while (*lp++ == *ep);
1471:         ep++;
1472:         goto star;
1473: 
1474:     case CCL | STAR:
1475:     case NCCL | STAR:
1476:         curlp = lp;
1477:         while (cclass(ep, *lp++, ep[-1] == (CCL | STAR)));
1478:         ep += *ep;
1479:         /* goto star; */
1480: 
1481:     star:
1482:         s_sav = s_tmp;
1483:         do {
1484:             if (--lp == locs)
1485:                 break;
1486:             if (advance(lp, ep))
1487:                 return(1);
1488:             s_tmp = s_sav;
1489:         } while (lp > curlp);
1490:         --s_tmp;
1491:         return(0);
1492: 
1493:     default:
1494:         errmsg(-26);
1495:     }
1496: }
1497: 
1498: linep *
1499: append(f, a, single, bkpf)
1500: func f;
1501: linep *a;
1502: {
1503:     register linep *a1, *a2, *rdot;
1504:     register nline, tl;
1505: 
1506:     nline = 0;
1507:     dot = a;
1508:     while ((*f)(single) == 0) {
1509:         if (dol >= endcore) {
1510:             if (sbrk(1024) == -1)
1511:                 errmsg(33);
1512:             endcore = (int)endcore + 1024;
1513:         }
1514:         tl = putline();
1515:         nline++;
1516:         a1 = ++dol;
1517:         a2 = a1 + 1;
1518:         rdot = ++dot;
1519:         while (a1 > rdot)
1520:             *--a2 = *--a1;
1521:         *rdot = tl;
1522:         if (bkpf) {
1523:             mods++;
1524:             backchk();
1525:         }
1526:         if (single)
1527:             break;
1528:     }
1529:     return(nline);
1530: }
1531: 
1532: are_you_sure() {
1533: #ifdef USE
1534:     if (alt)
1535:         return(1);
1536: #endif
1537:     if (!text_modified || fflg || immflg || zero == dol)
1538:         return(0);
1539:     return(yes_no(curt? "?forget" :
1540:         "did you forget to save your text", 1, 1, 0));
1541: }
1542: 
1543: argnum(ap)
1544: char **ap;
1545: {
1546:     register n;
1547:     register char *p;
1548: 
1549:     p = *ap;
1550:     n = 0;
1551:     while ('0' <= *p && *p <= '9')
1552:         n = n * 10 + *p++ - '0';
1553:     *ap = --p;
1554:     return(n);
1555: }
1556: 
1557: backchk() {
1558:     if (modcount == 0)
1559:         return;
1560:     if (mods >= modcount) {
1561:         mods = 0;
1562: #ifdef EOL
1563:         if (backup(TMP) && prompt2 && prompt3)
1564: #endif
1565: #ifndef EOL
1566:         if (backup(TMP) && prompt2)
1567: #endif
1568:             if (!curt)
1569:                 putsn(errtext[56]);
1570:     }
1571: }
1572: 
1573: backref(an, alp)
1574: char *alp;
1575: {
1576:     register n;
1577:     register char *bp, *lp;
1578: 
1579:     n = an;
1580:     bp = braslist[n];
1581:     lp = alp;
1582:     while (*bp++ == *lp++)
1583:         if (bp >= braelist[n])
1584:             return(1);
1585:     return(0);
1586: }
1587: 
1588: backup(af) {
1589:     register char *p1, *p2, *t2;
1590:     register linep *a1, *a2;
1591:     register func savint, savhup;
1592: 
1593:     if (io) {
1594:         putsn("******** backup: I/O in progress");
1595:         return(0);
1596:     }
1597:     flush_buf();
1598:     p1 = savedfile;
1599:     t2 = p2 = file;
1600:     while (*p2 = *p1++)
1601:         if (*p2++ == '/')
1602:             t2 = p2;
1603:     if (p2 > t2 + 10)
1604:         p2 = t2 + 10;
1605:     if (af != FILE && p2 >= &file[FNSIZE - 6])
1606:         errmsg(11);
1607:     switch (af < 0? -af : af) {
1608:         case FILE:  p1 = 0;     break;
1609:         case TMP:   p1 = dotedt;    break;
1610:         case INT:   p1 = dotint;    break;
1611:         case HUP:   p1 = dothup;    break;
1612:         case BAK:   p1 = dotbak;    break;
1613:         case TRM:   p1 = dottrm;    break;
1614:         default:    errmsg(-17);
1615:     }
1616:     if (p1)
1617:         while (*p2++ = *p1++);
1618:     if (af < 0) {
1619:         if (deltflg)
1620:             return(1);
1621:         return(!unlink(file));
1622:     }
1623:     if (dol == zero && !fflg) {
1624:         if (af == FILE)
1625:             if (curt)
1626:                 putsn("?48");
1627:             else
1628:                 putsn(errtext[48]);
1629:         return(1);
1630:     }
1631:     if (dol == zero)
1632:         return(1);
1633:     if (!iflg) {
1634:         savhup = signal(SIGHUP, 1);
1635:         savint = signal(SIGINT, 1);
1636:     }
1637:     if (over && af == FILE)
1638:         override();
1639:     io = create(file, (af == FILE? MODE : LMODE));
1640:     if (overfile) {
1641:         chmod(overfile, overmode);
1642:         overfile = 0;
1643:     }
1644:     if (io < 0) {
1645:         io = 0;
1646:         if (af != TMP) {
1647:             if (curt)
1648:                 putsn("?54");
1649:             else {
1650:                 puts2(errtext[54]);
1651:                 putsn(file);
1652:             }
1653:         }
1654:         if (!iflg) {
1655:             signal(SIGHUP, savhup);
1656:             signal(SIGINT, savint);
1657:         }
1658:         return(0);
1659:     }
1660:     io_w++;
1661:     a1 = addr1;
1662:     a2 = addr2;
1663:     addr1 = zero + 1;
1664:     addr2 = dol;
1665:     putfile();
1666:     close(io);
1667:     io = 0;
1668:     io_w = 0;
1669:     addr1 = a1;
1670:     addr2 = a2;
1671:     if (!iflg) {
1672:         signal(SIGHUP, savhup);
1673:         signal(SIGINT, savint);
1674:     }
1675:     return(1);
1676: }
1677: 
1678: #ifndef CKPT
1679: badsig(an) {
1680:     register n;
1681: 
1682:     if (n = backup(TMP))
1683:         putsn(errtext[56]);
1684:     puts("  Fatal Signal: ");
1685:     if (0 < an && an < NSTR && status[an])
1686:         putsn(status[an]);
1687:     else
1688:         printf("%d\n", an);
1689:     flush_buf();
1690:     if (n)
1691:         exit(1);
1692:     error();
1693: }
1694: #endif
1695: 
1696: blkio(b, buf, iofcn)
1697: func iofcn;
1698: {
1699:     lseek(tfile, 512L * b, 0);
1700:     if ((*iofcn)(tfile, buf, BLKSIZE) != BLKSIZE) {
1701:         badf++;
1702:         errmsg(-35);
1703:     }
1704: }
1705: 
1706: cclass(aset, ac, af)
1707: char *aset;
1708: charac ac;
1709: {
1710:     register char *set;
1711:     register n;
1712:     register charac c, m;
1713: 
1714:     set = aset;
1715:     if ((c = ac) == 0)
1716:         return(0);
1717:     n = *set++;
1718:     while (--n)
1719:         if (set[1] == '-' && n > 2) {
1720:             c = min(set[0], set[2]);
1721:             m = max(set[0], set[2]);
1722:             do {
1723:                 if (c == ac)
1724:                     return(af);
1725:             } while (++c != m);
1726:             set += 2;
1727:             c = ac;
1728:         } else
1729:             if (*set++ == c)
1730:                 return(af);
1731:     return(!af);
1732: }
1733: 
1734: #ifdef CKPT
1735: checkpoint(asig) {
1736:     extern etext;
1737:     register filedes f;
1738:     register char *p;
1739:     register func savint, savqit;
1740:     int n;
1741: 
1742:     savint = signal(SIGINT, 1);
1743:     savqit = signal(SIGQIT, 1);
1744:     p = &etext; /* won't work for -n, -i, or -z */
1745:     n = (char *)dol - p;
1746:     n += sizeof (int);
1747:     if ((f = create(cfname, LMODE)) < 0 ||
1748:         write(f, &n, sizeof n) != sizeof n) {
1749:         n = 66;
1750:         goto cerror;
1751:     }
1752: #ifdef pdp11    /* 16 bit byte count only */
1753:     if (n < 0) {
1754:         if (write(f, etext, 32256) != 32256) {
1755:             n = 66;
1756:             goto cerror;
1757:         }
1758:         n -= 32256; /* 63 blocks, since 64 is < 0 */
1759:         p += 32256;
1760:     }
1761: #endif
1762:     if (write(f, p, n) != n)
1763:         n = 66;
1764:     else
1765:         n = 0;
1766:     cerror:
1767:     close(f);
1768:     if (n) {
1769:         signal(SIGINT, savint);
1770:         signal(SIGQIT, savqit);
1771:         recovry = 0;
1772:         errmsg(n);
1773:     }
1774:     if (asig) {
1775:         puts2(status[asig]);
1776:         if (!curt)
1777:             puts(": Fatal error");
1778:     }
1779:     if (curt)
1780:         puts2("?CKPT ");
1781:     else {
1782:         puts2("Editing session checkpointed to \"");
1783:         puts2(cfname);
1784:         puts("\".\nTo recover your work, type:");
1785:         if (editor && *editor)
1786:             puts2(editor);
1787:         else
1788:             puts2("edit");
1789:         puts2(" -R");
1790:     }
1791:     puts(&tfname[tfnum]);
1792:     exit(1);
1793: }
1794: #endif
1795: 
1796: chk() {
1797:     register charac c;
1798:     register char *p2, *p1, *t2, **p;
1799:     register charac oldc;
1800:     long t;
1801:     struct stat s;
1802: 
1803:     if (*savedfile == '\0')
1804:         return(0);
1805:     t2 = p2 = file;
1806:     p1 = savedfile;
1807:     if (stat(p1, &s) >= 0)
1808:         t = s.st_mtime;
1809:     else
1810:         t = 0L;
1811:     while (*p2 = *p1++)
1812:         if (*p2++ == '/')
1813:             t2 = p2;
1814:     if (p2 > t2 + 10)
1815:         p2 = t2 + 10;
1816:     if (p2 >= &file[FNSIZE - 6])
1817:         return(0);
1818:     t2 = p2;
1819:     p = dots;
1820:     while (p1 = *p++) {
1821:         p2 = t2;
1822:         while (*p2++ = *p1++);
1823:         if (stat(file, &s) >= 0 && s.st_mtime >= t) {
1824:             if (curt) {
1825:                 puts2("?\"");
1826:                 puts2(file);
1827:                 puts2("\"  ");
1828:             } else {
1829:                 putsn("When you were last editing this file");
1830:                 putsn("you did not exit the editor normally,");
1831:                 puts2("leaving the file:  \"");
1832:                 puts2(file);
1833:                 if (p1 == dotedt) {
1834:                     putsn("\".\nIt contains your file up to the last \"[file saved]\"");
1835:                     putsn("message.  This file will be deleted if you do");
1836:                     putsn("not read it into the editor now.  If you read");
1837:                     putsn("it, then decide not to use it, exit the editor");
1838:                     putsn("with \"qi\".");
1839:                 } else
1840:                     putsn("\".");
1841:             }
1842:             return(yes_no(curt? "read" : "Do you wish to read it",
1843:                 1, -1, 0));
1844:         }
1845:     }
1846:     return(0);
1847: }
1848: 
1849: _cleanup() {
1850:     flush_buf();
1851: }
1852: 
1853: #ifdef CLEAR
1854: clear() {
1855:     register l, i;
1856: 
1857:     l = listf;
1858:     listf = 0;
1859:     puts2(clears);  /* clear sequence */
1860:     flush_buf();
1861:     i = 5;
1862:     while (--i >= 0)
1863:         putchar(0); /* ADM-3A's need padding at 19.2 */
1864:     putchar('\n');
1865:     listf = l;
1866: }
1867: #endif
1868: 
1869: commands(baseflg) {
1870:     extern getfile(), gettty();
1871:     register linep *a1;
1872:     register charac c;
1873:     register char *p;
1874:     register r, num;
1875: 
1876:     for ever {
1877: #ifdef AGAIN
1878:     if (agp) {
1879:         *agp++ = '\n';
1880:         *agp = '\0';
1881:     }
1882:     agf = 0;
1883:     agp = 0;
1884: #endif
1885:     immflg = 0;
1886: #ifdef LOG
1887:     if (logamp) {
1888:         ++logstats.lp_amp;
1889:         logamp = 0;
1890:     }
1891: #endif
1892:     if (!globp && (hupflag || termflg)) {
1893:         if (hupflag) {
1894:             backup(HUP);
1895:             puts2(errtext[57]);
1896:         } else {
1897:             backup(TRM);
1898:             puts2(errtext[58]);
1899:         }
1900:         delexit(1);
1901:     }
1902:     if (pflag) {
1903:         pflag = 0;
1904:         addr1 = addr2 = dot;
1905:         goto print;
1906:     }
1907:     if (!globp) {
1908: #ifdef USE
1909:         if (!alt) {
1910: #endif
1911:         if (modcount) {
1912:             if (text_modified > savf)
1913:                 mods++;
1914:             savf = text_modified;
1915:             backchk();
1916:         }
1917: #ifdef EOL
1918: #ifdef USE
1919:         if (prompt2 && prompt3 && !eflg2)
1920: #endif
1921: #ifndef USE
1922:         if (prompt2 && prompt3)
1923: #endif
1924: #endif
1925: #ifndef EOL
1926: #ifdef USE
1927:         if (prompt2 && !eflg2)
1928: #endif
1929: #ifndef USE
1930:         if (prompt2)
1931: #endif
1932: #endif
1933:         {
1934:             puts2(e_prompt);
1935:             flush_buf();
1936:         }
1937: #ifdef USE
1938:         }
1939: #endif
1940:     }
1941:     if (!globp) {
1942:         if (dotdot > dol)
1943:             dotdot = dol;
1944:         if (dotdot < zero)
1945:             dotdot = zero;
1946:         if (dot != lastdot) {
1947:             dotdot = lastdot;
1948:             lastdot = dot;
1949:         }
1950:     }
1951:     addr1 = 0;
1952:     addr2 = 0;
1953:     s_tmp = 0;
1954:     s_cnt = 0;
1955:     r = 1;
1956:     do {
1957:         addr1 = addr2;
1958:         if ((a1 = address()) == 0) {
1959:             c = getchar();
1960:             break;
1961:         }
1962:         addr2 = a1;
1963:         if ((c = getchar()) == ';') {
1964:             c = ',';
1965:             dot = a1;
1966:         }
1967:     } while (c == ',' && --r >= 0);
1968:     if (addr1 == 0)
1969:         addr1 = addr2;
1970:     if (!globp && !baseflg) {
1971:         if (addr1) {
1972:             old_a1 = addr1;
1973:             old_a2 = addr2;
1974:         }
1975:     }
1976:     line_num = (addr1? addr1 : dot) - zero;
1977: #ifdef AGAIN
1978:     if (c == 'o' || c == ctrl('Q')) { /* again command "o" */
1979:         if (c != ctrl('Q') && (peekc = getchar()) != '\n')
1980:             errmsg(1);
1981:         if (c == ctrl('Q'))
1982:             putchar(lastc = '\n');
1983:         if (*agbuf == 0)
1984:             errmsg(2);
1985:         agf++;
1986:         agp = agbuf;
1987:         c = *agp++;
1988:         peekc = 0;
1989: #ifdef LOG
1990:         ++logstats.lc_o;
1991: #endif
1992:     } else if (baseflg == 0 && globp == 0)
1993:         if (c != '\n') {
1994:             agp = agbuf;
1995:             *agp++ = c;  /* first char not yet saved */
1996:         }
1997: #endif
1998: 
1999:     switch (c) {
2000:     case 'a':
2001:         if ((peekc = getchar()) == 'b')
2002:             abort();
2003:         setdot();
2004: #ifdef XED
2005:         if (peekc != ' ' && peekc != '\n') {
2006:             c = peekc;
2007:             peekc = 0;
2008:             if (tack(c, 1))
2009:                 text_modified++;
2010: #ifdef LOG
2011:             ++logstats.lc_aslash;
2012: #endif
2013:             continue;
2014:         }
2015: #endif
2016:         line_num++;
2017:         num = addr2;
2018: #ifdef LOG
2019:         ++logstats.lc_append;
2020: #endif
2021:     caseadd:
2022:         if ((c = getchar()) == ' ') {
2023:             r = 1;
2024: #ifdef LOG
2025:             ++logstats.lc_aspace;
2026: #endif
2027:         } else {
2028: #ifndef XED
2029:             if (c != '\n') {
2030:                 peekc = c;
2031:                 newline();
2032:             }
2033: #endif
2034:             r = 0;
2035:         }
2036:         if (append(gettty, num, r, 1))
2037:             text_modified++;
2038:         continue;
2039: 
2040:     case 'b':
2041:         setnoaddr();
2042:         white_space();
2043:         if ((brcount = setnum(1)) <= 0)
2044:             brcount = 1;
2045: #ifdef LOG
2046:         ++logstats.lc_browse;
2047: #endif
2048:         continue;
2049: 
2050:     case 'c':
2051:         if ((peekc = getchar()) == 'o') {  /* co == t */
2052:             peekc = 0;
2053: #ifdef LOG
2054:             ++logstats.lc_copy;
2055: #endif
2056:             goto casecopy;
2057:         }
2058:         if (peekc != '\n')
2059:             goto casesub;
2060:         newline();
2061:         setdot();
2062:         nonzero();
2063:         delete();
2064:         text_modified++;
2065: #ifdef LOG
2066:         ++logstats.lc_change;
2067: #endif
2068:         append(gettty, addr1 - 1, 0, 0);
2069:         continue;
2070: 
2071:     case 'd':
2072: #ifdef DEBUG
2073: /*		*du	Dump command (testing only)	*/
2074:         if ((peekc = getchar()) == 'u') {
2075:             peekc = 0;
2076:             dump();
2077:             continue;
2078:         }
2079: #endif
2080:         if ((peekc = getchar()) == ' ' || peekc == ',') {
2081:             peekc = 0;
2082:             white_space();
2083:             p = linebuf;
2084:             if ((c = getchar()) == '\n')
2085:                 errmsg(51);
2086:             do {
2087:                 *p++ = c;
2088: #ifndef ALLOC
2089:                 if (p >= &linebuf[LBSIZE - 2])
2090: #else
2091:                 if (p >= &linebuf[lbsize - 2])
2092: #endif
2093:                     errmsg(11);
2094:             } while ((c = getchar()) >= 0 && c != '\n');
2095:             *p = 0;
2096: #ifdef LOG
2097:             ++logstats.lc_directory;
2098: #endif
2099:             if (chdir(linebuf) < 0)
2100:                 errmsg(51);
2101:             continue;
2102:         }
2103: #ifdef PAGE
2104:         if (peekc == '=') { /* d=<depth> */
2105:             peekc = 0;
2106:             setnoaddr();
2107:             pcount = setnum(PAGSIZ);
2108: #ifdef LOG
2109:             ++logstats.lc_depth;
2110: #endif
2111:             continue;
2112:         }
2113: #endif
2114:         newline();
2115:         setdot();
2116:         nonzero();
2117:         delete();
2118:         text_modified++;
2119: #ifdef LOG
2120:         ++logstats.lc_delete;
2121: #endif
2122:         continue;
2123: 
2124:     case 'e':
2125:         eagain:
2126:         if ((peekc = getchar()) != '\n') {
2127: #ifdef EOL
2128:             if (peekc == '=') {  /* e=c - set eol to 'c' */
2129:                 peekc = 0;
2130:                 if (immflg)
2131:                     errmsg(8);
2132:                 setnoaddr();
2133:                 eol = setchar(0);
2134: #ifdef LOG
2135:                 ++logstats.lc_eol;
2136: #endif
2137:                 continue;
2138:             }
2139: #endif
2140: #ifdef TABS
2141:             if (peekc == 'x') {
2142:                 peekc = 0;
2143:                 if (immflg)
2144:                     errmsg(8);
2145:                 if ((c = getchar()) != 'p')
2146:                     errmsg(8);
2147:                 newline();
2148:                 if (!tabc)
2149:                     errmsg(3);
2150:                 if (maxtab < 0)
2151:                     errmsg(9);
2152:                 if (exp())
2153:                     text_modified++;
2154: #ifdef LOG
2155:                 ++logstats.lc_exp;
2156: #endif
2157:                 continue;
2158:             }
2159: #endif
2160:             if ('0' <= peekc && peekc <= '9') {
2161:                 c = getnum();
2162:                 newline();
2163:                 if (0 <= c && c < NERR)
2164:                     printf("%3d: %s\n",
2165:                         c, errtext[c]);
2166: #ifdef LOG
2167:                 ++logstats.lc_errmsg;
2168: #endif
2169:                 continue;
2170:             }
2171:             if (peekc == '+' || peekc == '-') {
2172:                 c = peekc;
2173:                 peekc = 0;
2174:                 newline();
2175:                 curt = c == '-';
2176: #ifdef LOG
2177:                 if (curt)
2178:                     ++logstats.lc_eminus;
2179:                 else
2180:                     ++logstats.lc_eplus;
2181: #endif
2182:                 continue;
2183:             }
2184:             if (peekc == 'i') {
2185:                 peekc = 0;
2186:                 if (immflg)
2187:                     errmsg(8);
2188:                 immflg++;
2189:                 goto eagain;
2190:             }
2191:             setnoaddr();
2192:             if (fflg)
2193:                 errmsg(4);
2194:             if (peekc != ' ' && peekc != ',')
2195:         illfnm:     errmsg(5);
2196:             scopy(savedfile, tempfile);
2197:             if (zero == dol || text_modified == 0)
2198:                 backup(-TMP);
2199:             savedfile[0] = 0;
2200:             filename();
2201:             if (text_modified && are_you_sure()) {
2202:                 scopy(tempfile, savedfile);
2203:                 error();
2204:             }
2205:             peekc = '\n';
2206:         } else {
2207:             setnoaddr();
2208:             if (text_modified) {
2209:                 r = peekc;
2210:                 peekc = 0;
2211:                 if (are_you_sure()) {
2212:                     peekc = r;
2213:                     error();
2214:                 }
2215:                 peekc = r;
2216:             }
2217:             if (zero == dol || text_modified == 0)
2218:                 backup(-TMP);
2219:         }
2220:         if (init())
2221:             continue;
2222: #ifdef LOG
2223:         ++logstats.lc_edit;
2224: #endif
2225:         goto caseread;
2226: 
2227:     case 'f':
2228:         setnoaddr();
2229: #ifdef TABS
2230:         if ((peekc = getchar()) == '=') {  /* f=c fill char */
2231:             peekc = 0;
2232:             tabfill = setchar(TABFILL);
2233: #ifdef LOG
2234:             ++logstats.lc_fillset;
2235: #endif
2236:             continue;
2237:         }
2238: #endif
2239:         if ((c = getchar()) != '\n') {
2240:             if (fflg)
2241:                 errmsg(4);
2242:             peekc = c;
2243:             filename();
2244:             scopy(file, savedfile);
2245: #ifdef LOG
2246:             ++logstats.lc_fset;
2247: #endif
2248:             if (prompt2 == 0)
2249:                 continue;
2250:         }
2251: #ifdef LOG
2252:           else
2253:             ++logstats.lc_fshow;
2254: #endif
2255:         putsn(savedfile);
2256:         continue;
2257: 
2258:     case 'g':
2259:         global(1);
2260:         continue;
2261: 
2262:     case 'h':
2263: #ifdef HELP
2264:         if ((peekc = getchar()) == 'e') {  /* he[lp] */
2265:             peekc = 0;
2266:             setnoaddr();
2267:             skip_rest();
2268: #ifdef LOG
2269:             ++logstats.lc_help;
2270: #endif
2271:             if ((doc = open(help, 0)) > 0) {
2272:                 while ((c = read(doc, linebuf,
2273: #ifndef ALLOC
2274:                     LBSIZE)) > 0)
2275: #else
2276:                     lbsize)) > 0)
2277: #endif
2278:                     write(1, linebuf, c);
2279:                 close(doc);
2280:             }
2281:             doc = 0;
2282:             continue;
2283:         }
2284: #endif
2285:         if (zero != dol) {
2286:             setdot();
2287:             nonzero();
2288:         }
2289: #ifdef LOG
2290:         ++logstats.lc_header;
2291: #endif
2292:         header();
2293:         continue;
2294: 
2295:     case 'i':
2296:         setdot();
2297: #ifdef XED
2298:         if ((peekc = getchar()) != ' ' && peekc != '\n') {
2299:             c = peekc;
2300:             peekc = 0;
2301:             if (tack(c, 0))
2302:                 text_modified++;
2303: #ifdef LOG
2304:             ++logstats.lc_islash;
2305: #endif
2306:             continue;
2307:         }
2308: #endif
2309:         nonzero();
2310:         num = addr2 - 1;
2311: #ifdef LOG
2312:         ++logstats.lc_insert;
2313: #endif
2314:         goto caseadd;
2315: 
2316: #ifdef XED
2317:     case 'j':
2318:         setdot();
2319:         nonzero();
2320:         join();
2321:         text_modified++;
2322:         continue;
2323: #endif
2324: 
2325:     case 'k':
2326:         if ((c = getchar()) == '\n') {
2327:             setnoaddr();
2328: #ifdef LOG
2329:             ++logstats.lc_klist;
2330: #endif
2331:             printmarks();
2332:             continue;
2333:         }
2334:         if ('A' <= c && c <= 'Z')
2335:             c |= 040;
2336:         if (c < 'a' || c > 'z')
2337:             errmsg(0);
2338:         newline();
2339:         setdot();
2340:         nonzero();
2341: #ifdef HUGE
2342:         r = hugef ^ 01;
2343: #else
2344: #define r   1
2345: #endif
2346: #ifdef EXTMARK
2347:         if (addr1 != addr2) {
2348:             names[c - 'a'] = *addr1 | r;
2349:             names2[c - 'a'] = *addr2 | r;
2350:         } else {
2351:             names[c - 'a'] = *addr2 | r;
2352:             names2[c - 'a'] = 0;
2353:         }
2354: #else
2355:         names[c - 'a'] = *addr2 | r;
2356: #endif
2357: #ifdef LOG
2358:         ++logstats.lc_kset;
2359: #endif
2360:         continue;
2361: #ifndef HUGE
2362: #undef  r
2363: #endif
2364: 
2365:     case 'm':
2366: #ifdef DUMB
2367:         if ((peekc = getchar()) == '\n') {
2368:             setnoaddr();
2369:             peekc = 0;
2370:             dumbf ^= 01;
2371: #ifdef LOG
2372:             ++logstats.lc_magic;
2373: #endif
2374:             if (curt)
2375:                 putsn(dumbf? off : on);
2376:             else {
2377:                 puts2("\"$&[^.*\\(\\)\" have ");
2378:                 if (dumbf)
2379:                     puts2(no);
2380:                 putsn("special meaning");
2381:             }
2382:             continue;
2383:         }
2384: #endif
2385:         if ((peekc = getchar()) == 'o') {  /* mo == m */
2386:             peekc = 0;
2387: #ifdef LOG
2388:             ++logstats.lc_moove;
2389: #endif
2390:         }
2391: #ifdef LOG
2392:           else
2393:             ++logstats.lc_move;
2394: #endif
2395:         move(0);
2396:         text_modified++;
2397:         continue;
2398: 
2399:     case 'n':
2400:         setnoaddr();
2401: #ifdef PIPE
2402:         if ((peekc = getchar()) == '+') {
2403:             peekc = 0;
2404:             newline();
2405:             pno = 1;
2406: #ifdef LOG
2407:             ++logstats.lc_numplus;
2408: #endif
2409:             continue;
2410:         }
2411:         if (peekc == '-') {
2412:             peekc = 0;
2413:             newline();
2414:             pno = -1;
2415: #ifdef LOG
2416:             ++logstats.lc_numinus;
2417: #endif
2418:             continue;
2419:         }
2420: #endif
2421:         newline();
2422:         prompt1 ^= 01;
2423: #ifdef LOG
2424:         ++logstats.lc_numbers;
2425: #endif
2426:         if (curt)
2427:             putsn(prompt1? on : off);
2428:         else {
2429:             if (prompt1 == 0)
2430:                 puts2(no);
2431:             putsn("line numbers");
2432:         }
2433:         continue;
2434: 
2435:     case '\n':
2436:         if (globp || addr2 > dol)
2437:             continue;
2438:         if (addr2 == 0) {
2439:             addr1 = addr2 = dot + 1;
2440:             if (addr2 <= dol)
2441:                 line_num++;
2442:             if (brcount != 1) {
2443:                 addr2 = dot + brcount;
2444:                 if (addr1 > dol)
2445:                     continue;
2446:                 if (addr2 > dol)
2447:                     addr2 = dol;
2448:                 if (addr2 < zero)
2449:                     addr2 = zero;
2450: #ifdef CLEAR
2451:                 if (zflg && addr2 - addr1 > pcount / 2)
2452:                     clear();
2453: #endif
2454:             }
2455:         }
2456:         if (addr2 <= dol) {
2457:             pflag = 0;
2458:             goto print;
2459:         }
2460:         continue;
2461: 
2462:     case 'l':
2463:         listf++;
2464: #ifdef LOG
2465:         ++logstats.lc_list;
2466: #endif
2467:     case 'p':
2468:         if ((peekc = getchar()) == 'a') {
2469:             peekc = 0;
2470:     case ':':
2471:     case '*':
2472:             num = 0;
2473:             if (c == ':' || c == '*') {
2474:                 if ((peekc = getchar()) == ' ' ||
2475:                     peekc == '\t') {
2476:                     skip_rest();    /* comments */
2477: #ifdef LOG
2478:                     ++logstats.lc_comment;
2479: #endif
2480:                     continue;
2481:                 }
2482:                 r = peekc;
2483:                 peekc = 0;
2484: #ifdef LOG
2485:                 if (r == '-' || r == '+')
2486:                     ++logstats.lc_clnminus;
2487:                 else if (c == '*')
2488:                     ++logstats.lc_star;
2489:                 else
2490:                     ++logstats.lc_colon;
2491: #endif
2492:                 while (r == '-' || r == '^' || r == '+') {
2493:                     if (r == '+')
2494:                         ++num;
2495:                     else
2496:                         --num;
2497:                     r = getchar();
2498:                 }
2499:                 peekc = r;
2500:             }
2501: #ifdef LOG
2502:               else
2503:                 if (c != 'p')
2504:                     ++logstats.lc_print;
2505: #endif
2506:             newline();
2507:             pflag = 0;
2508:             if (addr1 == addr2) {
2509:                 if (num == -1 && c == ':') {
2510:                     if (addr2 == 0)
2511:                         addr2 = dot;
2512:                     addr1 = addr2 - pcount;
2513:                     if (addr1 <= zero)
2514:                         addr1 = zero + 1;
2515: #ifdef CLEAR
2516:                     if (zflg)
2517:                         clear();
2518: #endif
2519:                     goto print;
2520:                 }
2521:                 num *= pcount;
2522:                 if (c == '*')
2523:                     num -= (pcount + 1) / 2;
2524:                 if (addr1 == 0)
2525:                     a1 = dot + (num? num : 1);
2526:                 else
2527:                     a1 = addr1 + num;
2528:                 if (a1 <= zero)
2529:                     a1 = zero + 1;
2530:                 addr1 = addr2 = a1;
2531:             }
2532:             nonzero();
2533:             if (addr1 == addr2 || addr2 > dol ||
2534:                 addr2 <= zero)
2535:                 addr2 = dol;
2536:             setdot();
2537: #ifdef CLEAR
2538:             if (zflg && addr2 - addr1 > pcount / 2)
2539:                 clear();
2540: #endif
2541: #ifndef PAGE
2542:             if (addr2 > addr1 + pcount)
2543:                 addr2 = addr1 + pcount;
2544:             goto print;
2545: #else
2546:             page();
2547:             listf = 0;
2548: #ifdef PARENS
2549:             parenf = 0;
2550: #endif
2551: #ifdef STRLEN
2552:             quotef = 0;
2553: #endif
2554:             continue;
2555: #endif
2556:         } else if (peekc == 'p' || peekc == 'l') {
2557:             peekc = 0;
2558:             addr1 = zero + 1;
2559:             addr2 = dol;
2560: #ifdef LOG
2561:             ++logstats.lc_pprint;
2562: #endif
2563:         }
2564:         newline();
2565:         pflag = 0;
2566:     print:
2567:         setdot();
2568:         nonzero();
2569:         a1 = addr1;
2570: #ifdef PARENS
2571:         parenc[0] = 0;
2572:         parenc[1] = 0;
2573:         parenc[2] = 0;
2574: #endif
2575:         do {
2576:             col = 0;
2577:             printlno(line_num = a1 - zero);
2578:             puts(getline(*a1++));
2579:         } while (a1 <= addr2);
2580:         dot = addr2;
2581:         listf = 0;
2582: #ifdef PARENS
2583:         parenf = 0;
2584: #endif
2585: #ifdef STRLEN
2586:         quotef = 0;
2587: #endif
2588:         continue;
2589: 
2590:     case 'q':
2591:         if ((peekc = getchar()) == 'i') {  /* qi - immediate */
2592:             peekc = 0;
2593:             newline();
2594:             immflg++;
2595: #ifdef LOG
2596:             ++logstats.lc_qimm;
2597: #endif
2598:             return;
2599:         }
2600: #ifdef STRLEN
2601:         if (peekc == '=') { /* q=cc  set quote chars */
2602:             peekc = 0;
2603:             if ((c = getchar()) == '\\')
2604:                 c = getchar();
2605:             quotec = quotec2 = c;
2606: #ifdef LOG
2607:             ++logstats.lc_quote;
2608: #endif
2609:             if (c != '\n') {
2610:                 if ((c = getchar()) == '\\')
2611:                     c = getchar();
2612:                 if (c == '\n')
2613:                     continue;
2614:                 quotec2 = c;
2615:             } else {
2616:                 quotec = 0;
2617:                 quotec2 = 0;
2618:                 continue;
2619:             }
2620:             if (c != '\n')
2621:                 newline();
2622:             continue;
2623:         }
2624: #endif
2625:         setnoaddr();
2626:         if ((peekc = getchar()) != '\n')
2627:             errmsg(25);
2628:         peekc = 0;
2629: #ifdef LOG
2630:         ++logstats.lc_quit;
2631: #endif
2632:         return;
2633: 
2634:     case 'r':
2635: #ifdef LOG
2636:         ++logstats.lc_read;
2637: #endif
2638:     caseread:
2639:         filename();
2640:         if ((io = open(file, 0)) < 0) {
2641:             io = 0;
2642:             lastc = '\n';
2643:             if (curt)
2644:                 errmsg(53);
2645:             puts2(errtext[53]);
2646:             putsn(file);
2647:             error();
2648:         }
2649:         setall();
2650:         ninbuf = 0;
2651:         r = append(getfile, addr2, 0, 0);
2652:         if (prompt2)
2653:             printf((curt? prcntu : errtext[55]),
2654:                 r, (r == 1? null : quote_s));
2655:         close(io);
2656:         io = 0;
2657: #ifdef LOG
2658:         logstats.lt_rlines += r;
2659: #endif
2660:         if (num_reads++ || fflg) {
2661:             if (r)
2662:                 text_modified++;
2663:         } /* else
2664: 			text_modified = 0; */
2665:         if ((c == 'e' && bflg == 1) || bflg2 == 1) {
2666:             bflg2 = 0;
2667:             backup(BAK);
2668:         }
2669:         continue;
2670: 
2671:     case 's':
2672:         if (!globp && (peekc = getchar()) == '\n') {  /* w;q */
2673:             setnoaddr();
2674: #ifdef LOG
2675:             ++logstats.lc_stop;
2676: #endif
2677:             if (text_modified && !fflg)
2678:                 if (backup(FILE) == 0)
2679:                     error();  /* errmsg(10) */
2680:             peekc = text_modified = 0;
2681: #ifdef LOG
2682:             logstats.lt_wlines += dol - zero;
2683: #endif
2684:             return;
2685:         }
2686:         if (peekc == 'a') {  /* sa - count before auto-save */
2687:             setnoaddr();
2688:             peekc = 0;
2689:             modcount = setnum(MODCNT);
2690:             mods = 0;
2691: #ifdef LOG
2692:             ++logstats.lc_savecount;
2693: #endif
2694:             continue;
2695:         }
2696:     casesub:
2697:         setdot();
2698:         nonzero();
2699:         substitute(globp);
2700:         text_modified++;
2701: #ifdef LOG
2702:         if (c == 's')
2703:             ++logstats.lc_substitute;
2704:         else
2705:             ++logstats.lc_cslash;
2706: #endif
2707:         continue;
2708: 
2709:     case 't':
2710: #ifdef TABS
2711:         if ((peekc = getchar()) == '=') {  /* t=c tab char */
2712:             setnoaddr();
2713:             peekc = 0;
2714:             tabc = setchar(0);
2715: #ifdef LOG
2716:             ++logstats.lc_tabchar;
2717: #endif
2718:             continue;
2719:         } else if (peekc == ',') {  /* t,nn  set tabs */
2720:             setnoaddr();
2721: #ifdef LOG
2722:             ++logstats.lc_tabset;
2723: #endif
2724:             while ((c = getchar()) == ',') {
2725:                 while ((c = getchar()) == ',');
2726:                 if ((c < '0' || c > '9') && c != '-')
2727:                     break;
2728:                 peekc = c;
2729:                 settab(getsnum());
2730:             }
2731:             peekc = c;
2732:             newline();
2733:             continue;
2734:         } else if (peekc == '\n') { /* list tabs */
2735:             setnoaddr();
2736:             peekc = 0;
2737: #ifdef LOG
2738:             ++logstats.lc_tablist;
2739: #endif
2740:             listabs();
2741:             continue;
2742:         }
2743: #endif
2744: #ifdef LOG
2745:         ++logstats.lc_transfer;
2746: #endif
2747:     casecopy:
2748:         move(1);
2749:         text_modified++;
2750:         continue;
2751: 
2752: #ifdef UNDO
2753:     case 'u':
2754:         setnoaddr();
2755:         newline();
2756:         undo();
2757: #ifdef LOG
2758:         ++logstats.lc_undo;
2759: #endif
2760:         continue;
2761: #endif
2762: 
2763:     case 'v':
2764:         global(0);
2765:         continue;
2766: 
2767:     case 'w':
2768: #ifdef PAGE
2769:         if ((peekc = getchar()) == '=') {  /* w=<width> */
2770:             peekc = 0;
2771:             ccount = setnum(CCOUNT);
2772: #ifdef LOG
2773:             ++logstats.lc_width;
2774: #endif
2775:             continue;
2776:         }
2777: #endif
2778:         if ((peekc = getchar()) == 'i') {   /* wi over-ride */
2779:             ++immflg;
2780:             peekc = 0;
2781: #ifdef LOG
2782:             ++logstats.lc_wimm;
2783: #endif
2784:         }
2785: #ifdef LOG
2786:           else
2787:             ++logstats.lc_write;
2788: #endif
2789:         filename();
2790: #ifdef LOG
2791:         if (appflg) {
2792:             --logstats.lc_write;
2793:             ++logstats.lc_wonto;
2794:         }
2795: #endif
2796:         if (globp) {
2797:             setdot();
2798:             appflg++;
2799:         } else
2800:             setall();
2801:         if (dol == zero) {
2802:             if (curt)
2803:                 putsn("?48");
2804:             else
2805:                 putsn(errtext[48]);
2806:             if (!fflg || appflg)
2807:                 continue;
2808:         }
2809:         if (over || immflg)
2810:             override();
2811:         if (appflg)
2812:             io = open(file, 1);
2813:         if (!appflg || io < 0)
2814:             io = creat(file, MODE);
2815:         if (overfile) {
2816:             chmod(overfile, overmode);
2817:             overfile = 0;
2818:         }
2819:         if (io < 0) {
2820:             io = 0;
2821:             if (curt)
2822:                 errmsg(54);
2823:             puts2(errtext[54]);
2824:             putsn(file);
2825:             error();
2826:         }
2827:         io_w++;
2828:         if (appflg)
2829:             lseek(io, 0L, 2);   /* append onto file */
2830:         putfile();
2831:         close(io);
2832:         io = 0;
2833:         io_w = 0;
2834:         if (addr1 == zero + 1 && addr2 == dol)
2835:             text_modified = 0;
2836: #ifdef LOG
2837:         logstats.lt_wlines += dol - zero;
2838: #endif
2839:         continue;
2840: 
2841: #ifdef USE
2842:     case '@':
2843:         setnoaddr();
2844:         if (alt)
2845:             errmsg(6);
2846:         if ((peekc = getchar()) == 'p')
2847:             peekc = 0;
2848:         else
2849:             eflg2++;
2850:         if ((peekc = getchar()) == '\n' && altfile[0]) {
2851:             peekc = 0;
2852:             goto altname;
2853:         }
2854:         if ((c = getchar()) != ' ' && c != '\t' && c != ',')
2855:             errmsg(5);
2856:         white_space();
2857:         if ((c = getchar()) == '\n')
2858:             errmsg(7);
2859:         p = altfile;
2860:         *p++ = c;
2861:         while ((c = getchar()) != '\n') {
2862:             if (c < 0)
2863:                 errmsg(59);
2864:             *p++ = c;
2865:         }
2866:         *p = '\0';
2867:     altname:
2868: #ifdef LOG
2869:         ++logstats.lc_at;
2870: #endif
2871:         if ((alt = open(altfile, 0)) < 0) {
2872:             alt = 0;    /* this MUST be 0 */
2873:             lastc = '\n';
2874:             if (curt)
2875:                 errmsg(53);
2876:             puts2(errtext[53]);
2877:             putsn(altfile);
2878:             error();
2879:         }
2880:         continue;
2881: #endif
2882: 
2883: #ifdef DEBUG
2884:     case '#':   /* toggle debug flag */
2885:         if (addr1 != addr2 || addr1 != zero)
2886:             goto illcmd;
2887:         newline();
2888:         tflg ^= 01;
2889:         continue;
2890: 
2891: #ifdef XDEL
2892:     case '`':
2893:         setnoaddr();
2894:         newline();
2895:         if (ndeleted == 0)
2896:             errmsg(16);
2897:         printf("deleted = %o  ndeleted = %d\n", deleted, ndeleted);
2898:         { register n, *bp, nl;
2899:             int tl;
2900: 
2901:             tl = deleted;
2902:             bp = getblock(tl, READ);
2903: #ifdef HUGE
2904:             tl &= _1[hugef];
2905: #else
2906:             tl &= _1;
2907: #endif
2908:             nl = nleft / sizeof(linep);
2909:             for (n = 0; n < ndeleted; n++) {
2910:                 printf("%7d: %6o\n", n + 1, *bp++);
2911:                 if (--nl <= 0) {
2912: #ifdef HUGE
2913:                 bp = getblock(tl += _2[hugef], READ);
2914: #else
2915:                 bp = getblock(tl += _2, READ);
2916: #endif
2917:                 nl = nleft / sizeof(linep);
2918:                 }
2919:             }
2920:         }
2921:         continue;
2922: #endif
2923: #endif
2924: 
2925: #ifdef XDEL
2926:     case 'x':
2927:         newline();
2928:         r = undelete();
2929: #ifdef LOG
2930:         ++logstats.lc_xundelete;
2931: #endif
2932:         if (prompt2)
2933:             printf((curt? prcntu : errtext[55]),
2934:                 r, (r == 1? null : quote_s));
2935:         text_modified++;
2936:         continue;
2937: #endif
2938: 
2939: #ifdef YINT
2940:     case 'y':
2941:         if ((c = getchar()) == '+') {
2942:             setdot();
2943:             nonzero();
2944:             newline();
2945:             if (zero == dol)
2946:                 yplus = 0;
2947:             else
2948:                 yplus = *addr2 | 01;
2949:             yflg = 1;
2950: #ifdef LOG
2951:             ++logstats.lc_yplus;
2952: #endif
2953:         } else if (c == '-') {
2954:             setnoaddr();
2955:             newline();
2956:             yflg = 0;
2957: #ifdef LOG
2958:             ++logstats.lc_yminus;
2959: #endif
2960:         } else {
2961:             setnoaddr();
2962:             peekc = c;
2963:             newline();
2964:             yflg = 1;
2965:             yplus = 0;
2966: #ifdef LOG
2967:             ++logstats.lc_yintr;
2968: #endif
2969:         }
2970:         continue;
2971: #endif
2972: 
2973: #ifdef PIPE
2974:     case '|':
2975: #ifndef XED
2976:         if (globp)      /* turkeys will be turkeys */
2977:             errmsg(61);
2978: #endif
2979:         if (noshell)
2980:             errmsg(52);
2981:         if ((peekc = getchar()) == '+') {
2982:             peekc = 0;
2983:             newline();
2984:             setnoaddr();
2985:             strict++;
2986: #ifdef LOG
2987:             ++logstats.lc_piplus;
2988: #endif
2989:             continue;
2990:         } else if (peekc == '-') {
2991:             peekc = 0;
2992:             newline();
2993:             setnoaddr();
2994:             strict = 0;
2995: #ifdef LOG
2996:             ++logstats.lc_piminus;
2997: #endif
2998:             continue;
2999:         }
3000:         setdot();
3001:         shell();
3002:         continue;
3003: #endif
3004: 
3005:     case '!':
3006: #ifndef XED
3007:         if (globp)
3008:             errmsg(61);
3009: #endif
3010:         if (noshell)
3011:             errmsg(52);
3012:         setnoaddr();
3013:         shell();
3014:         continue;
3015: 
3016: #ifdef CKPT
3017:     case 'z':
3018:         newline();
3019:         setnoaddr();
3020:         checkpoint(0);  /* doesn't return */
3021: #endif
3022: 
3023:     case EOF:
3024: #ifdef USE
3025:         if (!baseflg && alt) {
3026:             close(alt);
3027:             alt = 0;
3028:             eflg2 = 0;
3029:             continue;
3030:         }
3031: #endif
3032:         return;
3033: 
3034:     }
3035:     illcmd:
3036:         errmsg(8);
3037:     }   /* nothing lasts "for ever" */
3038: }
3039: 
3040: compile(aeof)
3041: charac aeof;
3042: {
3043:     register charac eof, c;
3044:     register char *ep, *lastep, *bracketp;
3045:     register cclcnt;
3046:     char bracket[NBRA];
3047: 
3048:     ep = expbuf;
3049:     lastep = 0;
3050:     eof = aeof;
3051:     bracketp = bracket;
3052:     if ((c = getchar()) == eof || c == '\n') {
3053:         if (*ep == 0)
3054:             errmsg(27);
3055:         if (c == '\n')
3056:             peekc = c;
3057:         return;
3058:     }
3059:     circfl = 0;
3060:     nbra = 0;
3061:     if (
3062: #ifdef DUMB
3063:         !dumbf &&
3064: #endif
3065:             c == '^') {
3066:         c = getchar();
3067:         circfl++;
3068: #ifdef LOG
3069:         ++logstats.lp_caret;
3070: #endif
3071:     }
3072: /*	if (c == '*') {		/* if first = *, then quote it */
3073: /*		*ep++ = CCHR;	*/
3074: /*		*ep++ = c;	*/
3075: /*		c = 0;	*/
3076: /*	}	*/
3077:     peekc = c;
3078:     for ever {
3079:         if (ep >= &expbuf[ESIZE - 2 - (bracketp - bracket) * 2])
3080:             break;
3081:         c = getchar();
3082:         if (c == eof || c == '\n') {
3083:             while (bracketp > bracket) {
3084:                 *ep++ = CKET;
3085:                 *ep++ = *--bracketp;
3086:             }
3087:             *ep++ = CEOF;
3088:             if (c == '\n') {
3089:                 if (prompt2)
3090:                     pflag++;
3091:                 peekc = c;
3092:             }
3093:             return;
3094:         }
3095:         if (c != '*')
3096:             lastep = ep;
3097: #ifdef DUMB
3098:         if (dumbf && c >= 0)
3099:             goto defchar;
3100: #endif
3101:         switch (c) {
3102:         case '\\':
3103:             if ((c = getchar()) == '(') {
3104:                 if (nbra >= NBRA) {
3105:                     c = 44;
3106:                     goto cerror;
3107:                 }
3108:                 *bracketp++ = nbra;
3109:                 *ep++ = CBRA;
3110:                 *ep++ = nbra++;
3111: #ifdef LOG
3112:                 ++logstats.lp_paren;
3113: #endif
3114:                 continue;
3115:             }
3116:             if (c == ')') {
3117:                 if (bracketp <= bracket) {
3118:                     c = 45;
3119:                     goto cerror;
3120:                 }
3121:                 *ep++ = CKET;
3122:                 *ep++ = *--bracketp;
3123:                 continue;
3124:             }
3125:             if ('1' <= c && c < '1' + nbra) {
3126:                 *ep++ = CBACK;
3127:                 *ep++ = c - '1';
3128: #ifdef LOG
3129:                 ++logstats.lp_digit;
3130: #endif
3131:                 continue;
3132:             }
3133:             if (c == '\n') {
3134:                 c = 46;
3135:                 goto cerror;
3136:             }
3137:         defchar:
3138:         default:
3139:             *ep++ = CCHR;
3140:             *ep++ = c;
3141:             continue;
3142: 
3143:         case '.':
3144:             *ep++ = CDOT;
3145: #ifdef LOG
3146:             ++logstats.lp_dot;
3147: #endif
3148:             continue;
3149: 
3150:         case '*':
3151:             if (lastep == 0 ||
3152:                 *lastep == CBRA || *lastep == CKET)
3153:                 goto defchar;
3154:             *lastep |= STAR;
3155: #ifdef LOG
3156:             ++logstats.lp_star;
3157: #endif
3158:             continue;
3159: 
3160:         case '$':
3161:             if ((peekc = getchar()) != eof && peekc != '\n')
3162:                 goto defchar;
3163:             *ep++ = CDOL;
3164: #ifdef LOG
3165:             ++logstats.lp_dol;
3166: #endif
3167:             continue;
3168: 
3169:         case '[':
3170:             *ep++ = CCL;
3171:             *ep++ = 0;
3172:             cclcnt = 1;
3173:             if ((c = getchar()) == '^') {
3174:                 c = getchar();
3175:                 ep[-2] = NCCL;
3176: #ifdef LOG
3177:                 ++logstats.lp_nccl;
3178: #endif
3179:             }
3180: #ifdef LOG
3181:               else
3182:                 ++logstats.lp_ccl;
3183: #endif
3184:             do {
3185:                 if (c == '\\')
3186:                     c = getchar();
3187:                 if (c == '\n') {
3188:                     peekc = c;
3189:                     break;
3190:                 }
3191:                 if (c < 0) {
3192:                     c = 59;
3193:                     goto cerror;
3194:                 }
3195:                 *ep++ = c;
3196:                 cclcnt++;
3197:                 if (ep >= &expbuf[ESIZE - 2]) {
3198:                     c = 49;
3199:                     goto cerror;
3200:                 }
3201:             } while ((c = getchar()) != ']');
3202:             lastep[1] = cclcnt;
3203:             continue;
3204: 
3205:         case EOF:
3206:             c = 59;
3207:             goto cerror;
3208:         }
3209:     }
3210:     c = 42;
3211:    cerror:
3212:     expbuf[0] = '\0';
3213:     nbra = 0;
3214:     errmsg(c);
3215: }
3216: 
3217: compsub() {
3218:     register charac seof, c;
3219:     register char *p;
3220: 
3221:     if ((seof = getchar()) == '\n')
3222:         errmsg(40);
3223:     compile(seof);
3224:     p = rhsbuf;
3225:     for ever {
3226:         c = getchar();
3227:         if (c < 0)
3228:             errmsg(59);
3229:         if (c == '\\')
3230:             c = getchar() | 0200;
3231:         if (c == '\n') {
3232:             *p = 0;
3233:             peekc = 0;
3234:             if (prompt2)
3235:                 pflag++;
3236:             return(0);
3237:         }
3238:         if (c == seof)
3239:             break;
3240:         *p++ = c;
3241:         if (p >= &rhsbuf[LBSIZE / 2 - 2])
3242:             errmsg(41);
3243:     }
3244:     *p = '\0';
3245:     p = 0;
3246:     if ((peekc = getchar()) == 'g') {   /* if in 'glob' */
3247:         peekc = 0;
3248:         p = 1;
3249:     } else if ('0' <= peekc && peekc <= '9')
3250:         if ((s_cnt = getnum()) < 0)
3251:             s_cnt = 0;
3252:     newline();
3253:     return(p);
3254: }
3255: 
3256: create(as, am)
3257: char *as;
3258: {
3259:     register savmask;
3260:     register func savint, savqit;
3261:     register ret;
3262: 
3263:     if (am == LMODE) {
3264:         savint = signal(SIGINT, 1);
3265:         savqit = signal(SIGQIT, 1);
3266:         savmask = umask(LMASK);
3267:     }
3268:     ret = creat(as, am);
3269:     if (am == LMODE) {
3270:         umask(savmask);
3271:         signal(SIGINT, savint);
3272:         signal(SIGQIT, savqit);
3273:     }
3274:     return(ret);
3275: }
3276: 
3277: delete() {
3278:     register linep *a1, *a2, *a3;
3279: 
3280:     a1 = addr1;
3281:     a2 = addr2 + 1;
3282: #ifdef XDEL
3283:     if (!globp)
3284:         saveline();
3285: #endif
3286:     a3 = dol;
3287:     dol -= a2 - a1;
3288:     do {
3289:         *a1++ = *a2++;
3290:     } while (a2 <= a3);
3291:     a1 = addr1;
3292:     if (a1 > dol)
3293:         a1 = dol;
3294:     dot = a1;
3295: }
3296: 
3297: delexit(aretcode) {
3298: #ifdef LOG
3299: #include <sys/times.h>
3300:     struct tms t;
3301: #endif
3302: 
3303:     unlink(tfname);
3304: #ifdef LOG
3305:     if ((io = open(LOG, 1)) >= 0) {
3306:         time(&logstats.lt_end);
3307:         times(&t);
3308:         logstats.lt_usercpu = t.tms_utime;
3309:         logstats.lt_syscpu = t.tms_stime;
3310:         logstats.lt_kidscpu = t.tms_cutime + t.tms_cstime;
3311:         lseek(io, 0L, 2);
3312:         write(io, &logstats, sizeof logstats);
3313:     }
3314: #endif
3315:     exit(aretcode);
3316: }
3317: 
3318: dosub() {
3319:     register char *lp, *sp, *rp;
3320:     register charac c;
3321: 
3322:     lp = linebuf;
3323:     sp = genbuf;
3324:     rp = rhsbuf;
3325:     while (lp < loc1)
3326:         *sp++ = *lp++;
3327:     while (c = *rp++) {
3328: #ifdef DUMB
3329:         if (!dumbf)
3330: #endif
3331:             if (c == '&') {
3332: #ifdef LOG
3333:                 ++logamp;
3334: #endif
3335:                 sp = place(sp, loc1, loc2);
3336:                 continue;
3337:             } else if (c < 0 && (c &= 0177) >= '1' &&
3338:                 c < nbra + '1') {
3339:                 c -= '1';
3340:                 sp = place(sp,braslist[c],braelist[c]);
3341:                 continue;
3342:             }
3343:         *sp++ = c & 0177;
3344: #ifndef ALLOC
3345:         if (sp >= &genbuf[LBSIZE - 2])
3346: #else
3347:         if (sp >= &genbuf[lbsize - 2])
3348: #endif
3349:             errmsg(42);
3350:     }
3351:     lp = loc2;
3352:     loc2 = sp + (linebuf - genbuf);
3353:     while (*sp++ = *lp++)
3354: #ifndef ALLOC
3355:         if (sp >= &genbuf[LBSIZE - 2])
3356: #else
3357:         if (sp >= &genbuf[lbsize - 2])
3358: #endif
3359:             errmsg(43);
3360:     lp = linebuf;
3361:     sp = genbuf;
3362:     while (*lp++ = *sp++);
3363: }
3364: 
3365: #ifdef DEBUG
3366: dump() {
3367:     register linep *i;
3368:     register b, o;
3369: 
3370:     setdot();
3371:     nonzero();
3372:     newline();
3373:     line_num = addr1 - zero;
3374:     for (i = addr1; i <= addr2; i++) {
3375: #ifdef HUGE
3376:         b = (*i >> (8 - hugef)) & _3[hugef];
3377:         o = (*i << (1 + hugef)) & _4[hugef];
3378: #else
3379:         b = (*i >> 8) & _3;
3380:         o = (*i << 1) & _4;
3381: #endif
3382:         printlno(line_num++);
3383: #ifdef pdp11
3384:         printf("%6o:%7o%6d/%d\n", i, *i, b, o);
3385: #else
3386:         printf("%6o:%7o%6d/%d\n", i, *i&(unsigned)(unsigned short)-1, b, o);
3387: #endif
3388:     }
3389:     dot = addr2;
3390: }
3391: #endif
3392: 
3393: echo(ch)
3394: charac ch;
3395: {
3396: #ifdef AGAIN
3397:     static charac lastchar;
3398: #endif
3399: #ifdef USE
3400:     if (eflg || alt && !eflg2)
3401: #endif
3402: #ifndef USE
3403:     if (eflg)
3404: #endif
3405:         write(2, &ch, 1);
3406: #ifdef AGAIN
3407:     if (!agf && agp) {  /* save current command for "again" */
3408:         if (agp >= &agbuf[GBSIZE - 2])
3409:             agp = agbuf[0] = 0;
3410:         else
3411:             *agp++ = ch;
3412:         if (ch == '\n' && lastchar != '\\')
3413:             agp = *agp = 0;
3414:     }
3415:     lastchar = ch;
3416: #endif
3417:     return(ch);
3418: }
3419: 
3420: errfunc() {
3421:     if (io) {
3422:         close(io);
3423:         io = 0;
3424:         io_w = 0;
3425:     }
3426:     if (overfile) {
3427:         chmod(overfile, overmode);
3428:         overfile = 0;
3429:     }
3430: #ifdef HELP
3431:     if (doc) {
3432:         close(doc);
3433:         doc = 0;
3434:     }
3435: #endif
3436: #ifdef PIPE
3437:     if (pfile) {
3438:         close(pfile);
3439:         unlink(pfname);
3440:         pfile = 0;
3441:     }
3442: #endif
3443: /*	puts("?");	*/
3444:     if (!seekf)
3445:         lseek(0, 0L, 2);
3446:     pflag = 0;
3447:     listf = 0;
3448: #ifdef PARENS
3449:     parenf = 0;
3450: #endif
3451: #ifdef STRLEN
3452:     quotef = 0;
3453: #endif
3454:     if (globp) {
3455:         lastc = '\n';
3456:         globp = 0;
3457:     }
3458:     peekc = lastc;
3459:     skip_rest();
3460:     eflg2 = 0;
3461:     reset();
3462: }
3463: 
3464: errmsg(n) {
3465:     extern errno;
3466: 
3467:     listf = 0;
3468: #ifdef PARENS
3469:     parenf = 0;
3470: #endif
3471: #ifdef STRLEN
3472:     quotef = 0;
3473: #endif
3474:     col = 0;
3475:     if (n < 0) {
3476:         puts2("\7******** ");
3477:         printf("%d ", errno);
3478:         n = -n;
3479:     }
3480:     if (curt)
3481:         printf("?%d\n", n);
3482:     else
3483:         if (0 <= n && n < NERR)
3484:             putsn(errtext[n]);
3485:         else
3486:             printf("bad error number: %d\n", n);
3487:     error();
3488: }
3489: 
3490: execute(gf, addr)
3491: linep *addr;
3492: {
3493:     register char *p1, *p2;
3494:     register charac c;
3495: 
3496:     if (gf) {
3497:         if (circfl)
3498:             return(0);
3499:         p1 = linebuf;
3500:         p2 = genbuf;
3501:         while (*p1++ = *p2++);
3502:         locs = p1 = loc2;
3503:     } else {
3504:         if (addr == zero)
3505:             return(0);
3506:         p1 = getline(*addr);
3507:         locs = 0;
3508:     }
3509:     p2 = expbuf;
3510:     c = NBRA;
3511:     while (--c >= 0) {
3512:         braslist[c] = 0;
3513:         braelist[c] = 0;
3514:     }
3515:     if (circfl) {
3516:         loc1 = p1;
3517:         return(advance(p1, p2));
3518:     }
3519:     /* fast check for first character */
3520:     if (*p2 == CCHR) {
3521:         c = p2[1];
3522:         do {
3523:             if (*p1 != c)
3524:                 continue;
3525:             if (advance(p1, p2)) {
3526:                 loc1 = p1;
3527:                 return(1);
3528:             }
3529:         } while (*p1++);
3530:         return(0);
3531:     }
3532:     /* regular algorithm */
3533:     do {
3534:         if (advance(p1, p2)) {
3535:             loc1 = p1;
3536:             return(1);
3537:         }
3538:     } while (*p1++);
3539:     return(0);
3540: }
3541: 
3542: #ifdef TABS
3543: exp() {
3544:     register n;
3545:     register linep p, *a1;
3546: 
3547:     setdot();
3548:     nonzero();
3549:     n = 0;
3550:     for (a1 = addr1; a1 <= addr2; a1++) {
3551:         getline(*a1);
3552:         if (expand()) {
3553:             n++;
3554:             p = *a1;
3555:             *a1 = putline();
3556:             savemark(p, *a1);
3557:         }
3558:     }
3559:     dot = addr2;
3560:     return(n);
3561: }
3562: 
3563: expand() {
3564:     register char *p2;
3565:     register charac c;
3566:     register n;
3567:     register char *p1;
3568:     register cnt, i;
3569:     register flag tabflg;
3570: 
3571:     p1 = linebuf;
3572:     p2 = genbuf;
3573:     while (*p2++ = *p1++);
3574:     p2 = linebuf;
3575:     p1 = genbuf;
3576:     cnt = col = n = 0;
3577:     while (c = *p1++) {
3578:         if (c == tabc && col < maxtab) {
3579:             n = col;
3580:             c = tabfill;
3581:             if (c == '\t') {
3582:                 n = col;
3583:                 tabflg = 0;
3584:                 while (n < maxtab) {
3585:                     if ((++n & 07) == 0) {
3586:                         *p2++ = c;
3587:                         tabflg++;
3588:                         if (p2 >=
3589: #ifndef ALLOC
3590:                             &linebuf[LBSIZE - 2]
3591: #else
3592:                             &linebuf[lbsize - 2]
3593: #endif
3594:                             || n >= TABS * BPW)
3595:                             goto experr;
3596:                     }
3597:                     if (tabs[n >> BPWC] >> (n & BPWM) & 01)
3598:                         if (*p1 == tabc &&
3599:                             n < maxtab) {
3600:                             p1++;
3601:                             cnt++;
3602:                         } else
3603:                             break;
3604:                 }
3605:                 i = n;
3606:                 if (tabflg)
3607:                     n &= 07;
3608:                 else
3609:                     n -= col;
3610:                 col = i;
3611:                 while (n--) {
3612:                     *p2++ = ' ';
3613: #ifndef ALLOC
3614:                     if (p2 >= &linebuf[LBSIZE - 2])
3615: #else
3616:                     if (p2 >= &linebuf[lbsize - 2])
3617: #endif
3618:                         goto experr;
3619:                 }
3620:                 cnt++;
3621:                 continue;
3622:             }
3623:             do {
3624:                 *p2++ = c;
3625: #ifndef ALLOC
3626:                 if (p2 >= &linebuf[LBSIZE - 2]
3627: #else
3628:                 if (p2 >= &linebuf[lbsize - 2]
3629: #endif
3630:                     || n >= TABS * BPW)
3631:                     goto experr;
3632:                 n++;
3633:             } while (!(tabs[n >> BPWC] >> (n & BPWM) & 01));
3634:             col = n;
3635:             cnt++;
3636:             continue;
3637:         } else if ('\0' < c && c < ' ') {
3638:             switch (c) {
3639:             case '\b':
3640:                 col -= 2;
3641:                 break;
3642:             case '\t':
3643:                 col += 7 - (col & 07);
3644:                 break;
3645:             case '\r':
3646:                 col = -1;
3647:                 break;
3648:             default:
3649:                 col--;
3650:             }
3651:         }
3652:         if (c) {
3653:             *p2++ = c;
3654:             col++;
3655: #ifndef ALLOC
3656:             if (p2 >= &linebuf[LBSIZE - 2] ||
3657: #else
3658:             if (p2 >= &linebuf[lbsize - 2] ||
3659: #endif
3660:                 col >= TABS * BPW)
3661:     experr:         errmsg(12);
3662:         }
3663:     }
3664:     *p2++ = 0;
3665:     return(cnt);
3666: }
3667: #endif
3668: 
3669: #ifdef DEBUG
3670: #ifdef EXPDMP
3671: expdmp() {
3672:     register n;
3673:     register char *ep, **p;
3674:     register flag star;
3675: 
3676:     signal(SIGQIT, expdmp);
3677:     ep = expbuf;
3678:     putchar('"');
3679:     if (circfl)
3680:         putchar('^');
3681:     while (*ep) {
3682:         n = 0;
3683:         star = 0;
3684:         switch (*ep++) {
3685:         case CCHR | STAR:
3686:             star++;
3687:         case CCHR:
3688:             putchar(*ep++);
3689:             break;
3690:         case CDOT | STAR:
3691:             star++;
3692:         case CDOT:
3693:             putchar('.');
3694:             break;
3695:         case CDOL:
3696:             putchar('$');
3697:             break;
3698:         case CEOF:
3699:             putchar('"');
3700:             goto done;
3701:         case NCCL | STAR:
3702:             star++;
3703:         case NCCL:
3704:             n++;
3705:             goto ccl;
3706:         case CCL | STAR:
3707:             star++;
3708:         case CCL: ccl:
3709:             putchar('[');
3710:             if (n)
3711:                 putchar('^');
3712:             n = *ep++;
3713:             while (--n)
3714:                 putchar(*ep++);
3715:             putchar(']');
3716:             break;
3717:         case CBRA:
3718:             putchar('\\');
3719:             putchar('(');
3720:             ep++;
3721:             break;
3722:         case CKET:
3723:             putchar('\\');
3724:             putchar(')');
3725:             ep++;
3726:             break;
3727:         case CBACK | STAR:
3728:             star++;
3729:         case CBACK:
3730:             putchar('\\');
3731:             putchar(*ep++ + '1');
3732:             break;
3733:         default:
3734:             putchar('?');
3735:             break;
3736:         }
3737:         if (star)
3738:             putchar('*');
3739:     }
3740: done:   putchar('\n');
3741:     if (reading)
3742:         reset();
3743: }
3744: #endif
3745: #endif
3746: 
3747: filename() {
3748:     register char *p1, *p2;
3749:     register charac c;
3750: 
3751:     appflg = 0;
3752:     c = getchar();
3753:     if (c < 0)
3754:         errmsg(59);
3755:     if (c == '\n') {
3756:     noname:
3757:         if (savedfile[0] == 0)
3758:             errmsg(62);
3759:         scopy(savedfile, file);
3760:         return;
3761:     }
3762:     if (c != ' ' && c != '\t' && c != ',' && c != '>')
3763:         errmsg(5);
3764:     if (c != ',')
3765:         peekc = c;
3766:     white_space();
3767:     if ((c = getchar()) == '>') {
3768:         while ((c = getchar()) == '>');
3769:         appflg++;
3770:         if (c == '\n')
3771:             goto noname;
3772:         peekc = c;
3773:         white_space();
3774:         c = getchar();
3775:     }
3776:     if (c == '\n')
3777:         errmsg(7);
3778:     p1 = file;
3779:     do {
3780:         *p1++ = c;
3781:         if (p1 >= &file[FNSIZE - 2])
3782:             errmsg(11);
3783:     } while ((c = getchar()) != '\n');
3784:     *p1++ = 0;
3785:     if (savedfile[0] == 0)
3786:         scopy(file, savedfile);
3787: }
3788: 
3789: linep *
3790: findmark(alp, adflt)
3791: linep alp, *adflt;
3792: {
3793:     register linep *a, v;
3794: #ifdef HUGE
3795:     register i;
3796: 
3797:     i = hugef ^ 01;
3798: #endif
3799:     v = alp;
3800:     for (a = zero + 1; a <= dol; a++)
3801:         if (v == (*a |
3802: #ifdef HUGE
3803:                 i
3804: #else
3805:                 1
3806: #endif
3807:                 ))
3808:             return(a);
3809:     return(adflt);
3810: }
3811: 
3812: flush_buf() {
3813:     register n;
3814: 
3815:     if (n = linp - line) {
3816:         linp = line;
3817:         write(fout, line, n);
3818:     }
3819: }
3820: 
3821: #ifdef G_VFY
3822: gask(a1)
3823: linep *a1;
3824: {
3825:     register charac c;
3826: 
3827:     col = 0;
3828:     printlno(line_num = a1 - zero);
3829:     puts(linebuf);
3830:     puts2("Ok? ");
3831:     flush_buf();
3832:     if ((c = getchar()) < 0) {
3833:         putchar('\n');
3834:         return(-1);
3835:     }
3836:     if (c == '\n')
3837:         return(1);
3838:     skip_rest();
3839:     return(c != 'n');
3840: }
3841: #endif
3842: 
3843: char *
3844: getblock(atl, iof) {
3845:     extern read(), write();
3846:     register bno, off;
3847:     register linep *a;
3848: #ifdef HUGE
3849:     register flag c;
3850:     register func savint;
3851: 
3852:     bno = (atl >> (8 - hugef)) & _3[hugef];
3853:     off = (atl << (1 + hugef)) & _4[hugef];
3854: #else
3855:     bno = (atl >> 8) & _3;
3856:     off = (atl << 1) & _4;
3857: #endif
3858:     if (bno >=
3859: #ifdef HUGE
3860:            _5[hugef]
3861: #else
3862:            _5
3863: #endif
3864:                 ) {
3865: #ifdef HUGE
3866:         if (!hugef && !globp) { /* let's try converting to huge */
3867:             if (!curt) {
3868:                 putsn("File too large for normal editing.");
3869:                 puts2("Conversion to \"huge\" mode disallows ");
3870:                 puts2("use of the global command.");
3871:             }
3872:             c = yes_no(curt? "?huge" : "Do you wish to convert",
3873:                 1, 0, 0);
3874:             if (c) {
3875:                 savint = signal(SIGINT, 1);
3876:                 for (a = zero + 1; a <= dol; a++)
3877:                     *a = ((unsigned)*a) >> 1;
3878:                 hugef++;
3879:                 hugef2++;   /* conversion occurred */
3880:                 atl = (atl >> 1) & _6[hugef];
3881: #ifdef XDEL
3882:                 ndeleted = 0;   /* useless pointers */
3883:                 deleted = 0;
3884: #endif
3885:                 signal(SIGINT, savint);
3886:                 goto huger;
3887:             }
3888:         }
3889: #endif
3890:         errmsg(34);
3891:     }
3892: #ifdef HUGE
3893:     huger:
3894: #endif
3895:     nleft = BLKSIZE - off;
3896:     if (bno == iblock && !badf) {
3897:         ichanged |= iof;
3898:         return(ibuff + off);
3899:     }
3900:     if (bno == oblock)
3901:         return(obuff + off);
3902:     if (iof == READ) {
3903:         if (ichanged) {
3904:             blkio(iblock, ibuff, write);
3905:             ichanged = 0;
3906:         }
3907:         iblock = bno;
3908:         blkio(bno, ibuff, read);
3909:         return(ibuff + off);
3910:     }
3911:     if (oblock >= 0)
3912:         blkio(oblock, obuff, write);
3913:     oblock = bno;
3914:     return(obuff + off);
3915: }
3916: 
3917: charac
3918: getchar() {
3919:     flush_buf();
3920:     eof = 0;
3921:     if (lastc = peekc) {
3922:         peekc = 0;
3923:         return(lastc);
3924:     }
3925:     if (globp) {
3926:         if (lastc = *globp++) {
3927:             if (globf2 && *globp == 0)
3928:                 globp = globf2 = 0;
3929:             return(lastc);
3930:         }
3931:         globp = 0;
3932:         return(EOF);
3933:     }
3934: #ifdef AGAIN
3935:     if (agf
3936: #ifdef USE
3937:         && !alt
3938: #endif
3939:             ) { /* "again" stuff */
3940:         if (lastc = *agp++)
3941:             return(lastc);
3942:         agf = agp = 0;
3943:     }
3944: #endif
3945:     reading++;
3946: #ifdef USE
3947:     if (read(alt, &lastc, 1) <= 0) {
3948: #endif
3949: #ifndef USE
3950:     if (read(0, &lastc, 1) <= 0) {
3951: #endif
3952:         reading = 0;
3953:         eof++;
3954:         return(lastc = EOF);
3955:     }
3956:     reading = 0;
3957:     lastc &= 0177;
3958: #ifdef APLMAP
3959:     if (aplmap && lastc > ' ')
3960:         lastc = map_ascii[lastc - (' ' + 1)];
3961: #endif
3962: #ifdef EOL
3963:     if (lastc == '\n')
3964:         prompt3 = 1;
3965:     else if (eol && lastc == eol) {
3966:         lastc = '\n';
3967:         prompt3 = 0;
3968:     }
3969: #endif
3970: #ifdef CMDS
3971:     if (cmd)
3972:         write(cmd, &lastc, 1);
3973: #endif
3974:     eof = 0;
3975:     return(echo(lastc));
3976: }
3977: 
3978: getcopy() {
3979:     if (addr1 > addr2)
3980:         return(EOF);
3981:     getline(*addr1++);
3982:     return(0);
3983: }
3984: 
3985: getfile() {
3986:     register charac c;
3987:     register char *lp, *fp;
3988: 
3989:     lp = linebuf;
3990:     fp = nextip;
3991:     do {
3992:         if (--ninbuf < 0) {
3993: #ifndef ALLOC
3994:             if ((ninbuf = read(io, genbuf, LBSIZE) - 1) < 0)
3995: #else
3996:             if ((ninbuf = read(io, genbuf, lbsize) - 1) < 0)
3997: #endif
3998:                 if (lp == linebuf)
3999:                     return(EOF);
4000:                 else {
4001:                     lp++;
4002:                     break;
4003:                 }
4004:             fp = genbuf;
4005:         }
4006: #ifndef ALLOC
4007:         if (lp >= &linebuf[LBSIZE - 2] && (*fp & 0177) != '\n') {
4008: #else
4009:         if (lp >= &linebuf[lbsize - 2] && (*fp & 0177) != '\n') {
4010: #endif
4011:             printf((curt? "?long%u\n" : "line %u in file too long\n"),
4012:                 dot - zero + 1);
4013:             flush_buf();
4014:             lp++;
4015:             ninbuf++;
4016:             break;
4017:         }
4018:         if ((*lp++ = c = *fp++ & 0177) == 0) {
4019:             lp--;
4020:             continue;
4021:         }
4022:     } while (c != '\n');
4023:     *--lp = 0;
4024:     nextip = fp;
4025:     return(0);
4026: }
4027: 
4028: getline(tl) {
4029:     register char *bp, *lp;
4030:     register nl;
4031: 
4032: #ifdef DEBUG
4033:     if (tflg)
4034:         printf("getline:\t%o\n", tl);
4035: #endif
4036:     lp = linebuf;
4037:     bp = getblock(tl, READ);
4038: #ifdef HUGE
4039:     if (hugef2) {
4040:         hugef2 = 0;
4041:         tl = (tl >> 1) & _6[hugef];
4042:     }
4043:     tl &= _1[hugef];
4044: #else
4045:     tl &= _1;
4046: #endif
4047:     nl = nleft;
4048:     while (*lp++ = *bp++)
4049:         if (--nl <= 0) {
4050: #ifdef HUGE
4051:             bp = getblock(tl += _2[hugef], READ);
4052: #else
4053:             bp = getblock(tl += _2, READ);
4054: #endif
4055:             nl = nleft;
4056:         }
4057:     return(linebuf);
4058: }
4059: 
4060: getnum() {
4061:     register n;
4062:     register charac c;
4063: 
4064:     n = 0;
4065:     while ('0' <= (c = getchar()) && c <= '9')
4066:         n = n * 10 + c - '0';
4067:     peekc = c;
4068:     return(n);
4069: }
4070: 
4071: getsnum() {
4072:     register sign;
4073: 
4074:     if (sign = (peekc = getchar()) == '-')
4075:         peekc = 0;
4076:     return(sign? -getnum() : getnum());
4077: }
4078: 
4079: getsub() {
4080:     register char *p1, *p2;
4081: 
4082:     p1 = linebuf;
4083:     if ((p2 = linebp) == 0)
4084:         return(EOF);
4085:     while (*p1++ = *p2++);
4086:     linebp = 0;
4087:     return(0);
4088: }
4089: 
4090: gettty(single) {
4091:     register charac c;
4092:     register char *p, *gf;
4093: #ifdef TABS
4094:     int tabf;
4095: 
4096:     tabf = 0;
4097: #endif
4098:     p = linebuf;
4099:     gf = globp;
4100: #ifdef EOL
4101:     if (prompt2 && prompt3 && !single) {
4102: #endif
4103: #ifndef EOL
4104:     if (prompt2 && !single) {
4105: #endif
4106:         printlno(line_num);
4107:         flush_buf();
4108:     }
4109:     line_num++;
4110:     while ((c = getchar()) != '\n') {
4111:         if (c < 0) {
4112:             if (gf)
4113:                 peekc = c;
4114:             else if (prompt2 && (prompt1 || !zflg))
4115:                 putchar('\n');
4116:             if (p > linebuf)
4117:                 break;
4118:             return(c);
4119:         }
4120:         if ((c &= 0177) == 0)
4121:             continue;
4122: #ifdef TABS
4123:         if (tabc && c == tabc)
4124:             tabf++;
4125: #endif
4126:         *p++ = c;
4127: #ifndef ALLOC
4128:         if (p >= &linebuf[LBSIZE - 2])
4129: #else
4130:         if (p >= &linebuf[lbsize - 2])
4131: #endif
4132:             errmsg(30);
4133:     }
4134:     *p++ = 0;
4135: #ifdef TABS
4136:     if (tabf)
4137:         expand();
4138: #endif
4139:     if (!single && linebuf[0] == '.' && linebuf[1] == 0)
4140:         return(EOF);
4141:     return(0);
4142: }
4143: 
4144: global(k) {
4145:     register char *gp;
4146:     register charac c;
4147:     register linep *a1;
4148:     register flag globpf;
4149:     char globuf[GBSIZE];
4150: 
4151: #ifdef HUGE
4152:     if (hugef)
4153:         errmsg(10);
4154: #endif
4155:     if (globp)
4156:         errmsg(37);
4157:     setall();
4158:     nonzero();
4159:     if ((c = getchar()) == '\n')
4160:         peekc = c;
4161:     compile(c);
4162: #ifdef G_VFY
4163:     gaskf = 0;
4164:     if ((peekc = getchar()) == 'v') {
4165:         gaskf++;
4166:         peekc = 0;
4167:     }
4168: #endif
4169:     globpf = pflag;
4170:     if (peekc == '\n')
4171:         globpf = 0;
4172:     pflag = 0;
4173:     gp = globuf;
4174:     if ((peekc = getchar()) < 0)
4175:         errmsg(59);
4176:     if (peekc == '\n') {
4177:         *gp++ = 'p';
4178:         peekc = 0;
4179:     } else
4180:         while ((c = getchar()) != '\n') {
4181:             if (c == '\\') {
4182:                 c = getchar();
4183:                 if (c != '\n')
4184:                     *gp++ = '\\';
4185:             }
4186:             if (c < 0)
4187:                 errmsg(59);
4188:             *gp++ = c;
4189:             if (gp >= &globuf[GBSIZE - 2])
4190:                 errmsg(38);
4191:         }
4192:     *gp++ = '\n';
4193:     *gp = 0;
4194:     c = 0;
4195: #ifdef LOG
4196: #ifdef G_VFY
4197:     if (gaskf)
4198:         ++logstats.lc_gvfy;
4199: #endif
4200:     if (k)
4201:         ++logstats.lc_global;
4202:     else
4203:         ++logstats.lc_vglobal;
4204: #endif
4205:     for (a1 = zero + 1; a1 <= dol; a1++) {
4206:         *a1 &= ~01;
4207:         s_tmp = 0;
4208:         if (a1 >= addr1 && a1 <= addr2 && execute(0, a1) == k)
4209: #ifdef G_VFY
4210:             if (!gaskf || (c = gask(a1)))
4211:                 if (c < 0)
4212:                     addr2 = a1;
4213:                 else
4214: #endif
4215:                     *a1 |= 01;
4216:     }
4217:     for (a1 = zero + 1; a1 <= dol; a1++)
4218:         if (*a1 & 01) {
4219:             *a1 &= ~01;
4220:             dot = a1;
4221:             globp = globuf;
4222:             pflag = globpf;
4223:             commands(1);
4224:             a1 = zero;
4225:         }
4226: }
4227: 
4228: hangup() {
4229:     signal(SIGHUP, 1);
4230:     if (reading) {
4231:         backup(HUP);
4232:         if (fout != 1) {
4233:             flush_buf();
4234:             fout = 1;
4235:         }
4236:         puts2(errtext[57]);
4237:         delexit(1);
4238:     }
4239:     hupflag++;
4240: }
4241: 
4242: header() {
4243:     register colnum, number;
4244:     register flag lf;
4245: 
4246:     number = 0;
4247:     if ((peekc = getchar()) != '\n') {
4248:         white_space();
4249:         number = getnum();
4250:     }
4251:     if (!number)
4252:         number = ccount - (prompt1? 8 : 0);
4253:     newline();
4254:     if (zero != dol)
4255:         dot = addr2;
4256:     lf = listf;
4257:     listf = 0;
4258:     if (prompt1)
4259:         putchar('\t');
4260:     for (colnum = 0; colnum < number / 10; colnum++)
4261:         printf("%10d", colnum + 1);
4262:     putchar('\n');
4263:     if (prompt1)
4264:         putchar('\t');
4265:     for (colnum = 1; colnum <= number; colnum++)
4266: #ifdef TABS
4267:         if (colnum < (TABS << BPWC) &&
4268:             (tabs[(colnum - 1) >> BPWC] >>
4269:             ((colnum - 1) & BPWM) & 01))
4270:             putchar('-');
4271:         else
4272: #endif
4273:             putchar(colnum % 10 + '0');
4274:     putchar('\n');
4275:     listf = lf;
4276: }
4277: 
4278: init() {
4279:     register n;
4280:     register char *p;
4281: 
4282:     if (tfile > 0)
4283:         close(tfile);
4284:     if (io) {
4285:         close(io);
4286:         io = 0;
4287:         io_w = 0;
4288:     }
4289: #ifdef HELP
4290:     if (doc) {
4291:         close(doc);
4292:         doc = 0;
4293:     }
4294: #endif
4295: #ifdef USE
4296:     if (alt) {
4297:         close(alt);
4298:         alt = 0;
4299:         eflg2 = 0;
4300:     }
4301: #endif
4302: #ifdef PIPE
4303:     if (pfile) {
4304:         close(pfile);
4305:         unlink(pfname);
4306:         pfile = 0;
4307:     }
4308: #endif
4309:     tline = 0;
4310: #ifdef XDEL
4311:     deleted = 0;
4312:     ndeleted = 0;
4313: #endif
4314:     num_reads = 0;
4315:     text_modified = 0;
4316: #ifdef YINT
4317:     yplus = 0;
4318: #endif
4319: #ifdef UNDO
4320:     undo_oldp = 0;
4321:     undo_newp = 0;
4322: #endif
4323: #ifdef V7
4324:     if (overfile) {
4325:         chmod(overfile, overmode);
4326:         overfile = 0;
4327:     }
4328: #endif
4329:     iblock = oblock = -1;
4330:     badf = 0;
4331:     ichanged = 0;
4332:     if ((n = create(tfname, LMODE)) < 0) {
4333:         putsn(errtext[50]);
4334:         exit(1);
4335:     }
4336:     close(n);
4337:     if ((tfile = open(tfname, 2)) < 0) {
4338:         putsn(errtext[36]);
4339:         exit(1);
4340:     }
4341:     addr1 = addr2 = dot = dotdot = lastdot = zero = dol = fendcore;
4342:     endcore = fendcore - 2;
4343:     brk(fendcore);
4344:     n = 26;
4345:     while (--n >= 0) {  /* kill marks */
4346:         names[n] = 0;
4347: #ifdef EXTMARK
4348:         names2[n] = 0;
4349: #endif
4350:     }
4351:     p = globp;
4352:     globp = 0;
4353:     if (chk()) {
4354:         if ((io = open(file, 0)) < 0) {
4355:             io = 0;
4356:             lastc = '\n';
4357:             if (curt)
4358:                 putsn("?53");
4359:             else {
4360:                 puts2(errtext[53]);
4361:                 putsn(file);
4362:             }
4363:             flush_buf();
4364:         } else {
4365:             n = append(getfile, addr1, 0, 0);
4366:             if (prompt2)
4367:                 printf((curt? prcntu : errtext[55]),
4368:                     n, (n == 1? null : quote_s));
4369:             if (n) {
4370:                 num_reads++;
4371:                 text_modified++;
4372:             }
4373:             if (io) {
4374:                 close(io);
4375:                 io = 0;
4376:                 io_w = 0;
4377:             }
4378:         }
4379:         return(1);
4380:     }
4381:     globp = p;
4382:     return(0);
4383: }
4384: 
4385: istty(fd) {
4386:     register r;
4387:     short buf[3];   /* naughty int's */
4388: 
4389:     buf[2] = BS1;
4390:     r = 0;
4391:     if (gtty(fd, buf) >= 0)
4392:         ++r;
4393: #ifdef CLEAR
4394:     zflg = (buf[2] & BS1) == 0;
4395: #endif
4396:     if (pipef
4397: #ifdef V7
4398:           || getenv("_NO_STDIO_BUF")
4399: #endif
4400:                         )
4401:         ++r;
4402:     return(r);
4403: }
4404: 
4405: #ifdef XED
4406: join() {
4407:     register linep *a1;
4408:     register char *p1, *p2;
4409:     register charac c, ceof;
4410: 
4411:     setdot();
4412:     nonzero();
4413:     if (addr1 == addr2)
4414:         --addr1;
4415:     if (addr1 <= zero)
4416:         errmsg(60);
4417: 
4418:     p2 = rhsbuf;
4419:     if ((c = peekc = getchar()) < 0)
4420:         errmsg(59);
4421:     ceof = 0;
4422:     if (peekc != '\n' && peekc != 'p' && peekc != 'l'
4423: #ifdef PARENS
4424:         && peekc != 'b'
4425: #endif
4426: #ifdef STRLEN
4427:                 && peekc != 'q'
4428: #endif
4429:                        ) {
4430:         ceof = peekc;
4431:         peekc = 0;
4432:         while ((c = getchar()) != ceof && c != '\n') {
4433:             if (c < 0)
4434:                 errmsg(59);
4435:             if (c == '\\')
4436:                 if ((c = getchar()) == '\n')
4437:                     errmsg(46);
4438:             *p2++ = c;
4439:             if (p2 >= &rhsbuf[LBSIZE / 2 - 2])
4440:                 errmsg(42);
4441:         }
4442:         if (c != '\n')
4443:             c = '\0';
4444:         else
4445:             if (prompt2)
4446:                 pflag++;
4447:         if (p2 != rhsbuf)
4448:             *p2 = '\0';
4449:         if (*rhsbuf == 0)
4450:             errmsg(27);
4451: #ifdef LOG
4452:         ++logstats.lc_jglue;
4453: #endif
4454:     }
4455: #ifdef LOG
4456:       else
4457:         ++logstats.lc_join;
4458: #endif
4459:     peekc = c;
4460:     newline();
4461: 
4462:     p1 = rhsbuf;
4463:     while (*p1)
4464:         if (*p1++ == '\n')
4465:             errmsg(46);
4466: 
4467:     p2 = genbuf;
4468:     a1 = addr1;
4469: 
4470:     while (a1 <= addr2) {
4471:         p1 = getline(*a1++);
4472:         while (*p2++ = *p1++)
4473: #ifndef ALLOC
4474:             if (p2 >= &genbuf[LBSIZE - 2])
4475: #else
4476:             if (p2 >= &genbuf[lbsize - 2])
4477: #endif
4478:                 errmsg(12);
4479:         --p2;
4480:         if (ceof && a1 <= addr2) {
4481:             p1 = rhsbuf;
4482:             while (*p2++ = *p1++)
4483: #ifndef ALLOC
4484:                 if (p2 >= &genbuf[LBSIZE - 2])
4485: #else
4486:                 if (p2 >= &genbuf[lbsize - 2])
4487: #endif
4488:                     errmsg(12);
4489:             --p2;
4490:         }
4491:     }
4492:     *p2 = '\0';
4493: 
4494:     p1 = genbuf;
4495:     p2 = linebuf;
4496:     while (*p2++ = *p1++);
4497: 
4498:     a1 = putline();
4499:     savemark(*addr1, a1);
4500:     *addr1++ = a1;
4501:     delete();
4502:     dot = --addr1;
4503:     if (dot > dol)
4504:         dot = dol;
4505: }
4506: #endif
4507: 
4508: #ifdef TABS
4509: listabs() {
4510:     register n;
4511: 
4512:     if (maxtab < 0)
4513:         errmsg(9);
4514:     n = next_tab(-1);
4515:     printf("tabs: %d", n + 1);
4516:     while ((n = next_tab(n)) >= 0)
4517:         printf(",%d", n + 1);
4518:     putchar('\n');
4519: }
4520: #endif
4521: 
4522: mail() {
4523:     delexit(1);
4524: }
4525: 
4526: move(cflag) {
4527:     extern getcopy();
4528:     register linep *adt, *ad1, *ad2;
4529: 
4530:     setdot();
4531:     nonzero();
4532:     if ((adt = address()) == 0)
4533:         errmsg(31);
4534:     ad1 = addr1;
4535:     ad2 = addr2;
4536:     newline();
4537:     if (cflag) {
4538:         ad1 = dol;
4539:         append(getcopy, ad1++, 0, 0);
4540:         ad2 = dol;
4541:     }
4542:     ad2++;
4543:     if (adt < ad1) {
4544:         dot = adt + (ad2 - ad1);
4545:         if (++adt == ad1)
4546:             return;
4547:         reverse(adt, ad1);
4548:         reverse(ad1, ad2);
4549:         reverse(adt, ad2);
4550:     } else if (adt >= ad2) {
4551:         dot = adt++;
4552:         reverse(ad1, ad2);
4553:         reverse(ad2, adt);
4554:         reverse(ad1, adt);
4555:     } else
4556:         errmsg(28);
4557: }
4558: 
4559: newline() {
4560:     register charac c;
4561: 
4562:     if ((c = getchar()) == '\n')
4563:         return;
4564:     if (c == 'p' || c == 'l'
4565: #ifdef PARENS
4566:                  || c == 'b'
4567: #endif
4568: #ifdef STRLEN
4569:                          || c == 'q'
4570: #endif
4571:                             ) {
4572:         pflag++;
4573:         if (c == 'l')
4574:             listf++;
4575: #ifdef PARENS
4576:         else if (c == 'b')
4577:             parenf++;
4578: #endif
4579: #ifdef STRLEN
4580:         else if (c == 'q')
4581:             quotef++;
4582: #endif
4583:         if (getchar() == '\n')
4584:             return;
4585:     }
4586:     errmsg(25);
4587: }
4588: 
4589: #ifdef TABS
4590: next_tab(acol) {
4591:     register n;
4592: 
4593:     if ((n = acol) < maxtab) {
4594:         do {
4595:             n++;
4596:         } while (!(tabs[n >> BPWC] >> (n & BPWM) & 01));
4597:         return(n);
4598:     }
4599:     return(-1);
4600: }
4601: #endif
4602: 
4603: nonzero() {
4604:     if (addr1 <= zero)
4605:         errmsg(23);
4606:     if (addr2 > dol)
4607:         errmsg(24);
4608: }
4609: 
4610: #ifdef PIPE
4611: oil_spilled() {
4612:     if (!iflg) {
4613:         signal(SIGINT, 1);
4614:         signal(SIGQIT, 1);
4615:     }
4616:     signal(SIGPIP, 1);
4617:     piperr++;
4618: }
4619: #endif
4620: 
4621: onintr() {
4622:     register char *p1, *p2;
4623: 
4624:     signal(SIGINT, onintr);
4625: #ifdef USE
4626:     if (alt) {
4627:         close(alt);
4628:         alt = 0;
4629:         eflg2 = 0;
4630:     }
4631: #endif
4632:     if (io) {
4633:         if (curt)
4634:             putsn("?intI/O");
4635:         else {
4636:             puts2("\7Interrupted I/O!!!\7\nWarning: \"");
4637:             puts2(file);
4638:             if (io_w) {
4639:                 putsn("\" is probably truncated.");
4640:                 puts2("You should probably re-write it.");
4641:             } else {
4642:                 putsn("\" was not read entirely.");
4643:                 puts2("If you write the buffer, ");
4644:                 puts2("part of the file may be lost.");
4645:             }
4646:         }
4647:         flush_buf();
4648:     }
4649: #ifdef EOL
4650:     prompt3 = 1;
4651: #endif
4652:     if (fout != 1) {
4653:         close(fout);
4654:         fout = 1;
4655:     }
4656: #ifdef YINT
4657:     if (!globp && reading && yflg) {
4658:         globp = ".:\n";
4659:         if (yplus) {
4660:             dot = findmark(yplus, 0);
4661:         } else
4662:             globp++;
4663:         peekc = 0;
4664:         putchar('\n');
4665:         commands(1);
4666:         reset();
4667:     }
4668: #endif
4669:     if (iflg) {
4670:         signal(SIGINT, 1);
4671:         backup(INT);
4672:         delexit(1);
4673:     }
4674:     putchar(lastc = '\n');
4675:     errmsg(29);
4676: }
4677: 
4678: override() {
4679:     struct stat s;
4680: 
4681:     if (access(file, 02) < 0) {
4682:         if (stat(file, &s) >= 0 && (s.st_mode & S_IFMT) == S_IFREG) {
4683:             overmode = s.st_mode & 07777;
4684:             if (chmod(file, overmode) < 0)
4685:                 return;
4686:             if (immflg == 0) {
4687:                 if (curt) {
4688:                     puts2("?\"");
4689:                     puts2(file);
4690:                     puts2("\"  ");
4691:                 } else {
4692:                     puts2("The file \"");
4693:                     puts2(file);
4694:                     puts2("\" is write-protected.");
4695:                 }
4696:                 if (yes_no(curt? "override" :
4697:                     "Do you wish to over-ride the permission",
4698:                     0, 1, 1))
4699:                     return;
4700:             }
4701:             overfile = file;
4702:             if (chmod(overfile, overmode | 0200) < 0)
4703:                 overfile = 0;
4704:             else {
4705:                 putsn("[over-riding]");
4706: #ifdef LOG
4707:                 ++logstats.lm_overwrite;
4708: #endif
4709:             }
4710:         }
4711:     }
4712: }
4713: 
4714: #ifdef PAGE
4715: page() {
4716:     register cl, n;
4717:     register char *p, *pp;
4718:     register linep *a, *b;
4719:     register l;
4720: 
4721:     a = addr1;
4722:     if (addr2 != addr1)
4723:         b = addr2;
4724:     else
4725:         b = dol;
4726: #ifdef PARENS
4727:     parenc[0] = 0;
4728:     parenc[1] = 0;
4729:     parenc[2] = 0;
4730: #endif
4731:     for (n = pcount; n >= 0 && a <= b; n--) {
4732:         pp = p = getline(*a);
4733:         cl = prompt1? 8 : 0;
4734:         l = 0;
4735:         while (*p) {
4736:             if (*p < ' ' || *p > '~')
4737:                 switch (*p) {
4738:                 case '\b':
4739:                     if (listf)
4740:                         cl++;
4741:                     else {
4742:                         cl--;
4743:                         if (aflg
4744: #ifdef PARENS
4745:                              && !parenf
4746: #endif
4747: #ifdef STRLEN
4748:                              && !quotef
4749: #endif
4750:                                    )
4751:                             l++;
4752:                     }
4753:                     break;
4754:                 case '\t':
4755:                     if (listf)
4756:                         cl++;
4757:                     else
4758:                         cl += 8 - cl % 8;
4759:                     break;
4760:                 case '\r':
4761:                     if (listf)
4762:                         cl += 2;
4763:                     else
4764:                         cl = 0;
4765:                     break;
4766:                 case ctrl('L'): /* ADM-3A's */
4767:                     if (listf)
4768:                         cl++;
4769:                     cl++;
4770:                     break;
4771:                 default:
4772:                     if (listf || zflg)
4773:                         cl += 2;
4774:                 }
4775:             else
4776:                 cl++;
4777: #ifdef PARENS
4778:             if (parenf && paren(*p))
4779:                 l++;
4780: #endif
4781: #ifdef STRLEN
4782:             /* if (quotef && (*p == '"' || *p == '\'')) */
4783:             if (quotef && (quotec? *p == quotec :
4784:                 *p == '"' || *p == '\''))
4785:                 l++;
4786: #endif
4787:             if (cl < 0)
4788:                 cl = 0;
4789:             else if (cl > ccount) {
4790:                 cl = 0;
4791:                 if (--n < 0)
4792:                     goto done;
4793:             }
4794:             p++;
4795:         }
4796:         if (l)
4797:             if (--n < 0)
4798:                 goto done;
4799:         col = 0;
4800:         printlno(line_num = a - zero);
4801:         puts(pp);
4802:         a++;
4803:     }
4804:     done:
4805:     dot = a - 1;
4806: }
4807: #endif
4808: 
4809: #ifdef PARENS
4810: paren(ac) {
4811:     switch (ac) {
4812:     case '(':   return(1);
4813:     case '[':   return(2);
4814:     case '{':   return(3);
4815:     case ')':   return(-1);
4816:     case ']':   return(-2);
4817:     case '}':   return(-3);
4818:     }
4819:     return(0);
4820: }
4821: #endif
4822: 
4823: place(asp, al1, al2) {
4824:     register char *sp, *l1, *l2;
4825: 
4826:     sp = asp;
4827:     l1 = al1;
4828:     l2 = al2;
4829:     while (l1 < l2) {
4830:         *sp++ = *l1++;
4831: #ifndef ALLOC
4832:         if (sp >= &genbuf[LBSIZE - 2])
4833: #else
4834:         if (sp >= &genbuf[lbsize - 2])
4835: #endif
4836:             errmsg(42);
4837:     }
4838:     return(sp);
4839: }
4840: 
4841: /*VARARGS*/
4842: printf(as, aarglist)
4843: char *as;
4844: {
4845:     register *args, w;
4846:     register char *q;
4847:     register flag f;
4848: 
4849:     args = &aarglist;
4850:     while (*as) {
4851:         if (*as != '%') {
4852:             putchar(*as++);
4853:             continue;
4854:         }
4855:         if (*++as == '\0')
4856:             return;
4857:         w = 0;  /* no default width */
4858:         f = 0;  /* unsigned default */
4859:         while ('0' <= *as && *as <= '9')
4860:             w = w * 10 + *as++ - '0';
4861:         if (*as == '\0')
4862:             return;
4863:         switch (*as++) {
4864:         case 'c':   /* char */
4865:             putchar(*args++);
4866:             continue;
4867:         case 'd':   /* signed decimal */
4868:             f = 1;  /* signed */
4869:         case 'u':   /* unsigned decimal */
4870:             printfn(*args++, 10, f, w);
4871:             continue;
4872:         case 'o':   /* unsigned octal */
4873:             printfn(*args++, 8, 0, w);
4874:             continue;
4875:         case 's':   /* string */
4876:             q = *args++;
4877:             while (*q) {
4878:                 putchar(*q++);
4879:                 --w;
4880:             }
4881:             while (--w > 0)
4882:                 putchar(' ');
4883:             continue;
4884:         default:
4885:             putchar(as[-1]);
4886:             continue;
4887:         }
4888:     }
4889: }
4890: 
4891: printfn(an, ab, af, aw) {
4892:     register w;
4893:     register unsigned n;
4894:     register char *p;
4895:     char buf[(sizeof(int) != 2? 10 : 6) + 2];
4896: 
4897:     w = aw;
4898:     p = &buf[sizeof buf];
4899:     *--p = '\0';
4900:     n = an;
4901:     if (af)
4902:         if (an < 0)
4903:             n = -an;
4904:         else
4905:             af = 0;
4906:     do {
4907:         *--p = n % ab + '0';
4908:         --w;
4909:     } while (n /= ab);
4910:     if (af) {
4911:         *--p = '-';
4912:         --w;
4913:     }
4914:     while (--w >= 0)
4915:         putchar(' ');
4916:     while (*p)
4917:         putchar(*p++);
4918: }
4919: 
4920: printlno(an) {
4921:     register flag l;
4922: 
4923:     if (prompt1) {
4924:         l = listf;
4925:         listf = 0;
4926:         printf(fmtlno, an - aflg);
4927:         col = 8;
4928:         listf = l;
4929:     }
4930: }
4931: 
4932: printmarks() {
4933:     register linep *a1;
4934:     register charac c;
4935:     register n, i;
4936: 
4937: #ifdef HUGE
4938:     i = hugef ^ 01;
4939: #endif
4940:     for (c = 'a' - 'a'; c <= 'z' - 'a'; c++) {
4941:         if (names[c] == 0)  /* zap marks to deleted lines */
4942:         continue;
4943:         n = 0;
4944:         for (a1 = zero + 1; a1 <= dol; a1++)
4945:         if (names[c] == (*a1 |
4946: #ifdef HUGE
4947:                     i
4948: #else
4949:                     01
4950: #endif
4951:                       )) {
4952:             n++;
4953:             printf("%c=%u", c + 'a', a1 - zero);
4954: #ifdef EXTMARK
4955:             if (names2[c]) {
4956:             for (a1++; a1 <= dol; a1++)
4957:                 if (names2[c] == (*a1 | 01)) {
4958:                 printf(",%u", a1 - zero);
4959:                 break;
4960:                 }
4961:             }
4962: #endif
4963:             putchar(' ');
4964:             break;
4965:         }
4966:         if (n == 0)
4967:         names[c] = 0;   /* clear unknown marks */
4968:     }
4969:     putchar('\n');
4970: }
4971: 
4972: putchar(ac)
4973: charac ac;
4974: {
4975:     register char *lp;
4976:     register charac c;
4977: 
4978:     lp = linp;
4979:     c = ac;
4980: #ifdef APLMAP
4981:     if (aplmap && fout == 1 && c > ' ')
4982:         c = map_apl[c - (' ' + 1)];
4983: #endif
4984:     if (listf) {
4985:         if (++col >= ccount - 1) {
4986:             col = 1;
4987:             if (c != '\n') {
4988:                 *lp++ = '\\';
4989:                 *lp++ = '\n';
4990:             }
4991:         }
4992:         if (c == '\t') {
4993:             c = '>';
4994:             goto esc;
4995:         }
4996:         if (c == '\b') {
4997:             c = '<';
4998:         esc:
4999:             *lp++ = '-';
5000:             *lp++ = '\b';
5001:             *lp++ = c;
5002:             goto out;
5003:         }
5004:         if (c < ' ' && c != '\n' || c == 0177) {
5005:             *lp++ = '^';
5006:             *lp++ = c ^ 0100;
5007:             col++;
5008:             goto out;
5009:         }
5010:     }
5011:     *lp++ = c;
5012: out:
5013:     if (lp >= &line[TTSIZE]) {
5014:         linp = line;
5015:         write(fout, line, lp - line);
5016:         return;
5017:     }
5018:     linp = lp;
5019: }
5020: 
5021: putfile() {
5022:     register char *fp, *lp;
5023:     register nib;
5024:     register linep *a1;
5025: 
5026:     nib = BLKSIZE;
5027:     fp = genbuf;
5028:     a1 = addr1;
5029:     do {
5030:         lp = getline(*a1++);
5031:         for ever {
5032:             if (--nib < 0) {
5033:                 wte(io, genbuf, fp - genbuf);
5034:                 nib = BLKSIZE - 1;
5035:                 fp = genbuf;
5036:             }
5037:             if ((*fp++ = *lp++) == 0) {
5038:                 fp[-1] = '\n';
5039:                 break;
5040:             }
5041:         }
5042:     } while (a1 <= addr2);
5043:     wte(io, genbuf, fp - genbuf);
5044: }
5045: 
5046: putline() {
5047:     register char *bp, *lp;
5048:     register nl, tl;
5049: 
5050:     lp = linebuf;
5051:     tl = tline;
5052: #ifdef DEBUG
5053:     if (tflg)
5054:         printf("putline:\t%o\n", tl);
5055: #endif
5056:     bp = getblock(tl, WRITE);
5057: #ifdef HUGE
5058:     if (hugef2) {
5059:         hugef2 = 0;
5060:         tl = tline = (tline >> 1) & _6[hugef];
5061:     }
5062:     tl &= _1[hugef];
5063: #else
5064:     tl &= _1;
5065: #endif
5066:     nl = nleft;
5067:     while (*bp = *lp++) {
5068:         if (*bp++ == '\n') {
5069:             *--bp = 0;
5070:             linebp = lp;
5071:             break;
5072:         }
5073:         if (--nl <= 0) {
5074: #ifdef HUGE
5075:             bp = getblock(tl += _2[hugef], WRITE);
5076: #else
5077:             bp = getblock(tl += _2, WRITE);
5078: #endif
5079:             nl = nleft;
5080:         }
5081:     }
5082:     nl = tline;
5083: #ifdef HUGE
5084:     tline += (((lp - linebuf) + 03) >> (1 + hugef)) & _6[hugef];
5085: #else
5086:     tline += (((lp - linebuf) + 03) >> 1) & _6;
5087: #endif
5088:     return(nl);
5089: }
5090: 
5091: #ifdef PARENS
5092: putparen(an) {
5093:     register c;
5094: 
5095:     an %= 10 + 26 + 26;
5096:     if (an < 0)
5097:         an += 10 + 26 + 26;
5098:     c = '0';
5099:     if (an > 9 + 26)
5100:         c = 'a' - (10 + 26);
5101:     else if (an > 9)
5102:         c = 'A' - 10;
5103:     putchar(c + an);
5104: }
5105: #endif
5106: 
5107: puts(as) {
5108:     register n;
5109:     register flag ovp;
5110:     register char *sp, *s;
5111: 
5112:     sp = as;
5113:     ovp = 0;
5114:     while (*sp) {
5115:         if (aflg &&
5116: #ifdef PARENS
5117:                 !parenf &&
5118: #endif
5119: #ifdef STRLEN
5120:                        !quotef &&
5121: #endif
5122:                           !listf && *sp == '\b') {
5123:             ovp = 1;
5124:             sp += 2;
5125:             continue;
5126:         }
5127: #ifdef PARENS
5128:         if (!ovp && parenf && !listf && paren(*sp))
5129:             ovp = 1;
5130: #endif
5131: #ifdef STRLEN
5132:     /* if (!ovp && quotef && !listf && (*sp == '"' || *sp == '\'')) */
5133:         if (!ovp && quotef && !listf && (
5134:             quotec? *sp == quotec : *sp == '"' || *sp == '\''))
5135:             ovp = 1;
5136: #endif
5137:         putchar(*sp++);
5138:     }
5139:     sp = as;
5140:     if (aflg && ovp &&
5141: #ifdef PARENS
5142:                !parenf &&
5143: #endif
5144: #ifdef STRLEN
5145:                       !quotef &&
5146: #endif
5147:                          !listf) {
5148:         putchar('\n');
5149:         if (prompt1)
5150:             putchar('\t');
5151:         for (; *sp; sp++)
5152:             if (sp[1] == '\b' && sp[2]) {
5153:                 putchar(sp[2]);
5154:                 sp += 2;
5155:             } else if (*sp == '\t')
5156:                 putchar('\t');
5157:             else if (*sp >= ' ')
5158:                 putchar(' ');
5159:         ovp = 0;
5160:     }
5161: #ifdef PARENS
5162:     if (parenf && ovp && !listf) {
5163:         putchar('\n');
5164:         if (prompt1)
5165:             putchar('\t');
5166:         for (; *sp; sp++)
5167:             if (n = paren(*sp)) {
5168:                 if (n < 0) {
5169:                     n = -n - 1;
5170:                     putparen(parenc[n]--);
5171:                 } else
5172:                     putparen(++parenc[--n]);
5173:             } else if (*sp == '\t' || *sp >= ' ')
5174:                 putchar(*sp == '\t'? '\t' : ' ');
5175:         ovp = 0;
5176:     }
5177: #endif
5178: #ifdef STRLEN
5179:     if (quotef && ovp && !listf) {
5180:         s = null;
5181:         n = 0;
5182:         ovp = 0;
5183:         putchar('\n');
5184:         if (prompt1)
5185:             putchar('\t');
5186:         for (; *sp; sp++) {
5187:         /* if (n == 0 && (*sp == '"' || *sp == '\'') || */
5188:             if (n == 0 && (quotec? *sp == (ovp?
5189:                 quotec : quotec2) : *sp == '"' || *sp == '\'') ||
5190:                 *sp == n) {
5191:                 if (ovp) {
5192:                     ovp = 0;
5193:                     goto not;
5194:                 }
5195:                 if (n)
5196:                     n = 0;
5197:                 else {
5198:                     s = sp++;
5199:                     n = 0;
5200:                     while (*sp && *sp != *s) {
5201:                         if (*sp == '\\') {
5202:                           if ('0' <= *++sp && *sp <= '7') {
5203:                             if ('0' <= *++sp && *sp <= '7')
5204:                               if ('0' <= *++sp && *sp <= '7')
5205:                             sp++;
5206:                           } else
5207:                             sp++;
5208:                         } else
5209:                             sp++;
5210:                         n++;
5211:                     }
5212:                     sp = s;
5213:                     s = &"00000"[5];
5214:                     do {
5215:                         *--s = n % 10 + '0';
5216:                     } while (n /= 10);
5217:                     n = *sp;
5218:                 }
5219:             }
5220:     not:        if (*s)
5221:                 putchar(*s++);
5222:             else
5223:                 putchar(*sp == '\t'? '\t' : ' ');
5224:             if (*sp == '\\')
5225:                 ovp ^= 01;
5226:         }
5227:         ovp = 0;
5228:     }
5229: #endif
5230:     putchar('\n');
5231: }
5232: 
5233: puts2(as) {
5234:     register char *sp;
5235: 
5236:     sp = as;
5237:     while (*sp)
5238:         putchar(*sp++);
5239: }
5240: 
5241: #ifdef CKPT
5242: recover() {
5243:     extern etext;
5244:     register filedes f;
5245:     register char *p;
5246:     register func savint, savqit;
5247:     int n;
5248: 
5249:     savint = signal(SIGINT, 1);
5250:     savqit = signal(SIGQIT, 1);
5251:     if ((f = open(cfname, 0)) < 0 ||
5252:         read(f, &n, sizeof n) != sizeof n) {
5253:         n = 67;
5254:         goto cerror;
5255:     }
5256:     p = &etext;
5257:     if (brk(p + n) == -1) {
5258:         n = 67;
5259:         goto cerror;
5260:     }
5261: #ifdef pdp11    /* 16 bit byte count only */
5262:     if (n < 0) {
5263:         if (read(f, p, 32256) != 32256) {
5264:             n = 67;
5265:             goto cerror;
5266:         }
5267:         n -= 32256; /* 63 blocks, since 64 is < 0 */
5268:         p += 32256;
5269:     }
5270: #endif
5271:     if (read(f, p, n) != n ||
5272:         (tfile = open(tfname, 2)) < 0)
5273:         n = 67;
5274:     else
5275:         n = 0;
5276:     recovry = 1;    /* overwritten by reading data space */
5277:     cerror:
5278:     if (n) {
5279:         puts(errtext[n]);
5280:         exit(1);
5281:     }
5282:     if (f > 0)
5283:         close(f);
5284: 
5285:     /*
5286: 	 * "initialize" special stuff to restore order
5287: 	 */
5288: 
5289:     globp = 0;
5290:     io = 0;
5291:     io_w = 0;
5292: #ifdef HELP
5293:     doc = 0;
5294: #endif
5295: #ifdef USE
5296:     alt = 0;
5297: #endif
5298: #ifdef AGAIN
5299:     agf = 0;
5300:     agp = 0;
5301: #endif
5302: #ifdef EOL
5303:     prompt3 = 1;
5304: #endif
5305: #ifdef PIPE
5306:     if (pfile) {
5307:         unlink(pfname);
5308:         pfile = 0;
5309:     }
5310: #endif
5311: 
5312:     signal(SIGINT, savint);
5313:     signal(SIGQIT, savqit);
5314: }
5315: #endif
5316: 
5317: reverse(aa1, aa2) {
5318:     register linep *a1, *a2, t;
5319: 
5320:     a1 = aa1;
5321:     a2 = aa2;
5322:     for ever {
5323:         t = *--a2;
5324:         if (a2 <= a1)
5325:             return;
5326:         *a2 = *a1;
5327:         *a1++ = t;
5328:     }
5329: }
5330: 
5331: #ifdef XDEL
5332: saveline() {
5333:     register linep *a1, *a2, *bp;
5334:     register nl, tl;
5335: 
5336:     a1 = addr1;
5337:     a2 = addr2;
5338:     ndeleted = a2 - a1 + 1;
5339:     tl = tline;
5340: #ifdef DEBUG
5341:     if (tflg)
5342:         printf("saveline:\t%o\n", tl);
5343: #endif
5344:     bp = getblock(tl, WRITE);
5345: #ifdef HUGE
5346:     if (hugef2) {
5347:         hugef2 = 0;
5348:         tl = (tl >> 1) & _6[hugef];
5349:     }
5350:     tl &= _1[hugef];
5351: #else
5352:     tl &= _1;
5353: #endif
5354:     nl = nleft / sizeof(linep);
5355:     while (a1 <= a2) {
5356:         *bp++ = *a1++;
5357:         if (--nl <= 0) {
5358: #ifdef HUGE
5359:             bp = getblock(tl += _2[hugef], WRITE);
5360:             if (hugef2) {
5361:                 hugef2 = 0;
5362:                 tl = (tl >> 1) & _6[hugef];
5363:             }
5364: #else
5365:             bp = getblock(tl += _2, WRITE);
5366: #endif
5367:             nl = nleft / sizeof(linep);
5368:         }
5369:     }
5370:     deleted = tline;
5371: #ifdef HUGE
5372:     tline += ((a2 - addr1 + 1) << (1 - hugef)) & _6[hugef];
5373: #else
5374:     tline += ((a2 - addr1 + 1) << 1) & _6;
5375: #endif
5376: }
5377: #endif
5378: 
5379: savemark(p1, p2)
5380: linep p1, p2;
5381: {
5382:     register n;
5383: #ifdef HUGE
5384:     register i;
5385: 
5386:     i = hugef ^ 01;
5387:     p1 |= i;
5388:     p2 |= i;
5389: #else
5390:     p1 |= 01;
5391:     p2 |= 01;
5392: #endif
5393:     /* save "marks" on lines so marked */
5394:     for (n = 0; n <= 'z' - 'a'; n++) {
5395:         if (names[n] == 0)  /* zap marks to deleted lines */
5396:             continue;
5397:         if (names[n] == p1)
5398:             names[n] = p2;
5399: #ifdef EXTMARK
5400:         if (names2[n] && names2[n] == p1)
5401:             names2[n] = p2;
5402: #endif
5403:     }
5404: #ifdef YINT
5405:     /* don't lose "y+" line either */
5406:     if (yplus == p1)
5407:         yplus = p2;
5408: #endif
5409: #ifdef UNDO
5410:     /* and remember the line for "undo" */
5411:     undo_oldp = p1;
5412:     undo_newp = p2;
5413: #endif
5414: }
5415: 
5416: scopy(ass, ads)
5417: char *ass, *ads;
5418: {
5419:     register char *p, *q;
5420: 
5421:     p = ass;
5422:     q = ads;
5423:     while (*q++ = *p++)
5424:         ;
5425:     return(ads);
5426: }
5427: 
5428: setall() {
5429:     if (addr2 == 0) {
5430:         addr1 = zero + (zero != dol);
5431:         addr2 = dol;
5432:     }
5433:     setdot();
5434: }
5435: 
5436: setchar(adflt) {
5437:     register charac c;
5438: 
5439:     if ((c = getchar()) == '\\')
5440:         c = getchar();
5441:     if (c < 0)
5442:         errmsg(59);
5443:     if (c == '\n')
5444:         return(adflt);
5445:     newline();
5446:     return(c);
5447: }
5448: 
5449: setdot() {
5450:     if (addr2 == 0)
5451:         addr1 = addr2 = dot;
5452:     if (addr1 > addr2)
5453:         errmsg(21);
5454: }
5455: 
5456: setnoaddr() {
5457:     if (addr2)
5458:         errmsg(22);
5459: }
5460: 
5461: setnum(adflt) {
5462:     register n;
5463: 
5464:     white_space();
5465:     n = adflt;
5466:     if ('0' <= (peekc = getchar()) && peekc <= '9')
5467:         n = getnum();
5468:     newline();
5469:     return(n);
5470: }
5471: 
5472: #ifdef TABS
5473: settab(acs) {
5474:     register *p, i, n;
5475: 
5476:     if (acs == 0) {
5477:         maxtab = -1;
5478:         n = TABS;
5479:         p = tabs;
5480:         while (--n >= 0)
5481:             *p++ = 0;
5482:         return;
5483:     }
5484:     i = 0;
5485:     if (acs < 0) {
5486:         acs = -acs;
5487:         i++;
5488:     }
5489:     if (--acs < TABS * BPW) {
5490:         p = &tabs[acs >> BPWC];
5491:         *p |= 01 << (n = acs & BPWM);
5492:         if (i) {
5493:             *p ^= 01 << n;
5494:             if (acs == maxtab) {    /* find new maxtab */
5495:                 for (n = TABS - 1; n >= 0; --n)
5496:                     if (tabs[n >> BPWC] >> (n & BPWM) & 01)
5497:                         break;
5498:                 maxtab = n;
5499:             }
5500:         } else if (acs > maxtab)
5501:             maxtab = acs;
5502:     }
5503: }
5504: #endif
5505: 
5506: shell() {
5507: #ifdef PIPE
5508:     extern oil_spilled();
5509: #endif
5510:     register pid, wpid;
5511:     register linep *a;
5512:     register dp, df, nopipe, c, e, savint, savqit;
5513:     register linep *dest;
5514:     int retcode, p[2];
5515: 
5516: #ifdef PIPE
5517:     dp = 0;
5518:     df = 0;
5519:     if (addr2) {
5520: #ifdef LOG
5521:         ++logstats.lc_pipe;
5522: #endif
5523:         dest = 0;
5524:         nopipe = 0;
5525:         if ((peekc = getchar()) == '|') {
5526:             nonzero();
5527:             peekc = 0;
5528:             dp++;
5529:             df++;
5530: #ifdef LOG
5531:             --logstats.lc_pipe;
5532:             ++logstats.lc_dpipe;
5533: #endif
5534:         }
5535:         if ((peekc = getchar()) == '>') {
5536:             nonzero();
5537: #ifdef LOG
5538:             --logstats.lc_pipe;
5539:             ++logstats.lc_pto;
5540: #endif
5541:             goto pi;
5542:         } else if ((peekc = getchar()) == '<') {
5543:             nopipe++;
5544: #ifdef LOG
5545:             --logstats.lc_pipe;
5546:             ++logstats.lc_pfrom;
5547: #endif
5548:     pi:         peekc = 0;
5549:             dp++;
5550:             dest = addr2;
5551:         }
5552:         if (dp && '0' <= (peekc = getchar()) && peekc <= '9') {
5553:             c = getnum();
5554:             dest = zero + c;
5555:             if (dest < zero)
5556:                 dest = zero + 1;
5557:             if (dest > dol)
5558:                 dest = dol;
5559:         }
5560:     }
5561: #ifdef LOG
5562:       else
5563:         ++logstats.lc_shell;
5564: #endif
5565:     piperr = 0;
5566:     if (!iflg)
5567:         if (addr2) {
5568:             savint = signal(SIGINT, oil_spilled);
5569:             savqit = signal(SIGQIT, oil_spilled);
5570:         } else {
5571: #endif
5572:             savint = signal(SIGINT, 1);
5573:             savqit = signal(SIGQIT, 1);
5574: #ifdef PIPE
5575:         }
5576:     if (addr2 && pipe(p) < 0) {
5577:         c = 15;
5578:     errm:   if (!iflg) {
5579:             signal(SIGINT, savint);
5580:             signal(SIGQIT, savqit);
5581:         }
5582:         if (c)
5583:             errmsg(c);
5584:         error();
5585:     }
5586:     if (dp) {
5587:         if ((pfile = create(pfname, LMODE)) < 0) {
5588:             pfile = 0;
5589:             c = 64;
5590:             goto errm;
5591:         }
5592:         if ((io = open(pfname, 0)) < 0) {
5593:             io = 0;
5594:             c = 65;
5595:             goto errm;
5596:         }
5597:     }
5598: #endif
5599:     if ((pid = fork()) < 0) {
5600: #ifdef PIPE
5601:         if (addr2) {
5602:             close(p[0]);
5603:             close(p[1]);
5604:         }
5605: #endif
5606:         c = 14;
5607:         goto errm;
5608:     }
5609:     if (pid == 0) {
5610: /* kid */   if (!iflg) {
5611: /* kid */       signal(SIGHUP, 0);
5612: /* kid */       signal(SIGINT, 0);
5613: /* kid */       signal(SIGQIT, 0);
5614: /* kid */   }
5615: #ifdef PIPE
5616: /* kid */   if (addr2) {
5617: /* kid */       close(0);
5618: /* kid */       dup(p[0]);
5619: /* kid */       close(p[0]);
5620: /* kid */       close(p[1]);
5621: /* kid */       if (dp) {
5622: /* kid */           close(1);
5623: /* kid */           dup(pfile);
5624: /* kid */           close(pfile);
5625: /* kid */       }
5626: /* kid */   }
5627: #endif
5628: /* kid */   execl("/bin/sh", "!sh", "-t", 0);
5629: /* kid */   write(2, "No shell!\n", 10);
5630: /* kid */   exit(0177);
5631:     }
5632: #ifdef CMDS
5633:     if (cmd && !addr2)
5634:         write(cmd, "<UNIX>\n", 7);
5635: #endif
5636: #ifdef PIPE
5637:     if (addr2) {
5638:         signal(SIGPIP, oil_spilled);
5639:         close(p[0]);
5640:         e = eflg2;
5641:         eflg2++;
5642:         fout = p[1];
5643:         while ((c = getchar()) >= 0 && c != '\n')
5644:             putchar(c);
5645:         putchar('\n');
5646:         if (!nopipe) {
5647:             line_num = (a = addr1) - zero - aflg;
5648:             do {
5649:                 if (pno >= 0)
5650:                     printlno(line_num++);
5651:                 puts(getline(*a++));
5652:             } while (a <= addr2 && !piperr);
5653:         }
5654:         flush_buf();
5655:         fout = 1;
5656:         eflg2 = e;
5657:         close(p[1]);
5658:         if (!iflg) {
5659:             signal(SIGINT, 1);
5660:             signal(SIGQIT, 1);
5661:         }
5662:     }
5663: #endif
5664:     while ((wpid = wait(&retcode)) != pid && wpid >= 0);
5665: #ifdef CMDS
5666:     if (cmd)
5667:         lseek(cmd, 0L, 2);
5668: #endif
5669: #ifdef PIPE
5670:     if (addr2)
5671:         signal(SIGPIP, 0);
5672: #endif
5673:     if (c = retcode & 0177) {
5674:         if (0 < c && c < NSTR && status[c])
5675:             puts2(status[c]);
5676:         else
5677:             printf("signal %d", c);
5678:         if (retcode & 0200)
5679:             puts2(" -- core dumped");
5680:         putchar(lastc = '\n');
5681:         c = 0;
5682:         goto errm;
5683:     } else if (df && strict && retcode >> 8) {
5684:         printf("exit status %d\n", retcode >> 8);
5685:         c = 0;
5686:         goto errm;
5687:     }
5688: #ifdef PIPE
5689:       else if (addr2) {
5690:         if (piperr) {
5691:             putsn(status[SIGPIP]);
5692:             c = 0;
5693:             goto errm;
5694:         }
5695:         if (dp) {
5696:             if (df) {
5697:                 c = addr2 != dol;
5698:                 delete();
5699:                 if (dest == 0)
5700:                     dest = dot - c;
5701:             } else if (dest == 0)
5702:                 dest = addr2;
5703:             if (dest < zero)
5704:                 dest = zero;
5705:             if (c = append(getfile, dest, 0, 0))
5706:                 text_modified++;
5707:             if (prompt2)
5708:                 printf((curt? prcntu : errtext[55]),
5709:                     c, (c == 1? null : quote_s));
5710:             close(io);
5711:             io = 0;
5712:             unlink(pfname);
5713:             close(pfile);
5714:             pfile = 0;
5715:         }
5716:     }
5717: #endif
5718:     if (!iflg) {
5719:         signal(SIGINT, savint);
5720:         signal(SIGQIT, savqit);
5721:     }
5722:     if (!addr2)
5723:         putsn("!");
5724: #ifdef CLEAR
5725:     istty(1);   /* in case bs1 changed */
5726: #endif
5727: }
5728: 
5729: signals(ast)
5730: struct sigtab *ast;
5731: {
5732:     register n;
5733:     register struct sigtab *s;
5734: 
5735:     s = ast - 1;
5736:     while (n = (++s)->s_sig)
5737:         signal(n, s->s_func);
5738: }
5739: 
5740: skip_rest() {
5741:     register charac c;
5742: 
5743:     while ((c = getchar()) >= 0 && c != '\n');
5744: }
5745: 
5746: substitute(inglob) {
5747:     extern getsub();
5748:     register linep *a1, p;
5749:     register nl;
5750:     register flag gsubf;
5751: 
5752:     gsubf = compsub();      /* 0 or 1 depending on 'g' */
5753:     for (a1 = addr1; a1 <= addr2; a1++) {
5754:         s_tmp = s_cnt;
5755:         if (execute(0, a1) == 0)
5756:             continue;
5757:         inglob |= 01;
5758:         dosub();
5759:         if (gsubf)
5760:             while (*loc2) {
5761:                 if (execute(1) == 0)
5762:                     break;
5763:                 dosub();
5764:             }
5765:         p = *a1;
5766:         *a1 = putline();
5767:         savemark(p, *a1);
5768:         nl = append(getsub, a1, 0, 0);
5769:         a1 += nl;
5770:         addr2 += nl;
5771:     }
5772:     if (inglob == 0)
5773:         errmsg(39);
5774: }
5775: 
5776: #ifdef XED
5777: tack(aeof, aflag)
5778: char aeof;
5779: {
5780:     register n;
5781:     register char *p1, *p2;
5782:     register linep *a;
5783:     register charac c;
5784: 
5785:     nonzero();
5786:     setdot();
5787:     p1 = rhsbuf;    /* i/TEXT screwed for long lines */
5788:     while ((c = getchar()) != aeof && c != '\n') {
5789:         if (c == '\\')
5790:             if ((c = getchar()) == '\n')
5791:                 break;
5792:         if (c < 0)
5793:             errmsg(59);
5794:         *p1++ = c;
5795:         if (p1 >= &rhsbuf[LBSIZE / 2 - 2])
5796:             errmsg(42);
5797:     }
5798:     if (*rhsbuf == 0)
5799:         errmsg(27);
5800:     if (c == '\n') {
5801:         if (prompt2)
5802:             pflag++;
5803:     } else
5804:         newline();
5805:     if (p1 != rhsbuf)
5806:         *p1 = 0;
5807:     else
5808:         while (*p1)
5809:             p1++;
5810:     n = p1 - rhsbuf;
5811:     for (a = addr1; a <= addr2; a++) {
5812:         getline(*a);
5813:         for (p2 = linebuf; *p2; p2++);
5814: #ifndef ALLOC
5815:         if (p2 + n >= &linebuf[LBSIZE / 2 - 2])
5816: #else
5817:         if (p2 + n >= &linebuf[lbsize / 2 - 2])
5818: #endif
5819:             errmsg(30);
5820:         if (aflag) {    /* $ */
5821:             p1 = rhsbuf;
5822:             while (*p2++ = *p1++);
5823:         } else {    /* ^ */
5824:             p1 = p2 + n;
5825:             *p1 = *p2;
5826:             while (p2 > linebuf)
5827:                 *--p1 = *--p2;
5828:             p1 = linebuf;
5829:             p2 = rhsbuf;
5830:             while (*p2)
5831:                 *p1++ = *p2++;
5832:         }
5833:         p2 = *a;
5834:         *a = putline();
5835:         savemark(p2, *a);
5836:     }
5837:     dot = addr2;
5838:     return(addr2 - addr1 + 1);
5839: }
5840: #endif
5841: 
5842: term() {
5843:     signal(SIGTRM, 1);
5844:     if (reading) {
5845:         backup(TRM);
5846:         if (fout != 1) {
5847:             flush_buf();
5848:             fout = 1;
5849:         }
5850:         puts2(errtext[58]);
5851:         delexit(1);
5852:     }
5853:     termflg++;
5854: }
5855: 
5856: tmpname(as, an)
5857: char *as;
5858: {
5859:     register unsigned n;
5860:     register char *p, c;
5861: 
5862:     p = as;
5863:     n = an;
5864:     while (*p)
5865:         p++;
5866:     while (--p >= as)
5867:         if ((c = *p) == '0' || (c | 040) == 'x') {
5868:             *p = n % 10 + '0';
5869:             n /= 10;
5870: #ifdef CKPT
5871:             tfnum = p - as;
5872: #endif
5873:         }
5874:     return(as);
5875: }
5876: 
5877: #ifdef XDEL
5878: undelete() {
5879:     register linep *a1, *a2, *bp;
5880:     register tl, nl, num;
5881: 
5882:     if ((tl = deleted) == 0)
5883:         errmsg(16);
5884: #ifdef DEBUG
5885:     if (tflg)
5886:         printf("undelete:\t%o\n", tl);
5887: #endif
5888:     setdot();
5889:     a1 = dol + 1;
5890:     a2 = a1 + ndeleted;
5891:     bp = addr2 + 1;
5892:     if (dol + ndeleted > endcore) {
5893:         num = ((ndeleted * 2) + 1023) & ~01777;
5894:         if (sbrk(num) == -1)
5895:             errmsg(33);
5896:         endcore = (int)endcore + num;
5897:     }
5898:     while (a1 > bp)
5899:         *--a2 = *--a1;
5900:     dol += ndeleted;
5901:     a1 = addr2 + 1;
5902:     a2 = a1 + ndeleted;
5903:     bp = getblock(tl, READ);
5904: #ifdef HUGE
5905:     tl &= _1[hugef];
5906: #else
5907:     tl &= _1;
5908: #endif
5909:     nl = nleft / sizeof(linep);
5910:     while (a1 < a2) {
5911:         *a1++ = *bp++;
5912:         if (--nl <= 0) {
5913: #ifdef HUGE
5914:             bp = getblock(tl += _2[hugef], READ);
5915: #else
5916:             bp = getblock(tl += _2, READ);
5917: #endif
5918:             nl = nleft / sizeof(linep);
5919:         }
5920:     }
5921:     dot = a2 - 1;
5922:     return(ndeleted);
5923: }
5924: #endif
5925: 
5926: #ifdef UNDO
5927: undo() {
5928:     register linep *a, t, o;
5929: 
5930:     if (undo_newp == 0 || (a = findmark(undo_newp, 0)) == 0)
5931:         errmsg(13);
5932:     t = *a |
5933: #ifdef HUGE
5934:          hugef ^
5935: #endif
5936:              01;
5937:     o = undo_oldp;
5938:     savemark(*a, o);
5939:     *a = o;
5940:     undo_newp = o;
5941:     undo_oldp = t;
5942:     dot = a;
5943:     if (text_modified == 0)
5944:         text_modified++;
5945: }
5946: #endif
5947: 
5948: white_space() {
5949:     register charac c;
5950: 
5951:     while ((c = getchar()) == ' ' || c == '\t');
5952:     peekc = c;
5953: }
5954: 
5955: wte(fd, buf, len)
5956: char buf[];
5957: {
5958:     if (write(fd, buf, len) != len)
5959:         errmsg(-32);
5960: }
5961: 
5962: /*
5963:  * as	a prompt string
5964:  * ay	yes response, !no response
5965:  * ad	default (\n) response, <0 means no default allowed
5966:  * aef	end-of-file response
5967:  */
5968: yes_no(as, ay, ad, aef)
5969: char *as;
5970: {
5971:     register charac c, p;
5972:     register n;
5973:     register flag l;
5974: 
5975:     l = listf;
5976:     listf = 0;
5977:     p = peekc;
5978:     peekc = 0;
5979:     for ever {
5980:         putchar('\n');
5981:         puts2(as);
5982:         puts2("? ");
5983:         for (n = 0; n < 5; n++) {
5984:             flush_buf();
5985:             if ((c = getchar()) < 0) {
5986:                 putchar('\n');
5987:                 n = aef;
5988:                 goto ret;
5989:             }
5990:             if (c != '\n')
5991:                 skip_rest();
5992:             else if (ad >= 0) {
5993:                 n = ad;
5994:                 goto ret;
5995:             }
5996:             if (c == 'y' || c == 'n') {
5997:                 n = ay;
5998:                 if (c != 'y')
5999:                     n ^= 01;
6000:                 goto ret;
6001:             }
6002:             puts2("yes or no? ");
6003:         }
6004:     }
6005:     ret:
6006:     listf = l;
6007:     peekc = p;
6008:     return(n);
6009: }

Defined functions

_cleanup defined in line 1849; never used
abort defined in line 1162; used 1 times
address defined in line 1180; used 2 times
advance defined in line 1396; used 5 times
append defined in line 1498; used 7 times
are_you_sure defined in line 1532; used 3 times
argnum defined in line 1543; used 6 times
backchk defined in line 1557; used 2 times
backref defined in line 1573; used 2 times
backup defined in line 1588; used 15 times
badsig defined in line 1679; used 9 times
blkio defined in line 1696; used 3 times
cclass defined in line 1706; used 2 times
checkpoint defined in line 1735; used 10 times
chk defined in line 1796; used 1 times
clear defined in line 1854; used 3 times
commands defined in line 1869; used 3 times
compile defined in line 3040; used 3 times
compsub defined in line 3217; used 1 times
create defined in line 3256; used 4 times
delete defined in line 3277; used 4 times
delexit defined in line 3297; used 7 times
dosub defined in line 3318; used 2 times
dump defined in line 3366; used 1 times
echo defined in line 3393; used 1 times
errfunc defined in line 3420; used 1 times
errmsg defined in line 3464; used 93 times
exp defined in line 3543; used 11 times
expand defined in line 3563; used 2 times
expdmp defined in line 3671; used 3 times
filename defined in line 3747; used 4 times
findmark defined in line 3789; used 6 times
flush_buf defined in line 3812; used 16 times
gask defined in line 3822; used 1 times
getblock defined in line 3843; used 16 times
getchar defined in line 3917; used 94 times
getcopy defined in line 3978; used 2 times
getfile defined in line 3985; used 4 times
getline defined in line 4028; used 9 times
getnum defined in line 4060; used 8 times
getsnum defined in line 4071; used 1 times
getsub defined in line 4079; used 2 times
gettty defined in line 4090; used 3 times
global defined in line 4144; used 2 times
hangup defined in line 4228; used 3 times
header defined in line 4242; used 1 times
init defined in line 4278; used 2 times
istty defined in line 4385; used 2 times
join defined in line 4406; used 1 times
listabs defined in line 4509; used 1 times
mail defined in line 4522; used 3 times
main defined in line 776; never used
move defined in line 4526; used 2 times
newline defined in line 4559; used 33 times
next_tab defined in line 4590; used 2 times
nonzero defined in line 4603; used 18 times
oil_spilled defined in line 4611; used 4 times
onintr defined in line 4621; used 4 times
override defined in line 4678; used 2 times
page defined in line 4715; used 1 times
paren defined in line 4810; used 3 times
place defined in line 4823; used 2 times
printf defined in line 4842; used 27 times
printfn defined in line 4891; used 2 times
printlno defined in line 4920; used 6 times
printmarks defined in line 4932; used 1 times
putchar defined in line 4972; used 64 times
putfile defined in line 5021; used 2 times
putline defined in line 5046; used 5 times
putparen defined in line 5092; used 2 times
puts defined in line 5107; used 9 times
puts2 defined in line 5233; used 47 times
recover defined in line 5242; used 1 times
reverse defined in line 5317; used 6 times
saveline defined in line 5332; used 1 times
savemark defined in line 5379; used 5 times
scopy defined in line 5416; used 5 times
setall defined in line 5428; used 3 times
setchar defined in line 5436; used 3 times
setdot defined in line 5449; used 20 times
setnoaddr defined in line 5456; used 26 times
setnum defined in line 5461; used 4 times
settab defined in line 5473; used 2 times
shell defined in line 5506; used 2 times
signals defined in line 5729; used 2 times
skip_rest defined in line 5740; used 5 times
substitute defined in line 5746; used 1 times
tack defined in line 5777; used 2 times
term defined in line 5842; used 5 times
tmpname defined in line 5856; used 3 times
undelete defined in line 5878; used 1 times
undo defined in line 5927; used 1 times
white_space defined in line 5948; used 7 times
wte defined in line 5955; used 2 times
yes_no defined in line 5968; used 4 times

Defined variables

Sccsid defined in line 1; never used
_1 defined in line 589; never used
_env_rst defined in line 51; used 2 times
addr1 defined in line 543; used 70 times
addr2 defined in line 544; used 95 times
aflg defined in line 511; used 8 times
agbuf defined in line 207; used 5 times
agf defined in line 209; used 6 times
agp defined in line 208; used 17 times
alt defined in line 418; used 18 times
altfile defined in line 419; used 7 times
aplmap defined in line 217; used 3 times
braelist defined in line 440; used 9 times
braslist defined in line 441; used 7 times
brcount defined in line 490; used 6 times
ccount defined in line 383; used 5 times
cfname defined in line 222; used 5 times
clears defined in line 228; used 2 times
cmd defined in line 234; used 13 times
cmdfil defined in line 235; used 1 times
deleted defined in line 424; used 6 times
doc defined in line 257; used 11 times
dol defined in line 545; used 65 times
dot defined in line 546; used 37 times
dotbak defined in line 442; used 1 times
dotdot defined in line 547; used 7 times
dumbf defined in line 243; used 9 times
eflg2 defined in line 420; used 11 times
endcore defined in line 548; used 7 times
eol defined in line 247; used 4 times
errtext defined in line 610; used 28 times
fendcore defined in line 549; used 4 times
fout defined in line 507; used 12 times
gaskf defined in line 253; used 4 times
help defined in line 258; used 2 times
iblock defined in line 437; used 4 times
lastc defined in line 487; used 26 times
lastdot defined in line 550; used 4 times
lbsize defined in line 213; used 18 times
lfile defined in line 263; never used
logamp defined in line 264; used 3 times
logfile defined in line 262; never used
maxtab defined in line 408; used 11 times
names defined in line 551; used 12 times
names2 defined in line 553; used 11 times
ndeleted defined in line 425; used 12 times
old_a1 defined in line 555; used 3 times
old_a2 defined in line 556; used 3 times
parenc defined in line 387; used 8 times
parenf defined in line 388; used 11 times
pfile defined in line 392; used 14 times
pfname defined in line 393; used 8 times
piperr defined in line 394; used 4 times
prompt3 defined in line 249; used 8 times
quotec defined in line 400; used 8 times
quotef defined in line 402; used 11 times
recovry defined in line 223; used 7 times
sigtab1 defined in line 749; used 1 times
status defined in line 686; used 8 times
tabfill defined in line 406; used 3 times
tflg defined in line 239; used 6 times
tline defined in line 557; used 11 times
undo_newp defined in line 414; used 5 times
undo_oldp defined in line 413; used 4 times
yflg defined in line 429; used 7 times
yplus defined in line 430; used 8 times
zero defined in line 558; used 58 times
zflg defined in line 229; used 6 times

Defined struct's

logstat defined in line 265; never used
sigtab defined in line 746; used 4 times

Defined typedef's

block defined in line 68; used 2 times
charac defined in line 69; used 37 times
filedes defined in line 70; used 9 times
flag defined in line 71; used 23 times
linep defined in line 73; used 43 times

Defined macros

AGAIN defined in line 94; used 7 times
ALLOC defined in line 95; used 20 times
APLMAP defined in line 96; used 4 times
BAK defined in line 154; used 1 times
BLKSIZE defined in line 155; used 7 times
BPB defined in line 77; used 2 times
BPW defined in line 78; used 4 times
BPWC defined in line 79; used 7 times
BPWM defined in line 80; used 6 times
BS1 defined in line 156; used 2 times
CBACK defined in line 157; used 3 times
CBRA defined in line 158; used 2 times
CCHR defined in line 159; used 4 times
CCL defined in line 160; used 5 times
CCOUNT defined in line 161; used 2 times
CDOL defined in line 162; used 1 times
CDOT defined in line 163; used 3 times
CEOF defined in line 164; used 1 times
CKET defined in line 165; used 3 times
CLEAR defined in line 138; used 8 times
CMDS defined in line 139; used 7 times
DEBUG defined in line 97; used 11 times
DUMB defined in line 141; used 9 times
EEDHELP defined in line 129; used 1 times
EEDPROMPT defined in line 130; used 1 times
EEDTTL defined in line 131; used 1 times
EOF defined in line 166; used 6 times
EOL defined in line 99; used 12 times
ESIZE defined in line 167; used 3 times
EXTMARK defined in line 100; used 6 times
FILE defined in line 168; used 6 times
FNSIZE defined in line 169; used 9 times
GBSIZE defined in line 170; used 4 times
G_VFY defined in line 101; used 5 times
HELP defined in line 125; used 6 times
HUGE defined in line 104; used 29 times
HUP defined in line 171; used 2 times
INT defined in line 172; used 1 times
LBSIZE defined in line 173; used 24 times
LMASK defined in line 174; used 2 times
LMODE defined in line 175; used 6 times
MODCNT defined in line 176; used 2 times
MODE defined in line 177; used 3 times
NBRA defined in line 178; used 5 times
NCCL defined in line 179; used 3 times
NERR defined in line 680; used 2 times
NSTR defined in line 718; used 2 times
PAGE defined in line 106; used 7 times
PAGSIZ defined in line 180; used 2 times
PARENS defined in line 107; used 18 times
PIPE defined in line 108; used 17 times
PROMPT defined in line 126; used 1 times
READ defined in line 181; used 10 times
SIGBUS defined in line 182; used 2 times
SIGEMT defined in line 183; used 2 times
SIGFPE defined in line 184; used 2 times
SIGHUP defined in line 185; used 6 times
SIGILL defined in line 186; used 2 times
SIGINT defined in line 187; used 22 times
SIGIOT defined in line 188; used 2 times
SIGPIP defined in line 189; used 4 times
SIGQIT defined in line 190; used 17 times
SIGSEGV defined in line 191; used 2 times
SIGSYS defined in line 192; used 2 times
SIGTRC defined in line 193; used 1 times
SIGTRM defined in line 194; used 2 times
STAR defined in line 195; used 2 times
STRLEN defined in line 110; used 15 times
TABFILL defined in line 196; used 2 times
TABS defined in line 111; used 25 times
TMP defined in line 197; used 8 times
TRM defined in line 198; used 2 times
TTL defined in line 127; used 1 times
TTSIZE defined in line 199; used 2 times
UNDO defined in line 114; used 5 times
USE defined in line 115; used 19 times
V7 defined in line 26; used 3 times
WRITE defined in line 200; used 6 times
XDEL defined in line 116; used 8 times
XED defined in line 25; used 13 times
YINT defined in line 117; used 8 times
_1 defined in line 596; used 10 times
_1a defined in line 580; used 2 times
_1b defined in line 571; used 1 times
_2 defined in line 597; used 11 times
_2a defined in line 581; used 2 times
_2b defined in line 572; used 1 times
_3 defined in line 598; used 5 times
_3a defined in line 582; used 2 times
_3b defined in line 573; used 1 times
_4 defined in line 599; used 5 times
_4a defined in line 583; used 2 times
_4b defined in line 574; used 1 times
_5 defined in line 600; used 3 times
_5a defined in line 584; used 2 times
_5b defined in line 575; used 1 times
_6 defined in line 601; used 10 times
_6a defined in line 585; used 2 times
_6b defined in line 576; used 1 times
ctrl defined in line 204; used 4 times
error defined in line 203; used 9 times
ever defined in line 201; used 9 times
max defined in line 722; used 1 times
min defined in line 721; used 1 times
putsn defined in line 720; used 42 times
r defined in line 2344; used 37 times
reset defined in line 53; used 3 times
setexit defined in line 52; used 2 times
Last modified: 1986-10-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 23136
Valid CSS Valid XHTML 1.0 Strict