/* * When a hangup occurs our actions are similar to a preserve * command. If the buffer has not been [Modified], then we do * nothing but remove the temporary files and exit. * Otherwise, we sync the temp file and then attempt a preserve. * If the preserve succeeds, we unlink our temp files. * If the preserve fails, we leave the temp files as they are * as they are a backup even without preservation if they * are not removed. */ void onhup(int i) { (void)i; /* * USG tty driver can send multiple HUP's!! */ signal(SIGINT, SIG_IGN); signal(SIGHUP, SIG_IGN); if (chng == 0) { cleanup(1); ex_exit(0); } if (setexit() == 0) { if (preserve()) { cleanup(1); ex_exit(0); } } ex_exit(1); }
int main(int argc, char *argv[]) { Vstr_base *s2 = NULL; Vstr_base *s1 = ex_init(&s2); int count = 1; /* if no arguments are given just do stdin to stdout */ if (count >= argc) { io_fd_set_o_nonblock(STDIN_FILENO); ex_phones_name_read_fd_write_stdout(s1, s2, STDIN_FILENO); } /* loop through all arguments, open the file specified * and do the read/write loop */ while (count < argc) { unsigned int ern = 0; if (s2->len <= EX_MAX_R_DATA_INCORE) vstr_sc_mmap_file(s2, s2->len, argv[count], 0, 0, &ern); if ((ern == VSTR_TYPE_SC_MMAP_FILE_ERR_FSTAT_ERRNO) || (ern == VSTR_TYPE_SC_MMAP_FILE_ERR_MMAP_ERRNO) || (ern == VSTR_TYPE_SC_MMAP_FILE_ERR_TOO_LARGE)) { int fd = io_open(argv[count]); ex_phones_name_read_fd_write_stdout(s1, s2, fd); if (close(fd) == -1) warn("close(%s)", argv[count]); } else if (ern && (ern != VSTR_TYPE_SC_MMAP_FILE_ERR_CLOSE_ERRNO)) err(EXIT_FAILURE, "add"); else ex_phones_name_process_limit(s1, s2, EX_MAX_R_DATA_INCORE); ++count; } ex_phones_name_process_limit(s1, s2, 0); io_put_all(s1, STDOUT_FILENO); exit (ex_exit(s1, s2)); }
int main(int argc, char *argv[]) { Vstr_base *s1 = ex_init(NULL); mpz_t bignum; const char *loc_num_name = NULL; Vstr_ref *ref = NULL; const unsigned int num_flags = (VSTR_FLAG_PARSE_NUM_SEP | VSTR_FLAG_PARSE_NUM_SPACE); if (argc < 2) errx(EXIT_FAILURE, "No count specified"); vstr_cntl_conf(s1->conf, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '$'); vstr_fmt_add(s1->conf, "<dMPZ:%p>", ex_usr_dmpz_cb, VSTR_TYPE_FMT_PTR_VOID, VSTR_TYPE_FMT_END); vstr_fmt_add(s1->conf, "<oMPZ:%p>", ex_usr_ompz_cb, VSTR_TYPE_FMT_PTR_VOID, VSTR_TYPE_FMT_END); vstr_fmt_add(s1->conf, "<xMPZ:%p>", ex_usr_xmpz_cb, VSTR_TYPE_FMT_PTR_VOID, VSTR_TYPE_FMT_END); vstr_fmt_add(s1->conf, "<bMPZ:%p>", ex_usr_bmpz_cb, VSTR_TYPE_FMT_PTR_VOID, VSTR_TYPE_FMT_END); setlocale(LC_ALL, ""); loc_num_name = setlocale(LC_NUMERIC, NULL); if (!vstr_cntl_conf(s1->conf, VSTR_CNTL_CONF_SET_LOC_CSTR_AUTO_NAME_NUMERIC, loc_num_name)) errx(EXIT_FAILURE, "Couldn't change numeric locale info"); mpz_init(bignum); if (!vstr_add_cstr_ptr(s1, 0, argv[1]) || !vstr_parse_num(s1, 1, s1->len, num_flags, NULL, NULL, vmpz_num, bignum)) errno = ENOMEM, err(EXIT_FAILURE, "Couldn't init number"); vstr_del(s1, 1, s1->len); #if (EX_GMP_NUMS_USE_TST) { mpz_abs(bignum, bignum); mpz_neg(bignum, bignum); do { mpz_neg(bignum, bignum); vstr_add_fmt(s1, s1->len, "%%'20.40d = <$'20.40<dMPZ:%p>>\n", (void *)bignum); if (mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%'20.40d = <%'20.40ld>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%'40.20d = <$'40.20<dMPZ:%p>>\n", (void *)bignum); if (mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%'40.20d = <%'40.20ld>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%'20.40o = <$'20.40<oMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%'20.40o = <%'20.40lo>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%'40.20o = <$'40.20<oMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%'40.20o = <%'40.20lo>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%'20.40x = <$'20.40<xMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%'20.40x = <%'20.40lx>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%'40.20x = <$'40.20<xMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%'40.20x = <%'40.20lx>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%#'40d = <$#'40<dMPZ:%p>>\n", (void *)bignum); if (mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%#'40d = <%#'40ld>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%#'-40d = <$#'-40<dMPZ:%p>>\n", (void *)bignum); if (mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%#'-40d = <%#'-40ld>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%#'40o = <$#'40<oMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%#'40o = <%#'40lo>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%#'-40o = <$#'-40<oMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%#'-40o = <%#'-40lo>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%#'40x = <$#'40<xMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%#'40x = <%#'40lx>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%#'-40x = <$#'-40<xMPZ:%p>>\n", (void *)bignum); if ((mpz_sgn(bignum) != -1) && mpz_fits_slong_p(bignum)) vstr_add_fmt(s1, s1->len, "%%#'-40x = <%#'-40lx>\n", mpz_get_si(bignum)); vstr_add_fmt(s1, s1->len, "%%#'b = <$#'<bMPZ:%p>>\n", (void *)bignum); vstr_add_rep_chr(s1, s1->len, '-', 79); vstr_add_rep_chr(s1, s1->len, '\n', 1); } while (mpz_sgn(bignum) > 0); mpz_abs(bignum, bignum); } #endif if (!(ref = vstr_ref_make_strdup("_"))) errno = ENOMEM, err(EXIT_FAILURE, "Ref seperator"); if (!vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_LOC_REF_THOU_SEP, 2, ref, 1) || !vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_LOC_REF_THOU_SEP, 8, ref, 1) || !vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_LOC_REF_THOU_SEP, 16, ref, 1) || FALSE) errno = ENOMEM, err(EXIT_FAILURE, "Add seperator"); vstr_ref_del(ref); if (!(ref = vstr_ref_make_strdup("\4"))) errno = ENOMEM, err(EXIT_FAILURE, "Ref grouping"); if (!vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_LOC_REF_THOU_GRP, 2, ref) || !vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_LOC_REF_THOU_GRP, 16, ref) || FALSE) errno = ENOMEM, err(EXIT_FAILURE, "Add grouping"); vstr_ref_del(ref); vstr_add_fmt(s1, s1->len, " Input: %s\n", argv[1]); vstr_add_fmt(s1, s1->len, " %%#'x = $#'<xMPZ:%p>\n", (void *)bignum); vstr_add_fmt(s1, s1->len, " %%#'d = $#'<dMPZ:%p>\n", (void *)bignum); vstr_add_fmt(s1, s1->len, " %%#'o = $#'<oMPZ:%p>\n", (void *)bignum); vstr_add_fmt(s1, s1->len, " %%#'b = $#'<bMPZ:%p>\n", (void *)bignum); if (s1->conf->malloc_bad) errno = ENOMEM, err(EXIT_FAILURE, "Add string data"); io_put_all(s1, STDOUT_FILENO); exit (ex_exit(s1, NULL)); }
int main(int argc, char *argv[]) { Vstr_base *s1 = ex_init(NULL); mpz_t bignum; if (argc < 2) errx(EXIT_FAILURE, "No count specified"); vstr_cntl_conf(s1->conf, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '$'); if (!vstr_sc_fmt_add_vstr(s1->conf, "{vstr:%p%zu%zu%u}") || !vstr_fmt_add(s1->conf, "<words:%p>", ex_usr_words_cb, VSTR_TYPE_FMT_PTR_VOID, VSTR_TYPE_FMT_END)) errno = ENOMEM, err(EXIT_FAILURE, "Custom formatters"); #if EX_WORDS_USE_TST { struct Words_tst_conv { const char *i; const char *o; } tsts[] = { {"0", "Zero"}, {"1", "One"}, {"2", "Two"}, {"3", "Three"}, {"4", "Four"}, {"5", "Five"}, {"6", "Six"}, {"7", "Seven"}, {"8", "Eight"}, {"9", "Nine"}, {"10", "Ten"}, {"11", "Eleven"}, {"12", "Twelve"}, {"13", "Thirteen"}, {"14", "Fourteen"}, {"15", "Fifteen"}, {"16", "Sixteen"}, {"17", "Seventeen"}, {"18", "Eighteen"}, {"19", "Nineteen"}, {"20", "Twenty"}, {"21", "Twenty one"}, {"29", "Twenty nine"}, {"30", "Thirty"}, {"34", "Thirty four"}, {"40", "Forty"}, {"50", "Fifty"}, {"60", "Sixty"}, {"70", "Seventy"}, {"80", "Eighty"}, {"90", "Ninety"}, {"100", "One hundred"}, {"190", "One hundred and ninety"}, {"200", "Two hundred"}, {"1000", "One thousand"}, {"2000", "Two thousand"}, {"3210", "Three thousand two hundred and ten"}, {"9876543210", "Nine billion eight hundred and seventy six million five hundred and forty three thousand two hundred and ten"}, {"9876543210" VAL0_9(), "Nine quintillion eight hundred and seventy six quadrillion five hundred and forty three trillion two hundred and ten billion"}, {"-3210", "Minus three thousand two hundred and ten"}, }; unsigned int alen = sizeof(tsts) / sizeof(tsts[0]); struct Words_tst_conv *scan = tsts; while (alen) { mpz_init_set_str(bignum, scan->i, 0); vstr_del(s1, 1, s1->len); vstr_add_fmt(s1, s1->len, "$<words:%p>", (void *)bignum); if (!vstr_cmp_cstr_eq(s1, 1, s1->len, scan->o)) errx(EXIT_FAILURE, "Tst failed(%s): %s", scan->o, vstr_export_cstr_ptr(s1, 1, s1->len)); --alen; ++scan; } } #endif mpz_init_set_str(bignum, argv[1], 0); vstr_del(s1, 1, s1->len); vstr_add_fmt(s1, s1->len, " Input: %s\n", argv[1]); vstr_add_fmt(s1, s1->len, " Words: $<words:%p>\n", (void *)bignum); if (s1->conf->malloc_bad) errno = ENOMEM, err(EXIT_FAILURE, "Add string data"); io_put_all(s1, STDOUT_FILENO); exit (ex_exit(s1, NULL)); }
/* * Main loop for command mode command decoding. * A few commands are executed here, but main function * is to strip command addresses, do a little address oriented * processing and call command routines to do the real work. */ void commands(bool noprompt, bool exitoneof) { register line *addr; register int c; register int lchng; int given; int seensemi; int cnt; bool hadpr; resetflav(); nochng(); for (;;) { /* * If dot at last command * ended up at zero, advance to one if there is a such. */ if (dot <= zero) { dot = zero; if (dol > zero) dot = one; } shudclob = 0; /* * If autoprint or trailing print flags, * print the line at the specified offset * before the next command. */ if (pflag || (lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline)) { pflag = 0; nochng(); if (dol != zero) { addr1 = addr2 = dot + poffset; if (addr1 < one || addr1 > dol) error("Offset out-of-bounds|Offset after command too large"); setdot1(); goto print; } } nochng(); /* * Print prompt if appropriate. * If not in global flush output first to prevent * going into pfast mode unreasonably. */ if (inglobal == 0) { flush(); if (!hush && value(PROMPT) && !globp && !noprompt && endline) { ex_putchar(':'); hadpr = 1; } TSYNC(); } /* * Gobble up the address. * Degenerate addresses yield ".". */ addr2 = 0; given = seensemi = 0; do { addr1 = addr2; addr = address(0); c = getcd(); if (addr == 0) { if (c == ',') addr = dot; else if (addr1 != 0) { addr2 = dot; break; } else break; } addr2 = addr; given++; if (c == ';') { c = ','; dot = addr; seensemi = 1; } } while (c == ','); if (c == '%') { /* %: same as 1,$ */ addr1 = one; addr2 = dol; given = 2; c = ex_getchar(); } if (addr1 == 0) addr1 = addr2; if (c == ':') c = ex_getchar(); /* * Set command name for special character commands. */ tailspec(c); /* * If called via : escape from open or visual, limit * the set of available commands here to save work below. */ if (inopen) { if (c=='\n' || c=='\r' || c==CTRL('d') || c==EOF) { if (addr2) dot = addr2; if (c == EOF) return; continue; } if (any(c, "o")) notinvis: tailprim(Command, 1, 1); } switch (c) { case 'a': switch(peekchar()) { case 'b': /* abbreviate */ tail("abbreviate"); setnoaddr(); mapcmd(0, 1); anyabbrs = 1; continue; case 'r': /* args */ tail("args"); setnoaddr(); eol(); pargs(); continue; } /* append */ if (inopen) goto notinvis; tail("append"); setdot(); aiflag = exclam(); ex_newline(); vmacchng(0); deletenone(); setin(addr2); inappend = 1; ignore(append(gettty, addr2)); inappend = 0; nochng(); continue; case 'c': switch (peekchar()) { /* copy */ case 'o': tail("copy"); vmacchng(0); move(); continue; #ifdef CHDIR /* cd */ case 'd': tail("cd"); goto changdir; /* chdir */ case 'h': ignchar(); if (peekchar() == 'd') { register char *p; tail2of("chdir"); changdir: if (savedfile[0] == '/' || !value(WARN)) ignore(exclam()); else ignore(quickly()); if (skipend()) { p = getenv("HOME"); if (p == NULL) error("Home directory unknown"); } else getone(), p = file; eol(); if (chdir(p) < 0) filioerr(p); if (savedfile[0] != '/') edited = 0; continue; } if (inopen) tailprim("change", 2, 1); tail2of("change"); break; #endif default: if (inopen) goto notinvis; tail("change"); break; } /* change */ aiflag = exclam(); setCNL(); vmacchng(0); setin(addr1); delete(0); inappend = 1; ignore(append(gettty, addr1 - 1)); inappend = 0; nochng(); continue; /* delete */ case 'd': /* * Caution: dp and dl have special meaning already. */ tail("delete"); c = cmdreg(); setCNL(); vmacchng(0); if (c) YANKreg(c); delete(0); appendnone(); continue; /* edit */ /* ex */ case 'e': tail(peekchar() == 'x' ? "ex" : "edit"); editcmd: if (!exclam() && chng) c = 'E'; filename(c); if (c == 'E') { ungetchar(lastchar()); ignore(quickly()); } setnoaddr(); doecmd: init(); addr2 = zero; laste++; ex_sync(); rop(c); nochng(); continue; /* file */ case 'f': tail("file"); setnoaddr(); filename(c); noonl(); /* synctmp(); */ continue; /* global */ case 'g': tail("global"); global(!exclam()); nochng(); continue; /* insert */ case 'i': if (inopen) goto notinvis; tail("insert"); setdot(); nonzero(); aiflag = exclam(); ex_newline(); vmacchng(0); deletenone(); setin(addr2); inappend = 1; ignore(append(gettty, addr2 - 1)); inappend = 0; if (dot == zero && dol > zero) dot = one; nochng(); continue; /* join */ case 'j': tail("join"); c = exclam(); setcount(); nonzero(); ex_newline(); vmacchng(0); if (given < 2 && addr2 != dol) addr2++; join(c); continue; /* k */ case 'k': casek: pastwh(); c = ex_getchar(); if (endcmd(c)) serror("Mark what?|%s requires following letter", Command); ex_newline(); if (!islower(c)) error("Bad mark|Mark must specify a letter"); setdot(); nonzero(); names[c - 'a'] = *addr2 &~ 01; anymarks = 1; continue; /* list */ case 'l': tail("list"); setCNL(); ignorf(setlist(1)); pflag = 0; goto print; case 'm': if (peekchar() == 'a') { ignchar(); if (peekchar() == 'p') { /* map */ tail2of("map"); setnoaddr(); mapcmd(0, 0); continue; } /* mark */ tail2of("mark"); goto casek; } /* move */ tail("move"); vmacchng(0); move(); continue; case 'n': if (peekchar() == 'u') { tail("number"); goto numberit; } /* next */ tail("next"); setnoaddr(); ckaw(); ignore(quickly()); if (getargs()) makargs(); next(); c = 'e'; filename(c); goto doecmd; /* open */ case 'o': tail("open"); oop(); pflag = 0; nochng(); continue; case 'p': case 'P': switch (peekchar()) { /* put */ case 'u': tail("put"); setdot(); c = cmdreg(); eol(); vmacchng(0); if (c) putreg(c); else put(); continue; case 'r': ignchar(); if (peekchar() == 'e') { /* preserve */ tail2of("preserve"); eol(); if (preserve() == 0) error("Preserve failed!"); else error("File preserved."); } tail2of("print"); break; default: tail("print"); break; } /* print */ setCNL(); pflag = 0; print: nonzero(); if (CL && span() > EX_LINES) { flush1(); vclear(); } plines(addr1, addr2, 1); continue; /* quit */ case 'q': tail("quit"); setnoaddr(); c = quickly(); eol(); if (!c) quit: nomore(); if (inopen) { vgoto(WECHO, 0); if (!ateopr()) vnfl(); else { tostop(); } flush(); setty(normf); } cleanup(1); ex_exit(0); case 'r': if (peekchar() == 'e') { ignchar(); switch (peekchar()) { /* rewind */ case 'w': tail2of("rewind"); setnoaddr(); if (!exclam()) { ckaw(); if (chng && dol > zero) error("No write@since last chage (:rewind! overrides)"); } eol(); erewind(); next(); c = 'e'; ungetchar(lastchar()); filename(c); goto doecmd; /* recover */ case 'c': tail2of("recover"); setnoaddr(); c = 'e'; if (!exclam() && chng) c = 'E'; filename(c); if (c == 'E') { ungetchar(lastchar()); ignore(quickly()); } init(); addr2 = zero; laste++; ex_sync(); recover(); rop2(); revocer(); if (status == 0) rop3(c); if (dol != zero) change(); nochng(); continue; } tail2of("read"); } else tail("read"); /* read */ if (savedfile[0] == 0 && dol == zero) c = 'e'; pastwh(); vmacchng(0); if (peekchar() == '!') { setdot(); ignchar(); unix0(0); filter(0); continue; } filename(c); rop(c); nochng(); if (inopen && endline && addr1 > zero && addr1 < dol) dot = addr1 + 1; continue; case 's': switch (peekchar()) { /* * Caution: 2nd char cannot be c, g, or r * because these have meaning to substitute. */ /* set */ case 'e': tail("set"); setnoaddr(); set(); continue; /* shell */ case 'h': tail("shell"); setNAEOL(); vnfl(); putpad(TE); flush(); unixwt(1, unixex("-i", (char *) 0, 0, 0)); vcontin(0); continue; /* source */ case 'o': #ifdef notdef if (inopen) goto notinvis; #endif tail("source"); setnoaddr(); getone(); eol(); source(file, 0); continue; #ifdef SIGTSTP /* stop, suspend */ case 't': tail("stop"); goto suspend; case 'u': tail("suspend"); suspend: if (!dosusp) error("Old tty driver|Not using new tty driver/shell"); c = exclam(); eol(); if (!c) ckaw(); onsusp(0); continue; #endif } /* fall into ... */ /* & */ /* ~ */ /* substitute */ case '&': case '~': Command = "substitute"; if (c == 's') tail(Command); vmacchng(0); if (!substitute(c)) pflag = 0; continue; /* t */ case 't': if (peekchar() == 'a') { tail("tag"); tagfind(exclam()); if (!inopen) lchng = chng - 1; else nochng(); continue; } tail("t"); vmacchng(0); move(); continue; case 'u': if (peekchar() == 'n') { ignchar(); switch(peekchar()) { /* unmap */ case 'm': tail2of("unmap"); setnoaddr(); mapcmd(1, 0); continue; /* unabbreviate */ case 'a': tail2of("unabbreviate"); setnoaddr(); mapcmd(1, 1); anyabbrs = 1; continue; } /* undo */ tail2of("undo"); } else tail("undo"); setnoaddr(); markDOT(); c = exclam(); ex_newline(); undo(c); continue; case 'v': switch (peekchar()) { case 'e': /* version */ tail("version"); setNAEOL(); ex_printf("@(#) Version 3.6, 11/3/80" " (4.0BSD). git " "160803 14:24" +5); noonl(); continue; /* visual */ case 'i': tail("visual"); if (inopen) { c = 'e'; goto editcmd; } vop(); pflag = 0; nochng(); continue; } /* v */ tail("v"); global(0); nochng(); continue; /* write */ case 'w': c = peekchar(); tail(c == 'q' ? "wq" : "write"); wq: if (skipwh() && peekchar() == '!') { pofix(); ignchar(); setall(); unix0(0); filter(1); } else { setall(); wop(1); nochng(); } if (c == 'q') goto quit; continue; /* xit */ case 'x': tail("xit"); if (!chng) goto quit; c = 'q'; goto wq; /* yank */ case 'y': tail("yank"); c = cmdreg(); setcount(); eol(); vmacchng(0); if (c) YANKreg(c); else yank(); continue; /* z */ case 'z': zop(0); pflag = 0; continue; /* * */ /* @ */ case '*': case '@': c = ex_getchar(); if (c=='\n' || c=='\r') ungetchar(c); if (any(c, "@*\n\r")) c = lastmac; if (isupper(c)) c = tolower(c); if (!islower(c)) error("Bad register"); ex_newline(); setdot(); cmdmac(c); continue; /* | */ case '|': endline = 0; goto caseline; /* \n */ case '\n': endline = 1; caseline: notempty(); if (addr2 == 0) { if (UP != NOSTR && c == '\n' && !inglobal) c = CTRL('k'); if (inglobal) addr1 = addr2 = dot; else { if (dot == dol) error("At EOF|At end-of-file"); addr1 = addr2 = dot + 1; } } setdot(); nonzero(); if (seensemi) addr1 = addr2; ex_getline(*addr1); if (c == CTRL('k')) { flush1(); destline--; if (hadpr) shudclob = 1; } plines(addr1, addr2, 1); continue; /* " */ case '"': comment(); continue; /* # */ case '#': numberit: setCNL(); ignorf(setnumb(1)); pflag = 0; goto print; /* = */ case '=': ex_newline(); setall(); if (inglobal == 2) pofix(); ex_printf("%d", lineno(addr2)); noonl(); continue; /* ! */ case '!': if (addr2 != 0) { vmacchng(0); unix0(0); setdot(); filter(2); } else { unix0(1); pofix(); putpad(TE); flush(); unixwt(1, unixex("-c", uxb, 0, 0)); vclrech(1); /* vcontin(0); */ nochng(); } continue; /* < */ /* > */ case '<': case '>': for (cnt = 1; peekchar() == c; cnt++) ignchar(); setCNL(); vmacchng(0); shift(c, cnt); continue; /* ^D */ /* EOF */ case CTRL('d'): case EOF: if (exitoneof) { if (addr2 != 0) dot = addr2; return; } if (!isatty(0)) { if (intty) /* * Chtty sys call at UCB may cause a * input which was a tty to suddenly be * turned into /dev/null. */ onhup(0); return; } if (addr2 != 0) { setlastchar('\n'); putnl(); } if (dol == zero) { if (addr2 == 0) putnl(); notempty(); } ungetchar(EOF); zop(hadpr); continue; default: if (!isalpha(c)) break; ungetchar(c); tailprim("", 0, 0); } ierror("What?|Unknown command character '%c'", c); } }
/* * Main procedure. Process arguments and then * transfer control to the main command processing loop * in the routine commands. We are entered as either "ex", "edit", "vi" * or "view" and the distinction is made here. Actually, we are "vi" if * there is a 'v' in our name, "view" is there is a 'w', and "edit" if * there is a 'd' in our name. For edit we just diddle options; * for vi we actually force an early visual command. */ int main(int ac, char **av) { #ifndef VMUNIX char *erpath = EXSTRINGS; #endif register char *cp; register int c; bool recov = 0; bool ivis; bool itag = 0; bool fast = 0; #ifdef TRACE register char *tracef; #endif /* * Immediately grab the tty modes so that we wont * get messed up if an interrupt comes in quickly. */ gTTY(1); #ifndef USG3TTY normf = tty.sg_flags; #else normf = tty; #endif ppid = getpid(); /* * Defend against d's, v's, w's, and a's in directories of * path leading to our true name. */ av[0] = tailpath(av[0]); /* * Figure out how we were invoked: ex, edit, vi, view. */ ivis = any('v', av[0]); /* "vi" */ if (any('w', av[0])) /* "view" */ value(READONLY) = 1; if (any('d', av[0])) { /* "edit" */ value(OPEN) = 0; value(REPORT) = 1; value(MAGIC) = 0; } #ifndef VMUNIX /* * For debugging take files out of . if name is a.out. */ if (av[0][0] == 'a') erpath = tailpath(erpath); #endif /* * Open the error message file. */ draino(); #ifndef VMUNIX erfile = open(erpath+4, O_RDONLY); if (erfile < 0) { erfile = open(erpath, O_RDONLY); } #endif pstop(); /* * Initialize interrupt handling. */ oldhup = signal(SIGHUP, SIG_IGN); if (oldhup == SIG_DFL) signal(SIGHUP, onhup); oldquit = signal(SIGQUIT, SIG_IGN); ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL; if (signal(SIGTERM, SIG_IGN) == SIG_DFL) signal(SIGTERM, onhup); #ifdef SIGEMT if (signal(SIGEMT, SIG_IGN) == SIG_DFL) signal(SIGEMT, onemt); #endif /* * Initialize end of core pointers. * Normally we avoid breaking back to fendcore after each * file since this can be expensive (much core-core copying). * If your system can scatter load processes you could do * this as ed does, saving a little core, but it will probably * not often make much difference. */ #ifdef UNIX_SBRK fendcore = (line *) sbrk(0); endcore = fendcore - 2; #else # define LINELIMIT 0x8000 fendcore = malloc(LINELIMIT * sizeof(line *)); endcore = fendcore + LINELIMIT - 1; #endif /* * Process flag arguments. */ ac--, av++; while (ac && av[0][0] == '-') { c = av[0][1]; if (c == 0) { hush = 1; value(AUTOPRINT) = 0; fast++; } else switch (c) { case 'R': value(READONLY) = 1; break; #ifdef TRACE case 'T': if (av[0][2] == 0) tracef = "trace"; else { tracef = tttrace; tracef[8] = av[0][2]; if (tracef[8]) tracef[9] = av[0][3]; else tracef[9] = 0; } trace = fopen(tracef, "w"); if (trace == NULL) ex_printf("Trace create error\n"); setbuf(trace, tracbuf); break; #endif #ifdef LISPCODE case 'l': value(LISP) = 1; value(SHOWMATCH) = 1; break; #endif case 'r': recov++; break; case 't': if (ac > 1 && av[1][0] != '-') { ac--, av++; itag = 1; /* BUG: should check for too long tag. */ CP(lasttag, av[0]); } break; case 'v': ivis = 1; break; case 'w': defwind = 0; if (av[0][2] == 0) defwind = 3; else for (cp = &av[0][2]; isdigit((int)*cp); cp++) defwind = 10*defwind + *cp - '0'; break; #ifdef CRYPT case 'x': /* -x: encrypted mode */ xflag = 1; break; #endif default: smerror("Unknown option %s\n", av[0]); break; } ac--, av++; } #ifdef SIGTSTP if (!hush && signal(SIGTSTP, SIG_IGN) == SIG_DFL) signal(SIGTSTP, onsusp), dosusp++; #endif if (ac && av[0][0] == '+') { firstpat = &av[0][1]; ac--, av++; } #ifdef CRYPT if(xflag){ key = getpass(KEYPROMPT); kflag = crinit(key, perm); } #endif /* * If we are doing a recover and no filename * was given, then execute an exrecover command with * the -r option to type out the list of saved file names. * Otherwise set the remembered file name to the first argument * file name so the "recover" initial command will find it. */ if (recov) { if (ac == 0) { ppid = 0; setrupt(); execl(EXRECOVER, "exrecover", "-r", NULL); filioerr(EXRECOVER); ex_exit(1); } CP(savedfile, *av); av++, ac--; } /* * Initialize the argument list. */ argv0 = av; argc0 = ac; args0 = av[0]; erewind(); /* * Initialize a temporary file (buffer) and * set up terminal environment. Read user startup commands. */ if (setexit() == 0) { setrupt(); intty = isatty(0); value(PROMPT) = intty; if ((cp = getenv("SHELL"))) CP(shell, cp); if (fast || !intty) setterm("dumb"); else { gettmode(); if ((cp = getenv("TERM")) != 0 && *cp) setterm(cp); } } if (setexit() == 0 && !fast && intty) { if ((globp = getenv("EXINIT")) && *globp) commands(1,1); else { globp = 0; if ((cp = getenv("HOME")) != 0 && *cp) source(strcat(strcpy(genbuf, cp), "/.exrc"), 1); } } init(); /* moved after prev 2 chunks to fix directory option */ /* * Initial processing. Handle tag, recover, and file argument * implied next commands. If going in as 'vi', then don't do * anything, just set initev so we will do it later (from within * visual). */ if (setexit() == 0) { if (recov) globp = "recover"; else if (itag) globp = ivis ? "tag" : "tag|p"; else if (argc) globp = "next"; if (ivis) initev = globp; else if (globp) { inglobal = 1; commands(1, 1); inglobal = 0; } } /* * Vi command... go into visual. * Strange... everything in vi usually happens * before we ever "start". */ if (ivis) { /* * Don't have to be upward compatible with stupidity * of starting editing at line $. */ if (dol > zero) dot = one; globp = "visual"; if (setexit() == 0) commands(1, 1); } /* * Clear out trash in state accumulated by startup, * and then do the main command loop for a normal edit. * If you quit out of a 'vi' command by doing Q or ^\, * you also fall through to here. */ seenprompt = 1; ungetchar(0); globp = 0; initev = 0; setlastchar('\n'); setexit(); commands(0, 0); cleanup(1); return 0; }
fileinit() { register char *p; register int i, j; struct stat stbuf; if (tline == INCRMT * (HBLKS+2)) return; cleanup(0); if (tfile >= 0) close(tfile); tline = INCRMT * (HBLKS+2); blocks[0] = HBLKS; blocks[1] = HBLKS+1; blocks[2] = -1; dirtcnt = 0; iblock = -1; iblock2 = -1; oblock = -1; CP(tfname, svalue(DIRECTORY)); #ifndef vms if (stat(tfname, &stbuf)) #else goto vms_no_check_dir; #endif { dumbness: if (setexit() == 0) filioerr(tfname); else putNFL(); cleanup(1); ex_exit(1); } #ifndef vms if ((stbuf.st_mode & S_IFMT) != S_IFDIR) { errno = ENOTDIR; goto dumbness; } #else vms_no_check_dir: #endif ichanged = 0; ichang2 = 0; #ifndef vms ignore(strcat(tfname, "/ExXXXXX")); #else ignore(strcat(tfname, "ExXXXXX")); #endif for (p = strend(tfname), i = 5, j = getpid(); i > 0; i--, j /= 10) *--p = j % 10 | '0'; #ifdef vms ignore(strcat(tfname, ".txt.1")); unlink(tfname); #endif tfile = creat(tfname, 0600); if (tfile < 0) goto dumbness; #ifdef VMUNIX { extern stilinc; /* see below */ stilinc = 0; } #endif havetmp = 1; if (tfile >= 0) close(tfile); tfile = open(tfname, 2); if (tfile < 0) goto dumbness; #ifdef UNIX_SBRK /* brk((char *)fendcore); */ #endif }