Exemplo n.º 1
0
Arquivo: ex.c Projeto: n-t-roff/ex-3.6
/*
 * 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);
}
Exemplo n.º 2
0
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));
}
Exemplo n.º 3
0
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));
}
Exemplo n.º 4
0
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));
}
Exemplo n.º 5
0
/*
 * 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);
	}
}
Exemplo n.º 6
0
Arquivo: ex.c Projeto: n-t-roff/ex-3.6
/*
 * 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;
}
Exemplo n.º 7
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
}