Exemple #1
0
void gencond(Error_printer *err, Frag *frag, Node *n, int v)
{
	Node *f, *r;
	int end = 0;

	loop:	

	f = first(n);
	r = first(rest(n));
	n = rest(rest(n));

	if (f && r) { /* elif */
		int els = genbra(err, frag, f, 1); /* Branch if false */
		mklooplvl(frag, lvlSCOPE, 0, 0);
		if (v) {
			gen(err, frag, r);
			/* Value is still here, but we need to pop the lvlSCOPE */
			/* Value is put back at the branch target point: XXX */
			rmlooplvl(frag, lvlVALUE, 0, 0);
		} else
			genn(err, frag, r);
		rmlooplvl(frag, lvlSCOPE, 0, 0);
		emitc(frag, iBRA);
		if (end)
			addlist(frag, end, emitn(frag, 0));
		else
			end = emitn(frag, 0);
		/* Value is gone after the branch */
		setlist(frag, els, frag->code);
		goto loop;
	} else if (f) { /* else */
		mklooplvl(frag, lvlSCOPE, 0, 0);
		if (v) {
			gen(err, frag, f);
			rmlooplvl(frag, lvlVALUE, 0, 0);
		} else
			genn(err, frag, f);
		rmlooplvl(frag, lvlSCOPE, 0, 0);
		if (v) {
			mklooplvl(frag, lvlVALUE, 0, 0); /* here XXX */
		}
		setlist(frag, end, frag->code);
		return;
	} else { /* no else */
		if (v) {
			push_void(frag); /* or here XXX */
		}
		setlist(frag, end, frag->code);
		return;
	}
}
Exemple #2
0
int genelif(Error_printer *err, Frag *frag, Node * n, int v)
{
	switch (n->what) {
		case nEMPTY:
			return 0;
		case nIF: {
			int els = genbra(err, frag, n->l, 1);
			int rtval;
			mklooplvl(frag, lvlSCOPE, 0, 0);
			if (v)
				gen(err, frag, n->r);
			else
				genn(err, frag, n->r);
			rmlooplvl(frag, lvlSCOPE, 0, 0);
			emitc(frag, iBRA);
			rtval = emitn(frag, 0);
			setlist(frag, els, frag->code);
			return rtval;
		} case nSEMI: {
			if (n->r->what == nELSE && n->r->r->what == nIF) {
				int z = genelif(err, frag, n->l, v);
				if (!z)
					error_2(err, "\"%s\" %d: else without if", n->r->loc->name, n->r->loc->line);
				else
					addlist(frag, z, genelif(err, frag, n->r->r, v));
				return z;
			}
		}
	}
	if (v)
		gen(err, frag, n);
	else
		genn(err, frag, n);
	return 0;
}
Exemple #3
0
/*VARARGS2*/
void
vlprintf(char *cp, va_list ap)
{
	register int (*P)(int);

	P = setlist(1);
	vprintf(cp, ap);
	Putchar = P;
}
int main()
{
 char nlist[NMAX][CHMAX] ;//名詞リスト
 char vlist[NMAX][CHMAX] ;//動詞リスト
 int nnum,vnum ;//リストの項目数
 int i ;
 
 /*乱数の初期化*/
 srand(65535) ;
 /*名詞リストと動詞リストの読み込み*/
 nnum=setlist(nlist,NFILE) ;
 vnum=setlist(vlist,VFILE) ;

 for(i=0;i<50;++i){
  /*文の生成*/
  sentence(nlist,nnum,vlist,vnum) ;
  printf(".\n") ;
}
 return 0 ;
}
Exemple #5
0
void rmlooplvl(Frag *frag, int what, int cont, int brk)
{
	struct looplvl *ll = frag->looplvls;
	frag->looplvls = ll->next;
	if (what != ll->what) {
		printf("Expected level of type %d\n", what);
		printf("But we have this:\n");
		while (ll) {
			printf("  %d\n", ll->what);
			ll = ll->next;
		}
		abort();
	}
	if (ll->what == lvlLOOP) {
		setlist(frag, ll->cont, cont);
		setlist(frag, ll->brk, brk);
	}
	if (ll->what == lvlSCOPE)
		emitc(frag, iEND);
	if (ll->name)
		free(ll->name);
	free(ll);
}
Exemple #6
0
Pseudo *codegen(Error_printer *err, Node *n)
{
	Frag frag[1];

	init_frag(frag);

	gen(err, frag, n);

	emitc(frag, iSTASH);

	if (frag->rtn)
		setlist(frag, frag->rtn, frag->code);

	emitc(frag, iRTS);

	return frag->begcode;
}
Exemple #7
0
/* Process the class list from the caller. */
void
cl_sets(char *slist)
{
	char *list_ptr;

	/* If there is a list, process it; else skip it */
	if (slist && *slist) {
		list_ptr = qstrdup(slist);

		if (list_ptr && *list_ptr) {
			cl_NClasses = setlist(&cl_Classes, list_ptr);
			if (new_order)		/* if list order changed ... */
				/* ... tell the environment. */
				cl_putl("CLASSES", cl_Classes);
		}
	}
}
std::string	UpdateSpec::update() const {
	return std::for_each(begin(), end(), setlist());
}
vmain()
{
	register int c, cnt, i;
	char esave[TUBECOLS];
	char *oglobp;
	char d;
	line *addr;
	int ind, nlput;
	int shouldpo = 0;
	int onumber, olist, (*OPline)(), (*OPutchar)();

	vch_mac = VC_NOTINMAC;

	/*
	 * If we started as a vi command (on the command line)
	 * then go process initial commands (recover, next or tag).
	 */
	if (initev) {
		oglobp = globp;
		globp = initev;
		hadcnt = cnt = 0;
		i = tchng;
		addr = dot;
		goto doinit;
	}

	/*
	 * NB:
	 *
	 * The current line is always in the line buffer linebuf,
	 * and the cursor at the position cursor.  You should do
	 * a vsave() before moving off the line to make sure the disk
	 * copy is updated if it has changed, and a getDOT() to get
	 * the line back if you mung linebuf.  The motion
	 * routines in ex_vwind.c handle most of this.
	 */
	for (;;) {
		/*
		 * Decode a visual command.
		 * First sync the temp file if there has been a reasonable
		 * amount of change.  Clear state for decoding of next
		 * command.
		 */
		TSYNC();
		vglobp = 0;
		vreg = 0;
		hold = 0;
		seenprompt = 1;
		wcursor = 0;
		Xhadcnt = hadcnt = 0;
		Xcnt = cnt = 1;
		splitw = 0;
		if (i = holdupd) {
			if (state == VISUAL)
				ignore(peekkey());
			holdupd = 0;
/*
			if (LINE(0) < ZERO) {
				vclear();
				vcnt = 0;
				i = 3;
			}
*/
			if (state != VISUAL) {
				vcnt = 0;
				vsave();
				vrepaint(cursor);
			} else if (i == 3)
				vredraw(WTOP);
			else
				vsync(WTOP);
			vfixcurs();
		}

		/*
		 * Gobble up counts and named buffer specifications.
		 */
		for (;;) {
looptop:
#ifdef MDEBUG
			if (trace)
				fprintf(trace, "pc=%c",peekkey());
#endif
			if (isdigit(peekkey()) && peekkey() != '0') {
				hadcnt = 1;
				cnt = vgetcnt();
				forbid (cnt <= 0);
			}
			if (peekkey() != '"')
				break;
			ignore(getkey()), c = getkey();
			/*
			 * Buffer names be letters or digits.
			 * But not '0' as that is the source of
			 * an 'empty' named buffer spec in the routine
			 * kshift (see ex_temp.c).
			 */
			forbid (c == '0' || !isalpha(c) && !isdigit(c));
			vreg = c;
		}
reread:
		/*
		 * Come to reread from below after some macro expansions.
		 * The call to map allows use of function key pads
		 * by performing a terminal dependent mapping of inputs.
		 */
#ifdef MDEBUG
		if (trace)
			fprintf(trace,"pcb=%c,",peekkey());
#endif
		op = getkey();
		maphopcnt = 0;
		do {
			/*
			 * Keep mapping the char as long as it changes.
			 * This allows for double mappings, e.g., q to #,
			 * #1 to something else.
			 */
			c = op;
			op = map(c,arrows);
#ifdef MDEBUG
			if (trace)
				fprintf(trace,"pca=%c,",c);
#endif
			/*
			 * Maybe the mapped to char is a count. If so, we have
			 * to go back to the "for" to interpret it. Likewise
			 * for a buffer name.
			 */
			if ((isdigit(c) && c!='0') || c == '"') {
				ungetkey(c);
				goto looptop;
			}
			if (!value(REMAP)) {
				c = op;
				break;
			}
			if (++maphopcnt > 256)
				error("Infinite macro loop");
		} while (c != op);

		/*
		 * Begin to build an image of this command for possible
		 * later repeat in the buffer workcmd.  It will be copied
		 * to lastcmd by the routine setLAST
		 * if/when completely specified.
		 */
		lastcp = workcmd;
		if (!vglobp)
			*lastcp++ = c;

		/*
		 * First level command decode.
		 */
		switch (c) {

		/*
		 * ^L		Clear screen e.g. after transmission error.
		 */

		/*
		 * ^R		Retype screen, getting rid of @ lines.
		 *		If in open, equivalent to ^L.
		 *		On terminals where the right arrow key sends
		 *		^L we make ^R act like ^L, since there is no
		 *		way to get ^L.  These terminals (adm31, tvi)
		 *		are intelligent so ^R is useless.  Soroc
		 *		will probably foul this up, but nobody has
		 *		one of them.
		 */
		case CTRL(l):
		case CTRL(r):
			if (c == CTRL(l) || (KR && *KR==CTRL(l))) {
				vclear();
				vdirty(0, vcnt);
			}
			if (state != VISUAL) {
				/*
				 * Get a clean line, throw away the
				 * memory of what is displayed now,
				 * and move back onto the current line.
				 */
				vclean();
				vcnt = 0;
				vmoveto(dot, cursor, 0);
				continue;
			}
			vredraw(WTOP);
			/*
			 * Weird glitch -- when we enter visual
			 * in a very small window we may end up with
			 * no lines on the screen because the line
			 * at the top is too long.  This forces the screen
			 * to be expanded to make room for it (after
			 * we have printed @'s ick showing we goofed).
			 */
			if (vcnt == 0)
				vrepaint(cursor);
			vfixcurs();
			continue;

		/*
		 * $		Escape just cancels the current command
		 *		with a little feedback.
		 */
		case ESCAPE:
			beep();
			continue;

		/*
		 * @   		Macros. Bring in the macro and put it
		 *		in vmacbuf, point vglobp there and punt.
		 */
		 case '@':
			c = getesc();
			if (c == 0)
				continue;
			if (c == '@')
				c = lastmac;
			if (isupper(c))
				c = tolower(c);
			forbid(!islower(c));
			lastmac = c;
			vsave();
			CATCH
				char tmpbuf[BUFSIZ];

				regbuf(c,tmpbuf,sizeof(vmacbuf));
				macpush(tmpbuf, 1);
			ONERR
				lastmac = 0;
				splitw = 0;
				getDOT();
				vrepaint(cursor);
				continue;
			ENDCATCH
			vmacp = vmacbuf;
			goto reread;

		/*
		 * .		Repeat the last (modifying) open/visual command.
		 */
		case '.':
			/*
			 * Check that there was a last command, and
			 * take its count and named buffer unless they
			 * were given anew.  Special case if last command
			 * referenced a numeric named buffer -- increment
			 * the number and go to a named buffer again.
			 * This allows a sequence like "1pu.u.u...
			 * to successively look for stuff in the kill chain
			 * much as one does in EMACS with C-Y and M-Y.
			 */
			forbid (lastcmd[0] == 0);
			if (hadcnt)
				lastcnt = cnt;
			if (vreg)
				lastreg = vreg;
			else if (isdigit(lastreg) && lastreg < '9')
				lastreg++;
			vreg = lastreg;
			cnt = lastcnt;
			hadcnt = lasthad;
			vglobp = lastcmd;
			goto reread;

		/*
		 * ^U		Scroll up.  A count sticks around for
		 *		future scrolls as the scroll amount.
		 *		Attempt to hold the indentation from the
		 *		top of the screen (in logical lines).
		 *
		 * BUG:		A ^U near the bottom of the screen
		 *		on a dumb terminal (which can't roll back)
		 *		causes the screen to be cleared and then
		 *		redrawn almost as it was.  In this case
		 *		one should simply move the cursor.
		 */
		case CTRL(u):
			if (hadcnt)
				vSCROLL = cnt;
			cnt = vSCROLL;
			if (state == VISUAL)
				ind = vcline, cnt += ind;
			else
				ind = 0;
			vmoving = 0;
			vup(cnt, ind, 1);
			vnline(NOSTR);
			continue;

		/*
		 * ^D		Scroll down.  Like scroll up.
		 */
		case CTRL(d):
#ifdef TRACE
		if (trace)
			fprintf(trace, "before vdown in ^D, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol));
#endif
			if (hadcnt)
				vSCROLL = cnt;
			cnt = vSCROLL;
			if (state == VISUAL)
				ind = vcnt - vcline - 1, cnt += ind;
			else
				ind = 0;
			vmoving = 0;
			vdown(cnt, ind, 1);
#ifdef TRACE
		if (trace)
			fprintf(trace, "before vnline in ^D, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol));
#endif
			vnline(NOSTR);
#ifdef TRACE
		if (trace)
			fprintf(trace, "after vnline in ^D, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol));
#endif
			continue;

		/*
		 * ^E		Glitch the screen down (one) line.
		 *		Cursor left on same line in file.
		 */
		case CTRL(e):
			if (state != VISUAL)
				continue;
			if (!hadcnt)
				cnt = 1;
			/* Bottom line of file already on screen */
			forbid(lineDOL()-lineDOT() <= vcnt-1-vcline);
			ind = vcnt - vcline - 1 + cnt;
			vdown(ind, ind, 1);
			vnline(cursor);
			continue;

		/*
		 * ^Y		Like ^E but up
		 */
		case CTRL(y):
			if (state != VISUAL)
				continue;
			if (!hadcnt)
				cnt = 1;
			forbid(lineDOT()-1<=vcline); /* line 1 already there */
			ind = vcline + cnt;
			vup(ind, ind, 1);
			vnline(cursor);
			continue;


		/*
		 * m		Mark position in mark register given
		 *		by following letter.  Return is
		 *		accomplished via ' or `; former
		 *		to beginning of line where mark
		 *		was set, latter to column where marked.
		 */
		case 'm':
			/*
			 * Getesc is generally used when a character
			 * is read as a latter part of a command
			 * to allow one to hit rubout/escape to cancel
			 * what you have typed so far.  These characters
			 * are mapped to 0 by the subroutine.
			 */
			c = getesc();
			if (c == 0)
				continue;

			/*
			 * Markreg checks that argument is a letter
			 * and also maps ' and ` to the end of the range
			 * to allow '' or `` to reference the previous
			 * context mark.
			 */
			c = markreg(c);
			forbid (c == 0);
			vsave();
			names[c - 'a'] = (*dot &~ 01);
			ncols[c - 'a'] = cursor;
			anymarks = 1;
			continue;

		/*
		 * ^F		Window forwards, with 2 lines of continuity.
		 *		Count repeats.
		 */
		case CTRL(f):
			vsave();
			if (vcnt > 2) {
				addr = dot + (vcnt - vcline) - 2 + (cnt-1)*basWLINES;
				forbid(addr > dol);
				dot = addr;
				vcnt = vcline = 0;
			}
			vzop(0, 0, '+');
			continue;

		/*
		 * ^B		Window backwards, with 2 lines of continuity.
		 *		Inverse of ^F.
		 */
		case CTRL(b):
			vsave();
			if (one + vcline != dot && vcnt > 2) {
				addr = dot - vcline - 2 + (cnt-1)*basWLINES;
				forbid (addr <= zero);
				dot = addr;
				vcnt = vcline = 0;
			}
			vzop(0, 0, '^');
			continue;

		/*
		 * z		Screen adjustment, taking a following character:
		 *			z<CR>		current line to top
		 *			z<NL>		like z<CR>
		 *			z-		current line to bottom
		 *		also z+, z^ like ^F and ^B.
		 *		A preceding count is line to use rather
		 *		than current line.  A count between z and
		 *		specifier character changes the screen size
		 *		for the redraw.
		 *
		 */
		case 'z':
			if (state == VISUAL) {
				i = vgetcnt();
				if (i > 0)
					vsetsiz(i);
				c = getesc();
				if (c == 0)
					continue;
			}
			vsave();
			vzop(hadcnt, cnt, c);
			continue;

		/*
		 * Y		Yank lines, abbreviation for y_ or yy.
		 *		Yanked lines can be put later if no
		 *		changes intervene, or can be put in named
		 *		buffers and put anytime in this session.
		 */
		case 'Y':
			ungetkey('_');
			c = 'y';
			break;

		/*
		 * J		Join lines, 2 by default.  Count is number
		 *		of lines to join (no join operator sorry.)
		 */
		case 'J':
			forbid (dot == dol);
			if (cnt == 1)
				cnt = 2;
			if (cnt > (i = dol - dot + 1))
				cnt = i;
			vsave();
			vmacchng(1);
			setLAST();
			cursor = strend(linebuf);
			vremote(cnt, join, 0);
			notenam = "join";
			vmoving = 0;
			killU();
			vreplace(vcline, cnt, 1);
			if (!*cursor && cursor > linebuf)
				cursor--;
			if (notecnt == 2)
				notecnt = 0;
			vrepaint(cursor);
			continue;

		/*
		 * S		Substitute text for whole lines, abbrev for c_.
		 *		Count is number of lines to change.
		 */
		case 'S':
			ungetkey('_');
			c = 'c';
			break;

		/*
		 * O		Create a new line above current and accept new
		 *		input text, to an escape, there.
		 *		A count specifies, for dumb terminals when
		 *		slowopen is not set, the number of physical
		 *		line space to open on the screen.
		 *
		 * o		Like O, but opens lines below.
		 */
		case 'O':
		case 'o':
			vmacchng(1);
			voOpen(c, cnt);
			continue;

		/*
		 * C		Change text to end of line, short for c$.
		 */
		case 'C':
			if (*cursor) {
				ungetkey('$'), c = 'c';
				break;
			}
			goto appnd;

		/*
		 * ~	Switch case of letter under cursor
		 */
		case '~':
			{
				char mbuf[4];
				setLAST();
				mbuf[0] = 'r';
				mbuf[1] = *cursor;
				mbuf[2] = cursor[1]==0 ? 0 : ' ';
				mbuf[3] = 0;
				if (isalpha(mbuf[1]))
					mbuf[1] ^= ' ';	/* toggle the case */
				macpush(mbuf, 1);
			}
			continue;


		/*
		 * A		Append at end of line, short for $a.
		 */
		case 'A':
			operate('$', 1);
appnd:
			c = 'a';
			/* fall into ... */

		/*
		 * a		Appends text after cursor.  Text can continue
		 *		through arbitrary number of lines.
		 */
		case 'a':
			if (*cursor) {
				if (state == HARDOPEN)
					putchar(*cursor);
				cursor++;
			}
			goto insrt;

		/*
		 * I		Insert at beginning of whitespace of line,
		 *		short for ^i.
		 */
		case 'I':
			operate('^', 1);
			c = 'i';
			/* fall into ... */

		/*
		 * R		Replace characters, one for one, by input
		 *		(logically), like repeated r commands.
		 *
		 * BUG:		This is like the typeover mode of many other
		 *		editors, and is only rarely useful.  Its
		 *		implementation is a hack in a low level
		 *		routine and it doesn't work very well, e.g.
		 *		you can't move around within a R, etc.
		 */
		case 'R':
			/* fall into... */

		/*
		 * i		Insert text to an escape in the buffer.
		 *		Text is arbitrary.  This command reminds of
		 *		the i command in bare teco.
		 */
		case 'i':
insrt:
			/*
			 * Common code for all the insertion commands.
			 * Save for redo, position cursor, prepare for append
			 * at command and in visual undo.  Note that nothing
			 * is doomed, unless R when all is, and save the
			 * current line in a the undo temporary buffer.
			 */
			vmacchng(1);
			setLAST();
			vcursat(cursor);
			prepapp();
			vnoapp();
			doomed = c == 'R' ? 10000 : 0;
			if(FIXUNDO)
				vundkind = VCHNG;
			vmoving = 0;
			CP(vutmp, linebuf);

			/*
			 * If this is a repeated command, then suppress
			 * fake insert mode on dumb terminals which looks
			 * ridiculous and wastes lots of time even at 9600B.
			 */
			if (vglobp)
				hold = HOLDQIK;
			vappend(c, cnt, 0);
			continue;

		/*
		 * ^?		An attention, normally a ^?, just beeps.
		 *		If you are a vi command within ex, then
		 *		two ATTN's will drop you back to command mode.
		 */
		case ATTN:
			beep();
			if (initev || peekkey() != ATTN)
				continue;
			/* fall into... */

		/*
		 * ^\		A quit always gets command mode.
		 */
		case QUIT:
			/*
			 * Have to be careful if we were called
			 *	g/xxx/vi
			 * since a return will just start up again.
			 * So we simulate an interrupt.
			 */
			if (inglobal)
				onintr();
			/* fall into... */

#ifdef notdef
		/*
		 * q		Quit back to command mode, unless called as
		 *		vi on command line in which case dont do it
		 */
		case 'q':	/* quit */
			if (initev) {
				vsave();
				CATCH
					error("Q gets ex command mode, :q leaves vi");
				ENDCATCH
				splitw = 0;
				getDOT();
				vrepaint(cursor);
				continue;
			}
#endif
			/* fall into... */

		/*
		 * Q		Is like q, but always gets to command mode
		 *		even if command line invocation was as vi.
		 */
		case 'Q':
			vsave();
			/*
			 * If we are in the middle of a macro, throw away
			 * the rest and fix up undo.
			 * This code copied from getbr().
			 */
			if (vmacp) {
				vmacp = 0;
				if (inopen == -1)	/* don't screw up undo for esc esc */
					vundkind = VMANY;
				inopen = 1;	/* restore old setting now that macro done */
			}
			return;


		/*
		 * ZZ		Like :x
		 */
		 case 'Z':
			forbid(getkey() != 'Z');
			oglobp = globp;
			globp = "x";
			vclrech(0);
			goto gogo;
			
		/*
		 * P		Put back text before cursor or before current
		 *		line.  If text was whole lines goes back
		 *		as whole lines.  If part of a single line
		 *		or parts of whole lines splits up current
		 *		line to form many new lines.
		 *		May specify a named buffer, or the delete
		 *		saving buffers 1-9.
		 *
		 * p		Like P but after rather than before.
		 */
		case 'P':
		case 'p':
			vmoving = 0;
#ifdef notdef
			forbid (!vreg && value(UNDOMACRO) && inopen < 0);
#endif
			/*
			 * If previous delete was partial line, use an
			 * append or insert to put it back so as to
			 * use insert mode on intelligent terminals.
			 */
			if (!vreg && DEL[0]) {
				forbid ((DEL[0] & (QUOTE|TRIM)) == OVERBUF);
				vglobp = DEL;
				ungetkey(c == 'p' ? 'a' : 'i');
				goto reread;
			}

			/*
			 * If a register wasn't specified, then make
			 * sure there is something to put back.
			 */
			forbid (!vreg && unddol == dol);
			/*
			 * If we just did a macro the whole buffer is in
			 * the undo save area.  We don't want to put THAT.
			 */
			forbid (vundkind == VMANY && undkind==UNDALL);
			vsave();
			vmacchng(1);
			setLAST();
			i = 0;
			if (vreg && partreg(vreg) || !vreg && pkill[0]) {
				/*
				 * Restoring multiple lines which were partial
				 * lines; will leave cursor in middle
				 * of line after shoving restored text in to
				 * split the current line.
				 */
				i++;
				if (c == 'p' && *cursor)
					cursor++;
			} else {
				/*
				 * In whole line case, have to back up dot
				 * for P; also want to clear cursor so
				 * cursor will eventually be positioned
				 * at the beginning of the first put line.
				 */
				cursor = 0;
				if (c == 'P') {
					dot--, vcline--;
					c = 'p';
				}
			}
			killU();

			/*
			 * The call to putreg can potentially
			 * bomb since there may be nothing in a named buffer.
			 * We thus put a catch in here.  If we didn't and
			 * there was an error we would end up in command mode.
			 */
			addr = dol;	/* old dol */
			CATCH
				vremote(1, vreg ? putreg : put, vreg);
			ONERR
				if (vreg == -1) {
					splitw = 0;
					if (op == 'P')
						dot++, vcline++;
					goto pfixup;
				}
			ENDCATCH
			splitw = 0;
			nlput = dol - addr + 1;
			if (!i) {
				/*
				 * Increment undap1, undap2 to make up
				 * for their incorrect initialization in the
				 * routine vremote before calling put/putreg.
				 */
				if (FIXUNDO)
					undap1++, undap2++;
				vcline++;
				nlput--;

				/*
				 * After a put want current line first line,
				 * and dot was made the last line put in code
				 * run so far.  This is why we increment vcline
				 * above and decrease dot here.
				 */
				dot -= nlput - 1;
			}
#ifdef TRACE
			if (trace)
				fprintf(trace, "vreplace(%d, %d, %d), undap1=%d, undap2=%d, dot=%d\n", vcline, i, nlput, lineno(undap1), lineno(undap2), lineno(dot));
#endif
			vreplace(vcline, i, nlput);
			if (state != VISUAL) {
				/*
				 * Special case in open mode.
				 * Force action on the screen when a single
				 * line is put even if it is identical to
				 * the current line, e.g. on YP; otherwise
				 * you can't tell anything happened.
				 */
				vjumpto(dot, cursor, '.');
				continue;
			}
pfixup:
			vrepaint(cursor);
			vfixcurs();
			continue;

		/*
		 * ^^		Return to previous file.
		 *		Like a :e #, and thus can be used after a
		 *		"No Write" diagnostic.
		 */
		case CTRL(^):
			forbid (hadcnt);
			vsave();
			ckaw();
			oglobp = globp;
			if (value(AUTOWRITE))
				globp = "e! #";
			else
				globp = "e #";
			goto gogo;

		/*
		 * ^]		Takes word after cursor as tag, and then does
		 *		tag command.  Read ``go right to''.
		 */
		case CTRL(]):
			grabtag();
			oglobp = globp;
			globp = "tag";
			goto gogo;

		/*
		 * &		Like :&
		 */
		 case '&':
			oglobp = globp;
			globp = "&";
			goto gogo;
			
		/*
		 * ^G		Bring up a status line at the bottom of
		 *		the screen, like a :file command.
		 *
		 * BUG:		Was ^S but doesn't work in cbreak mode
		 */
		case CTRL(g):
			oglobp = globp;
			globp = "file";
gogo:
			addr = dot;
			vsave();
			goto doinit;

#ifdef SIGTSTP
		/*
		 * ^Z:	suspend editor session and temporarily return
		 * 	to shell.  Only works with Berkeley/IIASA process
		 *	control in kernel.
		 */
		case CTRL(z):
			forbid(dosusp == 0 || !ldisc);
			vsave();
			oglobp = globp;
			globp = "stop";
			goto gogo;
#endif

		/*
		 * :		Read a command from the echo area and
		 *		execute it in command mode.
		 */
		case ':':
			forbid (hadcnt);
			vsave();
			i = tchng;
			addr = dot;
			if (readecho(c)) {
				esave[0] = 0;
				goto fixup;
			}
			getDOT();
			/*
			 * Use the visual undo buffer to store the global
			 * string for command mode, since it is idle right now.
			 */
			oglobp = globp; strcpy(vutmp, genbuf+1); globp = vutmp;
doinit:
			esave[0] = 0;
			fixech();

			/*
			 * Have to finagle around not to lose last
			 * character after this command (when run from ex
			 * command mode).  This is clumsy.
			 */
			d = peekc; ungetchar(0);
			if (shouldpo) {
				/*
				 * So after a "Hit return..." ":", we do
				 * another "Hit return..." the next time
				 */
				pofix();
				shouldpo = 0;
			}
			CATCH
				/*
				 * Save old values of options so we can
				 * notice when they change; switch into
				 * cooked mode so we are interruptible.
				 */
				onumber = value(NUMBER);
				olist = value(LIST);
				OPline = Pline;
				OPutchar = Putchar;
#ifndef CBREAK
				vcook();
#endif
				commands(1, 1);
				if (dot == zero && dol > zero)
					dot = one;
#ifndef CBREAK
				vraw();
#endif
			ONERR
#ifndef CBREAK
				vraw();
#endif
				copy(esave, vtube[WECHO], TUBECOLS);
			ENDCATCH
			fixol();
			Pline = OPline;
			Putchar = OPutchar;
			ungetchar(d);
			globp = oglobp;

			/*
			 * If we ended up with no lines in the buffer, make
			 * a line, and don't consider the buffer changed.
			 */
			if (dot == zero) {
				fixzero();
				sync();
			}
			splitw = 0;

			/*
			 * Special case: did list/number options change?
			 */
			if (onumber != value(NUMBER))
				setnumb(value(NUMBER));
			if (olist != value(LIST))
				setlist(value(LIST));

fixup:
			/*
			 * If a change occurred, other than
			 * a write which clears changes, then
			 * we should allow an undo even if .
			 * didn't move.
			 *
			 * BUG: You can make this wrong by
			 * tricking around with multiple commands
			 * on one line of : escape, and including
			 * a write command there, but its not
			 * worth worrying about.
			 */
			if (FIXUNDO && tchng && tchng != i)
				vundkind = VMANY, cursor = 0;

			/*
			 * If we are about to do another :, hold off
			 * updating of screen.
			 */
			if (vcnt < 0 && Peekkey == ':') {
				getDOT();
				shouldpo = 1;
				continue;
			}
			shouldpo = 0;

			/*
			 * In the case where the file being edited is
			 * new; e.g. if the initial state hasn't been
			 * saved yet, then do so now.
			 */
			if (unddol == truedol) {
				vundkind = VNONE;
				Vlines = lineDOL();
				if (!inglobal)
					savevis();
				addr = zero;
				vcnt = 0;
				if (esave[0] == 0)
					copy(esave, vtube[WECHO], TUBECOLS);
			}

			/*
			 * If the current line moved reset the cursor position.
			 */
			if (dot != addr) {
				vmoving = 0;
				cursor = 0;
			}

			/*
			 * If current line is not on screen or if we are
			 * in open mode and . moved, then redraw.
			 */
			i = vcline + (dot - addr);
			if (i < 0 || i >= vcnt && i >= -vcnt || state != VISUAL && dot != addr) {
				if (state == CRTOPEN)
					vup1();
				if (vcnt > 0)
					vcnt = 0;
				vjumpto(dot, (char *) 0, '.');
			} else {
				/*
				 * Current line IS on screen.
				 * If we did a [Hit return...] then
				 * restore vcnt and clear screen if in visual
				 */
				vcline = i;
				if (vcnt < 0) {
					vcnt = -vcnt;
					if (state == VISUAL)
						vclear();
					else if (state == CRTOPEN) {
						vcnt = 0;
					}
				}

				/*
				 * Limit max value of vcnt based on $
				 */
				i = vcline + lineDOL() - lineDOT() + 1;
				if (i < vcnt)
					vcnt = i;
				
				/*
				 * Dirty and repaint.
				 */
				vdirty(0, LINES);
				vrepaint(cursor);
			}

			/*
			 * If in visual, put back the echo area
			 * if it was clobberred.
			 */
			if (state == VISUAL) {
				int sdc = destcol, sdl = destline;

				splitw++;
				vigoto(WECHO, 0);
				for (i = 0; i < TUBECOLS - 1; i++) {
					if (esave[i] == 0)
						break;
					vputchar(esave[i]);
				}
				splitw = 0;
				vgoto(sdl, sdc);
			}
			continue;

		/*
		 * u		undo the last changing command.
		 */
		case 'u':
			vundo(1);
			continue;

		/*
		 * U		restore current line to initial state.
		 */
		case 'U':
			vUndo();
			continue;

fonfon:
			beep();
			vmacp = 0;
			inopen = 1;	/* might have been -1 */
			continue;
		}

		/*
		 * Rest of commands are decoded by the operate
		 * routine.
		 */
		operate(c, cnt);
	}
}
Exemple #10
0
int execute(TREPTR argt, int execflg, int *pf1, int *pf2)
{
	/* `stakbot' is preserved by this routine */
	register TREPTR t;
	STKPTR sav = savstak();

	sigchk();

	if ((t = argt) && execbrk == 0) {
		register int treeflgs;
		int oldexit, type;
		register char **com;

		treeflgs = t->tretyp;
		type = treeflgs & COMMSK;
		oldexit = exitval;
		exitval = 0;

		switch (type) {

		case TCOM:
			{
				STRING a1;
				int argn, internal;
				ARGPTR schain = gchain;
				IOPTR io = t->treio;
				gchain = 0;
				argn = getarg((void *)t);/*FIXME*/
				com = scan(argn);
				a1 = com[1];
				gchain = schain;

				if ((internal = syslook(com[0], commands)) || argn == 0)
					setlist(((COMPTR) t)->comset, 0);

				if (argn && (flags & noexec) == 0) {	/* print command if execpr */
					if (flags & execpr) {
						argn = 0;
						prs(execpmsg);
						while (com[argn] != ENDARGS) {
							prs(com[argn++]);
							blank();
						}
						newline();
					}

					switch (internal) {

					case SYSDOT:
						if (a1) {
							register int f;

							if ((f = pathopen(getpath(a1), a1)) < 0)
								failed(a1, notfound);
							else
								execexp(0, f);
						}
						break;

					case SYSTIMES:
					{
						struct tms t;
						times(&t);
						prt(t.tms_cutime);
						blank();
						prt(t.tms_cstime);
						newline();
					}
					break;

					case SYSEXIT:
						exitsh(a1 ? stoi(a1) : oldexit);

					case SYSNULL:
						io = 0;
						break;

					case SYSCONT:
						execbrk = -loopcnt;
						break;

					case SYSBREAK:
						if ((execbrk = loopcnt) && a1)
							breakcnt = stoi(a1);
						break;

					case SYSTRAP:
						if (a1) {
							BOOL clear;
							if ((clear = digit(*a1)) == 0)
								++com;
							while (*++com) {
								int i;
								if ((i = stoi(*com)) >= MAXTRAP || i < MINTRAP)
									failed(*com, badtrap);
								else if (clear)
									clrsig(i);
								else {
									replace(&trapcom[i], a1);
									if (*a1)
										getsig(i);
									else
										ignsig(i);
								}
							}
						} else {	/* print out current traps */
							int i;

							for (i = 0; i < MAXTRAP; i++) {
								if (trapcom[i]) {
									prn(i);
									prs(colon);
									prs(trapcom[i]);
									newline();
								}
							}
						}
						break;

					case SYSEXEC:
						com++;
						initio(io);
						ioset = 0;
						io = 0;
						if (a1 == 0)
							break;

					case SYSLOGIN:
						flags |= forked;
						oldsigs();
						execa((const char **)com);
						done();

					case SYSCD:
						if (flags & rshflg)
							failed(com[0], restricted);
						else if ((a1 == 0 && (a1 = (char *)homenod.namval) == 0) || chdir(a1) < 0) /* FIXME */
							failed(a1, baddir);
						break;

					case SYSSHFT:
						if (dolc < 1)
							error(badshift);
						else {
							dolv++;
							dolc--;
						}
						assnum(&dolladr, dolc);
						break;

					case SYSWAIT:
						await(-1);
						break;

					case SYSREAD:
						exitval = readvar(&com[1]);
						break;

/*
				case SYSTST:
					exitval=testcmd(com);
					break;
*/

					case SYSSET:
						if (a1) {
							int argc;
							argc = options(argn, (const char **)com);
							if (argc > 1)
								setargs((const char **)com + argn - argc);
						} else if (((COMPTR) t)->comset == 0)
						        /* Scan name chain and print */
							namscan(printnam);
						break;

					case SYSRDONLY:
						exitval = N_RDONLY;
					case SYSXPORT:
						if (exitval == 0)
							exitval = N_EXPORT;;

						if (a1) {
							while (*++com)
								attrib(lookup(*com), exitval);
						} else {
							namscan(printflg);
						}
						exitval = 0;
						break;

					case SYSEVAL:
						if (a1)
							execexp(a1, (UFD)&com[2]);	/* FIXME */
						break;

					case SYSUMASK:
						if (a1) {
							int c, i;
							i = 0;
							while ((c = *a1++) >= '0' && c <= '7')
								i = (i << 3) + c - '0';
							umask(i);
						} else {
							int i, j;
							umask(i = umask(0));
							prc('0');
							for (j = 6; j >= 0; j -= 3)
								prc(((i >> j) & 07) + '0');
							newline();
						}
						break;

					default:
						internal = builtin(argn, com);

					}

					if (internal) {
						if (io)
							error(illegal);
						chktrap();
						break;
					}
				} else if (t->treio == 0)
					break;
			}

		case TFORK:
			if (execflg && (treeflgs & (FAMP | FPOU)) == 0)
				parent = 0;
			else {
				while ((parent = fork()) == -1) {
					sigchk();
					alarm(10);
					pause();
				}
			}

			if (parent) {	/* This is the parent branch of fork;    */
				/* it may or may not wait for the child. */
				if (treeflgs & FPRS && flags & ttyflg) {
					prn(parent);
					newline();
				}
				if (treeflgs & FPCL)
					closepipe(pf1);
				if ((treeflgs & (FAMP | FPOU)) == 0)
					await(parent);
				else if ((treeflgs & FAMP) == 0)
					post(parent);
				else
					assnum(&pcsadr, parent);

				chktrap();
				break;
			} else {	/* this is the forked branch (child) of execute */
				flags |= forked;
				iotemp = 0;
				postclr();
				settmp();

				/* Turn off INTR and QUIT if `FINT'  */
				/* Reset ramaining signals to parent */
				/* except for those `lost' by trap   */
				oldsigs();
				if (treeflgs & FINT) {
					signal(INTR, SIG_IGN);
					signal(QUIT, SIG_IGN);
				}

				/* pipe in or out */
				if (treeflgs & FPIN) {
					sh_rename(pf1[INPIPE], 0);
					close(pf1[OTPIPE]);
				}
				if (treeflgs & FPOU) {
					sh_rename(pf2[OTPIPE], 1);
					close(pf2[INPIPE]);
				}

				/* default std input for & */
				if (treeflgs & FINT && ioset == 0)
					sh_rename(chkopen(devnull), 0);

				/* io redirection */
				initio(t->treio);
				if (type != TCOM)
					execute(((FORKPTR) t)->forktre, 1, NULL, NULL);
				else if (com[0] != ENDARGS) {
					setlist(((COMPTR) t)->comset, N_EXPORT);
					execa((const char **)com);
				}
				done();
			}

		case TPAR:
			sh_rename(dup(2), output);
			execute(((PARPTR) t)->partre, execflg, NULL, NULL);
			done();

		case TFIL:
		{
			int pv[2];
			chkpipe(pv);
			if (execute(((LSTPTR) t)->lstlef, 0, pf1, pv) == 0)
				execute(((LSTPTR) t)->lstrit, execflg, pv, pf2);
			else
				closepipe(pv);
			break;
                }
		case TLST:
			execute(((LSTPTR) t)->lstlef, 0, NULL, NULL);
			execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL);
			break;

		case TAND:
			if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) == 0)
				execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL);
			break;

		case TORF:
			if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) != 0)
				execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL);
			break;

		case TFOR:
		{
			NAMPTR n = lookup(((FORPTR) t)->fornam);
			char **args;
			DOLPTR argsav = 0;

			if (((FORPTR) t)->forlst == 0) {
				args = (char **)dolv + 1;
				argsav = useargs();
			} else {
				ARGPTR schain = gchain;
				gchain = 0;
				trim((args = scan(getarg(((FORPTR) t)->forlst)))[0]);
				gchain = schain;
			}
			loopcnt++;
			while (*args != ENDARGS && execbrk == 0) {
				assign(n, *args++);
				execute(((FORPTR) t)->fortre, 0, NULL, NULL);
				if (execbrk < 0) {
					execbrk = 0;
				}
			}
			if (breakcnt)
				breakcnt--;
			execbrk = breakcnt;
			loopcnt--;
			argfor = freeargs(argsav);
        		break;
		}

		case TWH:
		case TUN:
		{
			int i = 0;

			loopcnt++;
			while (execbrk == 0 && (execute(((WHPTR) t)->whtre, 0, NULL, NULL) == 0) == (type == TWH)) {
				i = execute(((WHPTR) t)->dotre, 0, NULL, NULL);
				if (execbrk < 0)
					execbrk = 0;
			}
			if (breakcnt)
				breakcnt--;

			execbrk = breakcnt;
			loopcnt--;
			exitval = i;
			break;
		}

		case TIF:
			if (execute(((IFPTR) t)->iftre, 0, NULL, NULL) == 0)
				execute(((IFPTR) t)->thtre, execflg, NULL, NULL);
			else
				execute(((IFPTR) t)->eltre, execflg, NULL, NULL);
			break;

		case TSW:
		{
			register char *r = mactrim(((SWPTR) t)->swarg);
			t = (TREPTR) ((SWPTR) t)->swlst;
			while (t) {
				ARGPTR rex = ((REGPTR) t)->regptr;
				while (rex) {
					register char *s;
					if (gmatch(r, s = macro(rex->argval)) || (trim(s), eq(r, s))) {
						execute(((REGPTR)t)->regcom, 0, NULL, NULL);
						t = 0;
						break;
					} else
						rex = ((ARGPTR)rex)->argnxt;
				}
				if (t)
					t = (TREPTR) ((REGPTR) t)->regnxt;
			}
		}
		break;

		}
		exitset();
	}
Exemple #11
0
int CWinEnemyEditor::drawwin()
{
    setlist(m_wpos.x, m_wpos.y, &m_dpos.x, &m_cur.y, &m_dpos.y, m_list, m_cp);
    return true;
}
Exemple #12
0
static void gen(Error_printer *err, Frag *frag, Node * n)
{
	switch(n->what) {
		case nCOMMA: {
			genn(err, frag, n->l), gen(err, frag, n->r);
			break;
		} case nPAREN: {
			gen(err, frag, n->r);
			break;
		} case nLIST: {
			int amnt = genl(err, frag, n->r);
			push_lst(frag);
			emitn(frag, amnt);
			emitc(frag, iFIX);
			fixlooplvl(frag, amnt);
			break;
		} case nVOID: {
			push_void(frag);
			break;
		} case nTHIS: {
			push_this(frag);
			break;
		} case nNUM: {
			push_num(frag);
			emitl(frag, n->n);
			break;
		} case nFP: {
			push_fp(frag);
			emitd(frag, n->fp);
			break;
		} case nSTR: {
			push_str(frag);
			emits(frag, n->s, n->n);
			break;
		} case nNAM: {
			push_nam(frag);
			emitp(frag, n->s);
			emitc(frag, iGET_ATOM);
			break;
		} case nSET: {
			gen(err, frag, n->r);
//			gena(err, frag, n->l);  (lvalue change)
			gen(err, frag, n->l);
			emitc(frag, iSET);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			break;
		} case nIF: {
			gencond(err, frag, n->r, 1);
			break;
		} case nPOST: {
			gen(err, frag, n->l);
			gen(err, frag, n->r);
//			gena(err, frag, n->l); (lvalue change)
			gen(err, frag, n->l);
			emitc(frag, iSET);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			emitc(frag, iPOP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			break;
		} case nADDR: {
			/* Generate a code snippet */
			genfunc(err, frag, consempty(n->loc), n->r);
			break;
		} case nDEFUN: {
			if (n->r->what==nSEMI) {
				if (n->r->l->what==nCALL && n->r->l->l->what==nNAM) { /* fn sq(x) x*x */
					genfunc(err, frag, n->r->l->r, n->r->r);
					push_nam(frag);
					emitp(frag, n->r->l->l->s);
					emitc(frag, iGETF_ATOM);
					emitc(frag, iSET);
					rmlooplvl(frag, lvlVALUE, 0, 0);
				} else if (n->r->l->what==nNAM && n->r->r->what==nSEMI && n->r->r->l->what==nPAREN) { /* fn sq (x) x*x */
					genfunc(err, frag, n->r->r->l, n->r->r->r);
					push_nam(frag);
					emitp(frag, n->r->l->s);
					emitc(frag, iGETF_ATOM);
					emitc(frag, iSET);
					rmlooplvl(frag, lvlVALUE, 0, 0);
				} else if (n->r->l->what==nNAM && n->r->r->what==nPAREN) { /* fn sq (x) */
					genfunc(err, frag, n->r->r, consempty(n->loc));
					push_nam(frag);
					emitp(frag, n->r->l->s);
					emitc(frag, iGETF_ATOM);
					emitc(frag, iSET);
					rmlooplvl(frag, lvlVALUE, 0, 0);
				} else if (n->r->l->what==nPAREN) { /* fn (x) x*x */
					genfunc(err, frag, n->r->l, n->r->r);
				} else {
					error_2(err, "\"%s\" %d: ill-formed fn", n->r->loc->name, n->r->loc->line);
					push_void(frag);
				}
			} else if(n->r->what==nCALL && n->r->l->what==nNAM) { /* fn sq(x) */
				genfunc(err, frag, n->r->r, consempty(n->loc));
				push_nam(frag);
				emitp(frag, n->r->l->s);
				emitc(frag, iGETF_ATOM);
				emitc(frag, iSET);
				rmlooplvl(frag, lvlVALUE, 0, 0);
			} else if(n->r->what==nPAREN) { /* fn () */
				genfunc(err,frag, n->r, consempty(n->loc));
			} else {
				error_2(err, "\"%s\" %d: ill-formed fn", n->r->loc->name, n->r->loc->line);
				push_void(frag);
			}
			break;
		} case nLAMBDA: {
			genfunc(err, frag, n->r->l, n->r->r);
			break;
		} case nSEMI: {
			if (n->r->what == nELSE) {
				int done = genelif(err, frag, n->l, 1);
				if (!done)
					error_2(err, "\"%s\" %d: else w/o if error", n->r->loc->name, n->r->loc->line);
				if (n->r->r->what == nIF) {
					addlist(frag, done, genbra(err, frag, n->r->r->l, 1));
					n = n->r;
				}
				mklooplvl(frag, lvlSCOPE, 0, 0);
				gen(err, frag, n->r->r);
				rmlooplvl(frag, lvlSCOPE, 0, 0);
				setlist(frag, done, frag->code);
			} else {
				genn(err, frag, n->l);
				gen(err, frag, n->r);
			}
			break;
		} case nEQ: case nNE: case nGT: case nLT: case nGE: case nLE: case nLAND: case nLOR: case nNOT: {
			int b = genbra(err, frag, n, 1);
			int link;
			push_num(frag);
			emitl(frag, 1);
			emitc(frag, iBRA);
			link=emitn(frag, 0);
			setlist(frag, b, frag->code);
			push_num(frag);
			emitl(frag, 0);
			*(int *)(frag->begcode+link)=frag->code-link;
			break;
		} case nCALL: {
//			int nargs = genl(err, frag, n->r); /* By value */
			int nargs = gencl(err, frag, n->r); /* Functionalize */
			push_lst(frag);
			emitn(frag, nargs);
//			gena(err, frag, n->l); (lvalue change)
			gen(err, frag, n->l);
			emitc(frag, iCALL);
			fixlooplvl(frag, nargs + 1);
			break;
		} case nCALL1: { /* Ends up being the same as above */
//			if (n->r->what != nNAM)
//				error_2(err, "\"%s\" %d: Invalid member name", n->r->loc->name, n->r->loc->line);
			if (n->r->what == nNAM) { /* Turn it into a string .x -> ."x" */
				n->r->what = nSTR;
			}
			int nargs = gencl(err, frag, n->r);
//			push_str(frag);
//			emits(frag, n->r->s, n->r->n);
			push_lst(frag);
			emitn(frag, nargs);
//			gena(err, frag, n->l); (lvalue change)
			gen(err, frag, n->l);
			emitc(frag, iCALL);
			fixlooplvl(frag, nargs + 1);
			break;
		} case nCOM: case nNEG: case nSHL: case nSHR: case nMUL: case nDIV: case nMOD: case nAND:
		  case nADD: case nSUB: case nOR: case nXOR: case nAT: {
			if (n->l)
				gen(err, frag, n->l);
			if (n->r)
				gen(err, frag, n->r);
			emitc(frag, what_tab[n->what].i);
			if (n->r && n->l)
				rmlooplvl(frag, lvlVALUE, 0, 0);
			break;
		} default: {
			genn(err, frag, n);
			push_void(frag);
		}
	}
}
Exemple #13
0
static int genbra(Error_printer *err, Frag *frag, Node * n, int t)
{
	switch(n->what) {
		case nEQ: {
			gen(err, frag, n->l);
			gen(err, frag, n->r);
			emitc(frag, iCMP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			if (t)
				emitc(frag, iBNE);
			else
				emitc(frag, iBEQ);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			return emitn(frag, 0);
		} case nNE: {
			gen(err, frag, n->l);
			gen(err, frag, n->r);
			emitc(frag, iCMP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			if (t)
				emitc(frag, iBEQ);
			else
				emitc(frag, iBNE);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			return emitn(frag, 0);
		} case nGT: {
			gen(err, frag, n->l);
			gen(err, frag, n->r);
			emitc(frag, iCMP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			if (t)
				emitc(frag, iBLE);
			else
				emitc(frag, iBGT);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			return emitn(frag, 0);
		} case nGE: {
			gen(err, frag, n->l);
			gen(err, frag, n->r);
			emitc(frag, iCMP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			if (t)
				emitc(frag, iBLT);
			else
				emitc(frag, iBGE);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			return emitn(frag, 0);
		} case nLT: {
			gen(err, frag, n->l);
			gen(err, frag, n->r);
			emitc(frag, iCMP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			if (t)
				emitc(frag, iBGE);
			else
				emitc(frag, iBLT);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			return emitn(frag, 0);
		} case nLE: {
			gen(err, frag, n->l);
			gen(err, frag, n->r);
			emitc(frag, iCMP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			if (t)
				emitc(frag, iBGT);
			else
				emitc(frag, iBLE);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			return emitn(frag, 0);
		} case nNOT: {
			return genbra(err, frag, n->r, !t);
		} case nLAND: {
			int b1 = genbra(err, frag, n->l, 1);
			int b2;
			if (t)
				b2 = genbra(err, frag, n->r, 1), addlist(frag, b2, b1);
			else
				b2 = genbra(err, frag, n->r, 0), setlist(frag, b1, frag->code);
			return b2;
		} case nLOR: {
			int b1 = genbra(err, frag, n->l, 0);
			int b2;
			if (t)
				b2 = genbra(err, frag, n->r, 1), setlist(frag, b1, frag->code);
			else
				b2 = genbra(err, frag, n->r, 0), addlist(frag, b2, b1);
			return b2;
		} default: {
			gen(err, frag, n);
			if (t)
				emitc(frag, iBEQ);
			else
				emitc(frag, iBNE);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			return emitn(frag, 0);
		}
	}
}
Exemple #14
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);
	}
}
Exemple #15
0
void PlayList::buttonClicked (Button* buttonThatWasClicked)
{
    //[UserbuttonClicked_Pre]
    //[/UserbuttonClicked_Pre]
    
    if(buttonThatWasClicked == loadList)
    {
      
        getlist();

        Logger* log = Logger::getCurrentLogger();
        String testtext= sublist.getProperty(sublistId);
        log->writeToLog(testtext);
        log->writeToLog("test");
    }
    else if (buttonThatWasClicked == saveList)
    {
        setlist();

    }
    else if (buttonThatWasClicked == savesublist)
    {

       String testsubId= sublist.getProperty(sublistId);

        
       String testmusicId = music.getProperty(musicId);
        ValueTree newsublist = setsublist(testsubId, testmusicId);

        Logger* log = Logger::getCurrentLogger();
        log->writeToLog(testmusicId);
        log->writeToLog(testsubId);
        playlist.addChild(newsublist, 0, nullptr);
    }
    else if (buttonThatWasClicked == path){
        FileChooser chooser ("Select Music",File::nonexistent);
        if (chooser.browseForFileToOpen()) {
            File file (chooser.getResult());
            String musicname=file.getFileName();
            File path(file.getCurrentWorkingDirectory());
            String actpath= (file.getFullPathName());
            
            ValueTree newmusic= ValueTree(musicId);
            ValueTree newmusicpath = ValueTree(pathId);
            newmusic.addListener(this);
            newmusicpath.addListener(this);
            newmusic.addChild(newmusicpath, 0, nullptr);
            newmusicpath.setProperty(pathId, actpath, nullptr);
            newmusic.setProperty(musicId, musicname, nullptr);
            //ValueTree newsublist = ValueTree(sublistId);
            //newsublist.addListener(this);
            //newsublist.setProperty(sublistId, "New Playlist", nullptr);
            sublist.addChild(newmusic,0, nullptr);
        }
        
       
    }
    else if (buttonThatWasClicked == newsublist)
    {
        NativeMessageBox::showMessageBox(AlertWindow::QuestionIcon, "New Playlist Name", "Please input a new playlist name",testlabel);
        testlabel->setEditable(true,true,true);
        testlabel->addListener(this);
    }
    
}
Exemple #16
0
static void genn(Error_printer *err, Frag *frag, Node * n)
{
	switch(n->what) {
		case nPAREN: {
			genn(err, frag, n->r);
			break;
		} case nQUOTE: {
			error_2(err, "\"%s\" %d: `used incorrectly", n->loc->name, n->loc->line);
			break;
		} case nLABEL: {
			frag->looplvls->name = strdup(n->s);
			break;
		} case nLOCAL: {
			if (n->r->what == nSEMI && n->r->l->what == nPAREN) {
				int amnt;
				mklooplvl(frag, lvlSCOPE, 0, 0);
				amnt = genll(err, frag, n->r->l->r);
				push_lst(frag);
				emitn(frag, amnt);
				emitc(frag, iLOC);
				fixlooplvl(frag, amnt + 1);
				genla(err, frag, n->r->l->r);
				genn(err, frag, n->r->r);
				rmlooplvl(frag, lvlSCOPE, 0, 0);
			} else if (n->r->what == nSEMI && last_is_paren(n->r)) {
				// Handles with a b [f]
				Node *r;
				int amnt;
				n->r = extract_last_is_paren(n->r, &r);
				mklooplvl(frag, lvlSCOPE, 0, 0);
				amnt = genll(err, frag, n->r);
				push_lst(frag);
				emitn(frag, amnt);
				emitc(frag, iLOC);
				fixlooplvl(frag, amnt + 1);
				genla(err, frag, n->r);
				genn(err, frag, r);
				rmlooplvl(frag, lvlSCOPE, 0, 0);
			} else {
				int amnt = genll(err, frag, n->r); /* Create variables */
				push_lst(frag);
				emitn(frag, amnt);
				emitc(frag, iLOC);
				fixlooplvl(frag, amnt + 1);
				genla(err, frag, n->r); /* Initialize them */
			}
			break;
		} case nFOR: {
			int top, cont;
			Node *name;
			Node *args = extract_loop_name(n->r, &name);
			if (args->what != nSEMI) { /* One arg */
				genn(err, frag, args); /* Initializer */
			} else if (args->r->what != nSEMI) { /* Two args */
				genn(err, frag, args->l); /* Initializer */
				emitc(frag, iBRA);
				emitn(frag, 0);
				mklooplvl(frag, lvlLOOP, frag->code-sizeof(int), 0);
				if (name)
					frag->looplvls->name = strdup(name->r->s);
				top = frag->code;
				cont = frag->code;
				setlist(frag,genbra(err, frag, args->r, 0), top); /* Test */
				rmlooplvl(frag, lvlLOOP, cont, frag->code);
			} else if (args->r->r->what != nSEMI) { /* Three args */
				genn(err, frag, args->l); /* Initializer */
				emitc(frag, iBRA);
				emitn(frag, 0);
				mklooplvl(frag, lvlLOOP, frag->code-sizeof(int), 0);
				if (name)
					frag->looplvls->name = strdup(name->r->s);
				top = frag->code;
				genn(err, frag, args->r->r); /* Increment */
				cont = frag->code;
				setlist(frag,genbra(err, frag, args->r->l, 0), top); /* Test */
				rmlooplvl(frag, lvlLOOP, cont, frag->code);
			} else { /* Four args */
				genn(err, frag, args->l); /* Initializer */
				emitc(frag, iBRA);
				emitn(frag, 0);
				mklooplvl(frag, lvlLOOP, frag->code-sizeof(int), 0);
				if (name)
					frag->looplvls->name = strdup(name->r->s);
				top = frag->code;
				mklooplvl(frag, lvlSCOPE, 0, 0);
				genn(err, frag, args->r->r->r); /* Body */
				rmlooplvl(frag, lvlSCOPE, 0, 0);
				genn(err, frag, args->r->r->l); /* Increment */
				cont = frag->code;
				setlist(frag,genbra(err, frag, args->r->l, 0), top); /* Test */
				rmlooplvl(frag, lvlLOOP, cont, frag->code);
			}
			break;
		} case nFOREACH: case nFORINDEX: {
			int top, cont;
			Node *name;
			Node *args = extract_loop_name(n->r, &name);
			if (args->what != nSEMI) { /* One arg */
				error_2(err,"\"%s\" %d: No args for foreach?", n->loc->name, n->loc->line);
			} else if (args->r->what != nSEMI) { /* Two args */
				error_2(err,"\"%s\" %d: Only two args for foreach?", n->loc->name, n->loc->line);
			} else { /* Three args */
				if (args->l->what != nNAM) {
					error_2(err, "\"%s\" %d: First arg to foreach must be a variable", n->loc->name, n->loc->line);
				}
				mklooplvl(frag, lvlSCOPE, 0, 0); /* Scope for args */
				gen(err, frag, args->l);	/* Variable (check that it really is at runtime) */
				gen(err, frag, args->r->l);	/* Array/object */
				push_num(frag);
				emitl(frag, 0);	/* Temp vars for iFOREACH */
				push_num(frag);
				emitl(frag, -1);
				emitc(frag, iBRA);
				emitn(frag, 0);
				mklooplvl(frag, lvlLOOP, frag->code-sizeof(int), 0); /* Start loop */
				if (name)
					frag->looplvls->name = strdup(name->r->s);
				top = frag->code;
				mklooplvl(frag, lvlSCOPE, 0, 0); /* Scope for body */
				genn(err, frag, args->r->r);
				rmlooplvl(frag, lvlSCOPE, 0, 0); /* Body scope done */
				cont = frag->code;
				if (n->what == nFOREACH)
					emitc(frag, iFOREACH);
				else
					emitc(frag, iFORINDEX);
				align_frag(frag, sizeof(int));
				emitn(frag, top - (frag->code));
				rmlooplvl(frag, lvlLOOP, cont, frag->code); /* Complete loop */
				emitc(frag, iPOP);
				emitc(frag, iPOP);
				emitc(frag, iPOP);
				emitc(frag, iPOP);
				fixlooplvl(frag, 4); /* POP temp vars */
				rmlooplvl(frag, lvlSCOPE, 0, 0); /* POP args scope */
			}
			break;
		} case nWHILE: {
			int top, cont;
			Node *name;
			Node *args = extract_loop_name(n->r, &name);
			if (args->what==nEMPTY) {
				error_2(err,"\"%s\" %d: No args for while", n->loc->name, n->loc->line);
				break;
			}
			emitc(frag, iBRA);
			emitn(frag, 0);
			mklooplvl(frag, lvlLOOP, frag->code-sizeof(int), 0);
			if (name)
				frag->looplvls->name = strdup(name->r->s);
			top = frag->code;
			mklooplvl(frag, lvlSCOPE, 0, 0);
			if (args->what==nSEMI)
				genn(err, frag, args->r);
			rmlooplvl(frag, lvlSCOPE, 0, 0);
			cont = frag->code;
			if (args->what==nSEMI)
				setlist(frag, genbra(err, frag, args->l, 0), top);
			else
				setlist(frag, genbra(err, frag, args, 0), top);
			rmlooplvl(frag, lvlLOOP, cont, frag->code);
			break;
		} case nRETURN: {
			int z;
			if (n->r)
				gen(err, frag, n->r);
			else
				push_void(frag);
			emitc(frag, iSTASH);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			poploops(frag, NULL);
			emitc(frag, iBRA);
			z = emitn(frag, 0);
			if (frag->rtn)
				addlist(frag, frag->rtn, z);
			else
				frag->rtn = z;
			break;
		} case nLOOP: {
			int cont;
			Node *name;
			Node *args = extract_loop_name(n->r, &name);
			cont = frag->code;
			mklooplvl(frag, lvlLOOP, 0, 0);
			if (name)
				frag->looplvls->name = strdup(name->r->s);
			mklooplvl(frag, lvlSCOPE, 0, 0);
			genn(err, frag, args);
			rmlooplvl(frag, lvlSCOPE, 0, 0);
			emitc(frag, iBRA);
			align_frag(frag, sizeof(int));
			emitn(frag, cont - (frag->code));
			rmlooplvl(frag, lvlLOOP, cont, frag->code);
			break;
		} case nBREAK: {
			struct looplvl *ll = findlvl(frag, NULL);
			if (n->r) {
				// printf("looking... %s %p %p\n",n->r->s,frag,ll);
				if (n->r->what == nNAM)
					ll = findlvl(frag, n->r->s);
				else if (n->r->what != nEMPTY)
					error_2(err, "\"%s\" %d: Invalid argument to break", n->r->loc->name, n->r->loc->line);
			}
			if (ll) {
				int z;
				// printf("break %d %d\n", ll->scopelvl, frag->scopelvl);
				poploops(frag, ll);
				emitc(frag, iBRA);
				z = emitn(frag, 0);
				if (ll->brk)
					addlist(frag, ll->brk, z);
				else
					ll->brk = z;
			} else
				error_2(err, "\"%s\" %d: break with no loop", n->loc->name, n->loc->line);
			break;
		} case nCONT: {
			struct looplvl *ll = findlvl(frag, NULL);
			if (n->r) {
				if (n->r->what == nNAM)
					ll = findlvl(frag, n->r->s);
				else if (n->r->what != nEMPTY)
					error_2(err, "\"%s\" %d: Invalid argument to continue", n->r->loc->name, n->r->loc->line);
			}
			if (ll) {
				int z;
				poploops(frag, ll);
				emitc(frag, iBRA);
				z = emitn(frag, 0);
				if (ll->cont)
					addlist(frag, ll->cont, z);
				else
					ll->cont = z;
			} else
				error_2(err, "\"%s\" %d: continue with no loop", n->loc->name, n->loc->line);
			break;
		} case nUNTIL: {
			int els = genbra(err, frag, n->r, 1);
			struct looplvl *ll = findlvl(frag, NULL);
			if (ll) {
				int z;
				// printf("break %d %d\n", ll->scopelvl, frag->scopelvl);
				poploops(frag, ll);
				emitc(frag, iBRA);
				z = emitn(frag, 0);
				if (ll->brk)
					addlist(frag, ll->brk, z);
				else
					ll->brk = z;
			} else {
				error_2(err, "\"%s\" %d: until with no loop", n->loc->name, n->loc->line);
			}
			setlist(frag, els, frag->code);
			break;
		} case nIF: {
			gencond(err, frag, n->r, 0);
			break;
		} case nELSE: {
			error_2(err, "\"%s\" %d: else with no if", n->loc->name, n->loc->line);
			break;
		} case nSEMI: {
			if (n->r->what == nELSE) {
				int done = genelif(err, frag, n->l, 0);
				if (!done)
					error_2(err, "\"%s\" %d: else with no if", n->r->loc->name, n->r->loc->line);
				if (n->r->r->what == nIF) {
					addlist(frag, done, genbra(err, frag, n->r->r->l, 1));
					n = n->r;
				}
				mklooplvl(frag, lvlSCOPE, 0, 0);
				genn(err, frag, n->r->r);
				rmlooplvl(frag, lvlSCOPE, 0, 0);
				setlist(frag, done, frag->code);
			} else {
				genn(err, frag, n->l);
				genn(err, frag, n->r);
			}
			break;
		} case nEMPTY: {
			break;
		} default: {
			gen(err, frag, n);
			emitc(frag, iPOP);
			rmlooplvl(frag, lvlVALUE, 0, 0);
			break;
		}
	}
}
Exemple #17
0
int
main(int argc, char *argv[])
{
	struct utsname utsbuf;
	struct statvfs64 svfsb;
	struct cfent	**eptlist;
	FILE	*fp;
	VFP_T	*vfp;
	int	i, c, n, eptnum, found,
		part, nparts, npkgs, objects;
	char	buf[MAX_PKG_PARAM_LENGTH];
	char	temp[MAX_PKG_PARAM_LENGTH];
	char	param[MAX_PKG_PARAM_LENGTH];
	char	*pt, *value, *pkginst, *tmpdir, *abi_sym_ptr,
		**cmdparam;
	char	*pkgname;
	char	*pkgvers;
	char	*pkgarch;
	char	*pkgcat;
	void	(*func)();
	time_t	clock;
	fsblkcnt_t	bsize = 0;
	fsblkcnt_t	frsize = 0;
	struct cl_attr	**allclass = NULL;
	struct cl_attr	**order;

	/* initialize locale environment */

	(void) setlocale(LC_ALL, "");

#if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	/* initialize program name */

	(void) set_prog_name(argv[0]);

	/* tell spmi zones interface how to access package output functions */

	z_set_output_functions(echo, echoDebug, progerr);

	func = sigset(SIGINT, trap);
	if (func != SIG_DFL)
		func = sigset(SIGINT, func);
	func = sigset(SIGHUP, trap);
	setmapmode(MAPBUILD);	/* variable binding */
	if (func != SIG_DFL)
		func = sigset(SIGHUP, func);

	environ = NULL;
	while ((c = getopt(argc, argv, "osnp:l:r:b:d:f:a:v:?")) != EOF) {
		switch (c) {
		    case 'n':
			nflag++;
			break;

		    case 's':
			sflag++;
			break;

		    case 'o':
			overwrite++;
			break;

		    case 'p':
			putparam("PSTAMP", optarg);
			break;

		    case 'l':
			llimit = atol(optarg);
			break;

		    case 'r':
			pt = strtok(optarg, " \t\n, ");
			n = 0;
			do {
				rootlist[n++] = flex_device(pt, 0);
				if (n >= NROOT) {
					progerr(gettext(ERR_NROOT), NROOT);
					quit(1);
				}
			} while (pt = strtok(NULL, " \t\n, "));
			rootlist[n] = NULL;
			break;

		    case 'b':
			basedir = optarg;
			break;

		    case 'f':
			protofile = optarg;
			break;

		    case 'd':
			device = flex_device(optarg, 1);
			break;

		    case 'a':
			putparam("ARCH", optarg);
			break;

		    case 'v':
			putparam("VERSION", optarg);
			break;

		    default:
			usage();
		}
	}

	/*
	 * Store command line variable assignments for later
	 * incorporation into the environment.
	 */
	cmdparam = &argv[optind];

	/* Skip past equates. */
	while (argv[optind] && strchr(argv[optind], '='))
		optind++;

	/* Confirm that the instance name is valid */
	if ((pkginst = argv[optind]) != NULL) {
		if (pkgnmchk(pkginst, "all", 0)) {
			progerr(gettext(ERR_PKGINST), pkginst);
			quit(1);
		}
		argv[optind++] = NULL;
	}
	if (optind != argc)
		usage();

	tmpdir = getenv("TMPDIR");
	if (tmpdir == NULL)
		tmpdir = P_tmpdir;

	/* bug id 4244631, not ABI compliant */
	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
	if (abi_sym_ptr && (strncasecmp(abi_sym_ptr, "TRUE", 4) == 0)) {
		set_nonABI_symlinks();
	}

	if (device == NULL) {
		device = devattr(SPOOLDEV, "pathname");
		if (device == NULL) {
			progerr(gettext(ERR_DEVICE), SPOOLDEV);
			exit(99);
		}
	}

	if (protofile == NULL) {
		if (access("prototype", 0) == 0)
			protofile = "prototype";
		else if (access("Prototype", 0) == 0)
			protofile = "Prototype";
		else {
			progerr(gettext(ERR_PROTOTYPE));
			quit(1);
		}
	}

	if (devtype(device, &pkgdev)) {
		progerr(gettext(ERR_BADDEV), device);
		quit(1);
	}
	if (pkgdev.norewind) {
		/* initialize datastream */
		progerr(gettext(ERR_DSTREAM), device);
		quit(1);
	}
	if (pkgdev.mount) {
		if (n = pkgmount(&pkgdev, NULL, 0, 0, 1))
			quit(n);
	}

	/*
	 * convert prototype file to a pkgmap, while locating
	 * package objects in the current environment
	 */
	t_pkgmap = tempnam(tmpdir, "tmpmap");
	if (t_pkgmap == NULL) {
		progerr(gettext(ERR_TEMP), errno);
		exit(99);
	}

	(void) fprintf(stderr, gettext(MSG_PROTOTYPE));
	if (n = mkpkgmap(t_pkgmap, protofile, cmdparam)) {
		progerr(gettext(ERR_BUILD));
		quit(1);
	}

	setmapmode(MAPNONE);	/* All appropriate variables are now bound */

	if (vfpOpen(&vfp, t_pkgmap, "r", VFP_NEEDNOW) != 0) {
		progerr(gettext(ERR_TEMP), errno);
		quit(99);
	}

	eptlist = procmap(vfp, 0, NULL);

	if (eptlist == NULL) {
		quit(1);
	}

	(void) vfpClose(&vfp);

	/* Validate the zone attributes in pkginfo, before creation */
	if (!valid_zone_attr(eptlist)) {
		progerr(ERR_PKGINFO_INVALID_OPTION_COMB);
		quit(1);
	}

	(void) fprintf(stderr, gettext(MSG_PKGINFO));
	pt = NULL;
	for (i = 0; eptlist[i]; i++) {
		ckmissing(eptlist[i]->path, eptlist[i]->ftype);
		if (eptlist[i]->ftype != 'i')
			continue;
		if (strcmp(eptlist[i]->path, "pkginfo") == 0)
			svept = eptlist[i];
	}
	if (svept == NULL) {
		progerr(gettext(ERR_NOPKGINFO));
		quit(99);
	}
	eptnum = i;

	/*
	 * process all parameters from the pkginfo file
	 * and place them in the execution environment
	 */

	if ((fp = fopen(svept->ainfo.local, "r")) == NULL) {
		progerr(gettext(ERR_RDPKGINFO), svept->ainfo.local);
		quit(99);
	}
	param[0] = '\0';
	while (value = fpkgparam(fp, param)) {
		if (getenv(param) == NULL)
			putparam(param, value);
		free((void *)value);
		param[0] = '\0';
	}
	(void) fclose(fp);

	/* add command line variables */
	while (*cmdparam && (value = strchr(*cmdparam, '=')) != NULL) {
		*value = NULL;	/* terminate the parameter */
		value++;	/* value is now the value (not '=') */
		putparam(*cmdparam++, value);  /* store it in environ */
	}

	/* make sure parameters are valid */
	(void) time(&clock);
	if (pt = getenv("PKG")) {
		if (pkgnmchk(pt, NULL, 0) || strchr(pt, '.')) {
			progerr(gettext(ERR_PKGABRV), pt);
			quit(1);
		}
		if (pkginst == NULL)
			pkginst = pt;
	} else {
		progerr(gettext(ERR_NOPARAM), "PKG", svept->path);
		quit(1);
	}
	/*
	 * verify consistency between PKG parameter and pkginst
	 */
	(void) snprintf(param, sizeof (param), "%s.*", pt);
	if (pkgnmchk(pkginst, param, 0)) {
		progerr(gettext(ERR_PKGMTCH), pt, pkginst);
		quit(1);
	}

	/*
	 * *********************************************************************
	 * this feature is removed starting with Solaris 10 - there is no built
	 * in list of packages that should be run "the old way"
	 * *********************************************************************
	 */

#ifdef	ALLOW_EXCEPTION_PKG_LIST
	/* Until 2.9, set it from the execption list */
	if (exception_pkg(pkginst, LINK))
		set_nonABI_symlinks();
#endif

	if ((pkgname = getenv("NAME")) == NULL) {
		progerr(gettext(ERR_NOPARAM), "NAME", svept->path);
		quit(1);
	}
	if (ckparam("NAME", pkgname))
		quit(1);
	if ((pkgvers = getenv("VERSION")) == NULL) {
		/* XXX - I18n */
		/* LINTED do not use cftime(); use strftime instead */
		(void) cftime(buf, "\045m/\045d/\045Y", &clock);
		(void) snprintf(temp, sizeof (temp),
			gettext("Dev Release %s"), buf);
		putparam("VERSION", temp);
		pkgvers = getenv("VERSION");
		logerr(gettext(WRN_SETPARAM), "VERSION", temp);
	}
	if (ckparam("VERSION", pkgvers))
		quit(1);
	if ((pkgarch = getenv("ARCH")) == NULL) {
		(void) uname(&utsbuf);
		putparam("ARCH", utsbuf.machine);
		pkgarch = getenv("ARCH");
		logerr(gettext(WRN_SETPARAM), "ARCH", utsbuf.machine);
	}
	if (ckparam("ARCH", pkgarch))
		quit(1);
	if (getenv("PSTAMP") == NULL) {
		/* use octal value of '%' to fight sccs expansion */
		/* XXX - I18n */
		/* LINTED do not use cftime(); use strftime instead */
		(void) cftime(buf, "\045Y\045m\045d\045H\045M\045S", &clock);
		(void) uname(&utsbuf);
		(void) snprintf(temp, sizeof (temp), "%s%s",
			utsbuf.nodename, buf);
		putparam("PSTAMP", temp);
		logerr(gettext(WRN_SETPARAM), "PSTAMP", temp);
	}
	if ((pkgcat = getenv("CATEGORY")) == NULL) {
		progerr(gettext(ERR_NOPARAM), "CATEGORY", svept->path);
		quit(1);
	}
	if (ckparam("CATEGORY", pkgcat))
		quit(1);

	/*
	 * warn user of classes listed in package which do
	 * not appear in CLASSES variable in pkginfo file
	 */
	objects = 0;
	for (i = 0; eptlist[i]; i++) {
		if (eptlist[i]->ftype != 'i') {
			objects++;
			addlist(&allclass, eptlist[i]->pkg_class);
		}
	}

	if ((pt = getenv("CLASSES")) == NULL) {
		if (allclass && *allclass) {
			cl_setl(allclass);
			cl_putl("CLASSES", allclass);
			logerr(gettext(WRN_SETPARAM), "CLASSES",
			    getenv("CLASSES"));
		}
	} else {
		cl_sets(qstrdup(pt));
		if (allclass && *allclass) {
			for (i = 0; allclass[i]; i++) {
				found = 0;
				if (cl_idx(allclass[i]->name) != -1) {
					found++;
					break;
				}
				if (!found) {
					logerr(gettext(WRN_CLASSES),
					    (char *)allclass[i]);
				}
			}
		}
	}

	(void) fprintf(stderr, gettext(MSG_VOLUMIZE), objects);
	order = (struct cl_attr **)0;
	if (pt = getenv("ORDER")) {
		pt = qstrdup(pt);
		(void) setlist(&order, pt);
		cl_putl("ORDER", order);
	}

	/* stat the intended output filesystem to get blocking information */
	if (pkgdev.dirname == NULL) {
		progerr(gettext(ERR_WHATVFS), device);
		quit(99);
	}
	if (statvfs64(pkgdev.dirname, &svfsb)) {
		progerr(gettext(ERR_STATVFS), pkgdev.dirname);
		quit(99);
	}

	if (bsize == 0) {
		bsize = svfsb.f_bsize;
	}
	if (frsize == 0) {
		frsize = svfsb.f_frsize;
	}
	if (limit == 0)
		/*
		 * bavail is in terms of fragment size blocks - change
		 * to 512 byte blocks
		 */
		limit = (((long)frsize > 0) ?
			howmany(frsize, DEV_BSIZE) :
			howmany(bsize, DEV_BSIZE)) * svfsb.f_bavail;
	if (ilimit == 0) {
		ilimit = (svfsb.f_favail > 0) ?
		    svfsb.f_favail : svfsb.f_ffree;
	}

	nparts = splpkgmap(eptlist, eptnum, (char **)order, bsize, frsize,
	    &limit, &ilimit, &llimit);

	if (nparts <= 0) {
		progerr(gettext(ERR_SPLIT));
		quit(1);
	}

	if (nflag) {
		for (i = 0; eptlist[i]; i++)
			(void) ppkgmap(eptlist[i], stdout);
		exit(0);
		/*NOTREACHED*/
	}

	(void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s",
			pkgdev.dirname, pkginst);
	if (!isdir(pkgloc) && !overwrite) {
		progerr(gettext(ERR_OVERWRITE), pkgloc);
		quit(1);
	}

	/* output all environment install parameters */
	t_pkginfo = tempnam(tmpdir, "pkginfo");
	if ((fp = fopen(t_pkginfo, "w")) == NULL) {
		progerr(gettext(ERR_TEMP), errno);
		exit(99);
	}
	for (i = 0; environ[i]; i++) {
		if (isupper(*environ[i])) {
			(void) fputs(environ[i], fp);
			(void) fputc('\n', fp);
		}
	}
	(void) fclose(fp);

	started++;
	(void) rrmdir(pkgloc);
	if (mkdir(pkgloc, 0755)) {
		progerr(gettext(ERR_MKDIR), pkgloc);
		quit(1);
	}

	/* determine how many packages already reside on the medium */
	pkgdir = pkgdev.dirname;
	npkgs = 0;
	while (pt = fpkginst("all", NULL, NULL))
		npkgs++;
	(void) fpkginst(NULL); /* free resource usage */

	if (nparts > 1) {
		if (pkgdev.mount && npkgs) {
			progerr(gettext(ERR_ONEVOL));
			quit(1);
		}
	}

	/*
	 *  update pkgmap entry for pkginfo file, since it may
	 *  have changed due to command line or failure to
	 *  specify all neccessary parameters
	 */
	for (i = 0; eptlist[i]; i++) {
		if (eptlist[i]->ftype != 'i')
			continue;
		if (strcmp(eptlist[i]->path, "pkginfo") == 0) {
			svept = eptlist[i];
			svept->ftype = '?';
			svept->ainfo.local = t_pkginfo;
			(void) cverify(0, &svept->ftype, t_pkginfo,
				&svept->cinfo, 1);
			svept->ftype = 'i';
			break;
		}
	}

	if (nparts > 1)
		(void) fprintf(stderr, gettext(MSG_PACKAGEM), nparts);
	else
		(void) fprintf(stderr, gettext(MSG_PACKAGE1));

	for (part = 1; part <= nparts; part++) {
		if ((part > 1) && pkgdev.mount) {
			if (pkgumount(&pkgdev)) {
				progerr(gettext(ERR_UMOUNT), pkgdev.mount);
				quit(99);
			}
			if (n = pkgmount(&pkgdev, NULL, part, nparts, 1))
				quit(n);
			(void) rrmdir(pkgloc);
			if (mkdir(pkgloc, 0555)) {
				progerr(gettext(ERR_MKDIR), pkgloc);
				quit(99);
			}
		}
		outvol(eptlist, eptnum, part, nparts);

		/* Validate (as much as possible) the control scripts. */
		if (part == 1) {
			char inst_path[PATH_MAX];

			(void) fprintf(stderr, gettext(MSG_VALSCRIPTS));
			(void) snprintf(inst_path, sizeof (inst_path),
					"%s/install", pkgloc);
			checkscripts(inst_path, 0);
		}
	}

	quit(0);
	/*NOTREACHED*/
}