Annotation of 43BSD/contrib/apl/src/xed.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.