예제 #1
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smopen()
{
  string c=cmd.getid();
  string p=cmd.getparms();

  if (c=="edit")
    term->vieweditor();
  if (c=="edit2") {
    if (note==0)
      return smerror("no edit window open");
    note->on_winotherAct_triggered();
  }
  if (c=="edit" || c=="edit2")
    return "";
  if (c!="tab") {
    return smerror("unrecognized sm command: open " + c);
  }
  term->vieweditor();
  if (p.empty())
    note->newtemp();
  else {
    QString f=s2q(smgetscript(p));
    if (!cfexist(f))
      return smerror("file not found: " + q2s(f));
    note->fileopen(f);
  }
  rc=-1;
  return i2s(note->editIndex());
}
예제 #2
0
void smfree(struct mempool *mp, void *ptr)
{
  struct memnode *mn, *pmn;
  if (!ptr)
    return;
  if (!(mn = find_mn(mp, ptr))) {
    smerror("SMALLOC: bad pointer passed to smfree()\n");
    return;
  }
  if (!mn->used) {
    smerror("SMALLOC: attempt to free the not allocated region (double-free)\n");
    return;
  }
  assert(mn->size > 0);
#if SM_COMMIT_SUPPORT
  if (mp->uncommit)
    mp->uncommit(mn->mem_area, mn->size);
#endif
  mn->used = 0;
  if (mn->next && !mn->next->used) {
    /* merge with next */
    assert(mn->next->mem_area >= mn->mem_area);
    mntruncate(mn, mn->size + mn->next->size);
  }
  pmn = mn->prev;
  if (pmn && !pmn->used) {
    /* merge with prev */
    assert(pmn->mem_area <= mn->mem_area);
    mntruncate(pmn, pmn->size + mn->size);
    mn = pmn;
  }
}
예제 #3
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smfocus()
{
  string p=cmd.getparms();
  if (p.empty())
    return smerror("sm focus needs additional parameters");
  if (p=="term")
    term->smact();
  else if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    if (note->editIndex()==-1)
      return "";
    note->activateWindow();
    note->raise();
    note->repaint();
  } else if (p=="edit2") {
    if (note2==0 || note2->editIndex()==-1)
      return smerror("No active edit2 window");
    setnote(note2);
    note->activateWindow();
    note->raise();
    note->repaint();
  } else
    return smerror("unrecognized sm command: focus " + p);
  return "";
}
예제 #4
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smsave()
{
  string p=cmd.getparms();
  if (note==0)
    return smerror("No active edit window");
  if (p.empty())
    return smerror("sm save parameter not given");
  if (p=="edit")
    return smsaveactive();
  if (p=="tabs")
    return smsaveall();
  return smerror("sm save parameter should be 'edit' or 'tabs': " + p);
}
예제 #5
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smgetwin(string p)
{
  rc=-2;
  if (p=="term")
    return smgetwin1(tedit);
  if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    return smgetwin2(note);
  }
  if (note2==0)
    return smerror("No active edit2 window");
  return smgetwin2(note2);
}
예제 #6
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smactive()
{
  string p=cmd.getparms();
  QStringList opt=qsplit(p);
  if (note==0 || note->editIndex()<0)
    return smerror ("No active edit window");
  if (opt[0]!="tab")
    return smerror ("unrecognized sm command parameters: " + p);
  int ndx=opt[1].toInt();
  if (ndx<0 || ndx>=note->count())
    return smerror ("invalid tab index: " + p);
  note->setindex(ndx);
  return "";
}
예제 #7
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smreplace()
{
  string c=cmd.getid();
  string p=cmd.getparms();
  if (note==0 || note->editIndex()<0)
    return smerror ("No active edit window");
  if (c!="edit")
    return smerror("unrecognized sm command: replace " + c);
  if (p.empty())
    return smerror("replace needs 2 parameters: edit filename");
  QString f=s2q(smgetscript(p));
  if (!cfexist(f))
    return smerror("file not found: " + q2s(f));
  note->filereplace(f);
  return"";
}
예제 #8
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string sm(string c)
{
  rc=0;
  if (c=="act")
    return smact();
  if (c=="active")
    return smactive();
  if (c=="close")
    return smclose();
  if (c=="focus")
    return smfocus();
  if (c=="font")
    return smfont();
  if (c=="get")
    return smget();
  if (c=="html")
    return smhtml();
  if (c=="new")
    return smopen();
  if (c=="open")
    return smopen();
  if (c=="profont")
    return smprofont();
  if (c=="replace")
    return smreplace();
  if (c=="save")
    return smsave();
  if (c=="set")
    return smset();
  else if (c=="prompt")
    return smprompt();
  cmd.getparms();
  return smerror("unrecognized sm command: " + c);
}
예제 #9
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smgettabs(QString p)
{
  Note *n;
  if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    n=note;
  } else if (p=="edit2") {
    if (note2==0)
      return smerror("No active edit2 window");
    n=note2;
  } else
    return smerror("sm get tabs needs edit or edit2 parameter");
  rc=-2;
  return n->gettabstate();
}
예제 #10
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smsetinputlog(string c,string q)
{
  if (c!="text")
    return smerror("unrecognized sm command: set inputlog " + c + "..." );
  dlog_set(s2q(q));
  return "";
}
예제 #11
0
int smget_area_size(struct mempool *mp, void *ptr)
{
  struct memnode *mn;
  if (!(mn = find_mn(mp, ptr))) {
    smerror("SMALLOC: bad pointer passed to smget_area_size()\n");
    return -1;
  }
  return mn->size;
}
예제 #12
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
// set vertical scroll
string smsetscroll(Bedit *e, string q)
{
  if (!e) return"";
  QList<int> s=qsl2intlist(qsplit(q));
  if (s.size()!= 1)
    return smerror("sm set scroll should have a single parameter of scroll size");
  e->settop(s[0]);
  return"";
}
예제 #13
0
void *smalloc(struct mempool *mp, size_t size)
{
  struct memnode *mn;
  if (!size) {
    smerror("SMALLOC: zero-sized allocation attempted\n");
    return NULL;
  }
  if (!(mn = smfind_free_area(mp, size))) {
    smerror("SMALLOC: Out Of Memory on alloc, requested=%zu\n", size);
    return NULL;
  }
#if SM_COMMIT_SUPPORT
  if (mp->commit && !mp->commit(mn->mem_area, size))
    return NULL;
#endif
  mn->used = 1;
  mntruncate(mn, size);
  assert(mn->size == size);
  memset(mn->mem_area, 0, size);
  return mn->mem_area;
}
예제 #14
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smset()
{
  string p=cmd.getid();
  if (p.empty())
    return smerror("sm set parameters not given");

  string c=cmd.getid();
  if (c.empty())
    return smerror("sm set " + p + " parameters not given");
  string q=cmd.getparms();

  if (p=="inputlog")
    return smsetinputlog(c,q);

  if (p=="term") {
    if (c=="text")
      return smsettext(p,q);
    if (c=="xywh")
      return smsetxywh(p,q);
    return smerror("command applies only to an edit window: " + c);
  }

  Bedit *e;

  if (p=="edit") {
    if (note==0)
      return smerror("No active edit window");
    e=(Bedit *)note->editPage();
  } else if (p=="edit2") {
    if (note2==0)
      return smerror("No active edit2 window");
    e=(Bedit *)note2->editPage();
  } else
    return smerror("unrecognized sm command: set " + p);

  if (e==0 && (c=="scroll" || c=="select" || c=="text"))
    return smerror("no edit window for sm command: set " + c);

  if (c=="scroll")
    return smsetscroll(e,q);
  if (c=="select")
    return smsetselect(e,q);
  if (c=="text")
    return smsettext(p,q);
  if (c=="xywh")
    return smsetxywh(p,q);

  return smerror("unrecognized sm command: set " + p + " " + q);
}
예제 #15
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smsetselect(Bedit *e, string q)
{
  if (!e) return"";
  QList<int> s=qsl2intlist(qsplit(q));
  if (s.size()!= 2)
    return smerror("sm set select should have begin and end parameters");
  int m=e->toPlainText().size();
  if (s[1]==-1) s[1]=m;
  s[1]=qMin(m,s[1]);
  s[0]=qMin(s[0],s[1]);
  e->setselect(s[0],s[1]-s[0]);
  return"";
}
예제 #16
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smclose()
{
  string c=cmd.getid();
  string p=cmd.getparms();
  if (c=="tab") {
    if (note==0 || note->editIndex()<0)
      return smerror ("No active edit window");
    int ndx=s2q(p).toInt();
    if (ndx<0 || ndx>=note->count())
      return smerror ("invalid tab index: " + p);
    note->tabclose(ndx);
  } else if (c=="edit") {
    if (note==0)
      return smerror ("No edit window");
    note->close();
  } else if (c=="edit2") {
    if (note2==0)
      return smerror ("No edit2 window");
    note2->close();
  } else
    return smerror ("unrecognized sm command parameters: " + p);
  return "";
}
예제 #17
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smget()
{
  string p=cmd.getparms();
  if (p.size()==0)
    return smerror("sm get needs additional parameters");
  if (p=="active")
    return smgetactive();
  if (p=="term" || p=="edit" || p=="edit2")
    return smgetwin(p);
  if (p=="termcwh")
    return smgettermcwh();
  if (p=="inputlog")
    return smgetinputlog();
  if (p=="xywh")
    return smgetxywh();
  QStringList s=qsplit(p);
  if (s[0]=="tabs") {
    if(s.size()<=1)
      return smerror("sm command requires another parameter: get tabs");
    else
      return smgettabs(s[1]);
  }
  return smerror("unrecognized sm command: get " + p);
}
예제 #18
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smprofont()
{
  string p=cmd.getparms();
  if (!p.empty()) {
    Font *fnt = new Font(p);
    if (fnt->error) {
      delete fnt;
      return smerror("unrecognized sm command: font " + p);
    } else {
      QApplication::setFont(fnt->font);
      delete fnt;
    }
  } else
    QApplication::setFont(config.DefProFont);
  return "";
}
예제 #19
0
static struct memnode *find_mn(struct mempool *mp, unsigned char *ptr)
{
  struct memnode *mn;
  if (!POOL_USED(mp)) {
    smerror("SMALLOC: unused pool passed\n");
    return NULL;
  }
  for (mn = &mp->mn; mn->next; mn = mn->next) {
    if (mn->mem_area > ptr)
      return NULL;
    if (mn->mem_area == ptr) {
      return mn;
    }
  }
  return NULL;
}
예제 #20
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string smfont()
{
  string p=cmd.getparms();
  if (!p.empty()) {
    Font *fnt = new Font(p);
    if (fnt->error) {
      delete fnt;
      return smerror("unrecognized sm command: font " + p);
    } else {
      config.Font=fnt->font;
      delete fnt;
      fontset(config.Font);
    }
  } else
    fontset(config.DefFont);
  return "";
}
예제 #21
0
void *smrealloc(struct mempool *mp, void *ptr, size_t size)
{
  struct memnode *mn, *pmn;
  if (!ptr)
    return smalloc(mp, size);
  if (!(mn = find_mn(mp, ptr))) {
    smerror("SMALLOC: bad pointer passed to smrealloc()\n");
    return NULL;
  }
  if (!mn->used) {
    smerror("SMALLOC: attempt to realloc the not allocated region\n");
    return NULL;
  }
  if (size == 0) {
    smfree(mp, ptr);
    return NULL;
  }
  if (size == mn->size)
    return ptr;
  if (size < mn->size) {
    /* shrink */
#if SM_COMMIT_SUPPORT
    if (mp->uncommit)
      mp->uncommit(mn->mem_area + size, mn->size - size);
#endif
    mntruncate(mn, size);
  } else {
    /* grow */
    struct memnode *nmn = mn->next;
    if (nmn && !nmn->used && mn->size + nmn->size >= size) {
      /* expand */
#if SM_COMMIT_SUPPORT
      if (mp->commit && !mp->commit(nmn->mem_area, size - mn->size))
        return NULL;
#endif
      memset(nmn->mem_area, 0, size - mn->size);
      mntruncate(mn, size);
    } else {
      pmn = mn->prev;
      if (pmn && !pmn->used && pmn->size + mn->size + (nmn->used ? 0 : nmn->size) >= size) {
        /* move */
#if SM_COMMIT_SUPPORT
        if (mp->commit) {
	  size_t psize = min(size, pmn->size);
	  if (!mp->commit(pmn->mem_area, psize))
            return NULL;
	  if (size > pmn->size + mn->size &&
		!mp->commit(nmn->mem_area, size - pmn->size - mn->size)) {
	    if (mp->uncommit)
	      mp->uncommit(pmn->mem_area, psize);
            return NULL;
	  }
        }
#endif
        pmn->used = 1;
        memmove(pmn->mem_area, mn->mem_area, mn->size);
        memset(pmn->mem_area + mn->size, 0, size - mn->size);
        mn->used = 0;
#if SM_COMMIT_SUPPORT
	if (size < pmn->size + mn->size) {
	  size_t overl = size > pmn->size ? size - pmn->size : 0;
	  if (mp->uncommit)
	    mp->uncommit(mn->mem_area + overl, mn->size - overl);
	}
#endif
        if (!nmn->used)
          mntruncate(mn, mn->size + nmn->size);
        mntruncate(pmn, size);
        return pmn->mem_area;
      } else {
        /* relocate */
        void *new_ptr = smalloc(mp, size);
        if (!new_ptr) {
          smerror("SMALLOC: Out Of Memory on realloc, requested=%zu\n", size);
          return NULL;
        }
        memcpy(new_ptr, mn->mem_area, mn->size);
        smfree(mp, mn->mem_area);
        return new_ptr;
      }
    }
  }
  assert(mn->size == size);
  return mn->mem_area;
}
예제 #22
0
파일: ex.c 프로젝트: n-t-roff/ex-2.2
/*
 * 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" or "vi"
 * and the distinction is made here.  Actually, we are "vi" if
 * there is a 'v' in our name, 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, setting the external initev so
 * the q command in visual doesn't give command mode.
 */
int
main(int ac, char **av)
{
#if 0
	char *erpath = EXSTRINGS;
#endif
	register char *cp;
	register int c;
	bool recov = 0;
	bool ivis = any('v', av[0]);
	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);
	normf = tty;

#if 0
	/*
	 * For debugging take files out of . if name is a.out.
	 * If a 'd' in our name, then set options for edit.
	 */
	if (av[0][0] == 'a')
		erpath += 9;
#endif
	if (ivis) {
		options[MAGIC].odefault = value(MAGIC) = 0;
		options[BEAUTIFY].odefault = value(BEAUTIFY) = 1;
	} else if (any('d', av[0])) {
		value(OPEN) = 0;
		value(REPORT) = 1;
		value(MAGIC) = 0;
	}

	/*
	 * Open the error message file.
	 */
	draino();
#if 0
	erfile = open(erpath, 0);
	if (erfile < 0) {
		flush();
		exit(1);
	}
#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);

	/*
	 * 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) {

#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 LISP
		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':
			globp = "";
			ivis = 1;
			break;

		default:
			smerror("Unknown option %s\n", av[0]);
			break;
		}
		ac--, av++;
	}
	if (ac && av[0][0] == '+') {
		firstln = getn(av[0] + 1);
		if (firstln == 0)
			firstln = 20000;
		ac--, av++;
	}

	/*
	 * 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) {
			die++;
			setrupt();
			execl(EXRECOVER, "exrecover", "-r", NULL);
			filioerr(EXRECOVER);
			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.
	 */
	init();
	if (setexit() == 0) {
		setrupt();
		intty = isatty(0);
		if (fast || !intty)
			setterm("dumb");
		else {
			gettmode();
			if ((cp = getenv("TERM")) != 0)
				setterm(cp);
			if ((cp = getenv("HOME")) != 0)
				source(strcat(strcpy(genbuf, cp), "/.exrc"), 1);
		}
	}

	/*
	 * 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.
	 */
	ungetchar(0);
	globp = 0;
	initev = 0;
	setlastchar('\n');
	setexit();
	commands(0, 0);
	cleanup(1);
	return 0;
}
예제 #23
0
파일: ex.c 프로젝트: 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;
}