Exemplo n.º 1
0
/*
 fileIn reads in a module definition
 */
void fileIn(FILE *fd, boolean printit)
{
    while (fgets(textBuffer, TextBufferSize, fd) != NULL)
    {
        lexinit(textBuffer);
        if (token == inputend)
            ; /* do nothing, get next line */
        else if ((token == binary) && streq(tokenString, "\""))
            ; /* do nothing, its a comment */
        /* Syntax for Class and Methods definitions
         
         Number extend [
           radiusToArea [
             ^self squared * Float pi
           ]
           radiusToCircumference [
             ^self * 2 * Float pi
           ]
         ]
        */
        else if ((token == nameconst) && streq(tokenString,"Class"))
            readClassDeclaration();
        else if ((token == nameconst) && streq(tokenString,"Methods"))
            readMethods(fd, printit);
        else
            sysError("unrecognized line", textBuffer);
    }
}
Exemplo n.º 2
0
void
loop(int toplevel)
{
    List list;
#ifdef DEBUG
    int oasp = toplevel ? 0 : alloc_stackp;
#endif

    pushheap();
    for (;;) {
	freeheap();
	errflag = 0;
	if (interact && isset(SHINSTDIN))
	    preprompt();
	hbegin();		/* init history mech        */
	intr();			/* interrupts on            */
	lexinit();              /* initialize lexical state */
	if (!(list = parse_event())) {	/* if we couldn't parse a list */
	    hend();
	    if (tok == ENDINPUT && !errflag)
		break;
	    continue;
	}
	if (hend()) {
	    int toksav = tok;

	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
		stopmsg--;
	    execlist(list, 0, 0);
	    tok = toksav;
	    if (toplevel)
		noexitct = 0;
	}
	DPUTS(alloc_stackp != oasp, "BUG: alloc_stackp changed in loop()");
	if (ferror(stderr)) {
	    zerr("write error", NULL, 0);
	    clearerr(stderr);
	}
	if (subsh)		/* how'd we get this far in a subshell? */
	    exit(lastval);
	if (((!interact || sourcelevel) && errflag) || retflag)
	    break;
	if (trapreturn) {
	    lastval = trapreturn;
	    trapreturn = 0;
	}
	if (isset(SINGLECOMMAND) && toplevel) {
	    if (sigtrapped[SIGEXIT])
		dotrap(SIGEXIT);
	    exit(lastval);
	}
    }
    popheap();
}
Exemplo n.º 3
0
/* YY_STARTBLOCK -- Terminate the last command block and start a new one.
 * Save old command block in history (if interactive) and in logfile (if
 * interactive, logging is enabled, and logflag argument is true).  Even
 * if logging is enabled, a command will not be logged which aborts or is
 * interrupted.
 */
void
yy_startblock (
  int	logflag
)
{
	register char *ip;

	if (cldebug)
	    eprintf ("startblock (%d)\n", logflag);

	/* Log cmdblk only if it was filled by an interactive task.  We must
	 * make the test when the new block is initialized since the write is
	 * delayed.
	 */
	if (cmdblk_save) { 
	    /* Do not record commands which consist only of whitespace.
	     */
	    for (ip=cmdblk;  isspace (*ip);  ip++)
		;
	    if (*ip != EOS) {
		/* Use the raw_cmdblk, saved in get_command().
		 */
		put_history (raw_cmdblk);
		if (logflag && log_commands())
		    put_logfile (raw_cmdblk);
	    }
	}

	if (cldebug) 
	    eprintf ("startblock: ifseen=%d\n", ifseen);

	if (!ifseen) {
	    ip_cmdblk = op_cmdblk = cmdblk;
	    *ip_cmdblk = EOS;
	}
	cmdblk_line = 0;
	cmdblk_save = (currentask->t_flags & T_INTERACTIVE);

	/* Mode switching of the lexical analyzer is enabled by this call
	 * if the CL parameter lexmodes is set.  Called between blocks
	 * entered interactively and also during error recovery.
	 */
	lexinit();
}
Exemplo n.º 4
0
Arquivo: init.c Projeto: AMDmi3/zsh
enum loop_return
loop(int toplevel, int justonce)
{
    Eprog prog;
    int err, non_empty = 0;

    queue_signals();
    pushheap();
    if (!toplevel)
	zcontext_save();
    for (;;) {
	freeheap();
	if (stophist == 3)	/* re-entry via preprompt() */
	    hend(NULL);
	hbegin(1);		/* init history mech        */
	if (isset(SHINSTDIN)) {
	    setblock_stdin();
	    if (interact && toplevel) {
	        int hstop = stophist;
		stophist = 3;
		/*
		 * Reset all errors including the interrupt error status
		 * immediately, so preprompt runs regardless of what
		 * just happened.  We'll reset again below as a
		 * precaution to ensure we get back to the command line
		 * no matter what.
		 */
		errflag = 0;
		preprompt();
		if (stophist != 3)
		    hbegin(1);
		else
		    stophist = hstop;
		/*
		 * Reset all errors, including user interupts.
		 * This is what allows ^C in an interactive shell
		 * to return us to the command line.
		 */
		errflag = 0;
	    }
	}
	use_exit_printed = 0;
	intr();			/* interrupts on            */
	lexinit();              /* initialize lexical state */
	if (!(prog = parse_event(ENDINPUT))) {
	    /* if we couldn't parse a list */
	    hend(NULL);
	    if ((tok == ENDINPUT && !errflag) ||
		(tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) ||
		justonce)
		break;
	    if (exit_pending) {
		/*
		 * Something down there (a ZLE function?) decided
		 * to exit when there was stuff to clear up.
		 * Handle that now.
		 */
		stopmsg = 1;
		zexit(exit_pending >> 1, 0);
	    }
	    if (tok == LEXERR && !lastval)
		lastval = 1;
	    continue;
	}
	if (hend(prog)) {
	    enum lextok toksav = tok;

	    non_empty = 1;
	    if (toplevel &&
		(getshfunc("preexec") ||
		 paramtab->getnode(paramtab, "preexec" HOOK_SUFFIX))) {
		LinkList args;
		char *cmdstr;

		/*
		 * As we're about to freeheap() or popheap()
		 * anyway, there's no gain in using permanent
		 * storage here.
		 */
		args = newlinklist();
		addlinknode(args, "preexec");
		/* If curline got dumped from the history, we don't know
		 * what the user typed. */
		if (hist_ring && curline.histnum == curhist)
		    addlinknode(args, hist_ring->node.nam);
		else
		    addlinknode(args, "");
		addlinknode(args, dupstring(getjobtext(prog, NULL)));
		addlinknode(args, cmdstr = getpermtext(prog, NULL, 0));

		callhookfunc("preexec", args, 1, NULL);

		/* The only permanent storage is from getpermtext() */
		zsfree(cmdstr);
		/*
		 * Note this does *not* remove a user interrupt error
		 * condition, even though we're at the top level loop:
		 * that would be inconsistent with the case where
		 * we didn't execute a preexec function.  This is
		 * an implementation detail that an interrupting user
		 * does't care about.
		 */
		errflag &= ~ERRFLAG_ERROR;
	    }
	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
		stopmsg--;
	    execode(prog, 0, 0, toplevel ? "toplevel" : "file");
	    tok = toksav;
	    if (toplevel)
		noexitct = 0;
	}
	if (ferror(stderr)) {
	    zerr("write error");
	    clearerr(stderr);
	}
	if (subsh)		/* how'd we get this far in a subshell? */
	    exit(lastval);
	if (((!interact || sourcelevel) && errflag) || retflag)
	    break;
	if (isset(SINGLECOMMAND) && toplevel) {
	    dont_queue_signals();
	    if (sigtrapped[SIGEXIT])
		dotrap(SIGEXIT);
	    exit(lastval);
	}
	if (justonce)
	    break;
    }
Exemplo n.º 5
0
void
loop(int toplevel, int justonce)
{
    List list;
#ifdef DEBUG
    int oasp = toplevel ? 0 : alloc_stackp;
#endif

    pushheap();
    for (;;) {
	freeheap();
	errflag = 0;
	if (isset(SHINSTDIN)) {
	    setblock_stdin();
	    if (interact)
		preprompt();
	}
	hbegin();		/* init history mech        */
	intr();			/* interrupts on            */
	lexinit();              /* initialize lexical state */
	if (!(list = parse_event())) {	/* if we couldn't parse a list */
	    hend();
	    if ((tok == ENDINPUT && !errflag) || justonce)
		break;
	    continue;
	}
	if (hend()) {
	    int toksav = tok;
	    List prelist;

	    if (toplevel && (prelist = getshfunc("preexec")) != &dummy_list) {
		Histent he = gethistent(curhist);
		LinkList args;
		PERMALLOC {
		    args = newlinklist();
		    addlinknode(args, "preexec");
		    if (he && he->text)
			addlinknode(args, he->text);
		} LASTALLOC;
		doshfunc(prelist, args, 0, 1);
		freelinklist(args, (FreeFunc) NULL);
		errflag = 0;
	    }
	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
		stopmsg--;
	    execlist(list, 0, 0);
	    tok = toksav;
	    if (toplevel)
		noexitct = 0;
	}
	DPUTS(alloc_stackp != oasp, "BUG: alloc_stackp changed in loop()");
	if (ferror(stderr)) {
	    zerr("write error", NULL, 0);
	    clearerr(stderr);
	}
	if (subsh)		/* how'd we get this far in a subshell? */
	    exit(lastval);
	if (((!interact || sourcelevel) && errflag) || retflag)
	    break;
	if (trapreturn) {
	    lastval = trapreturn;
	    trapreturn = 0;
	}
	if (isset(SINGLECOMMAND) && toplevel) {
	    if (sigtrapped[SIGEXIT])
		dotrap(SIGEXIT);
	    exit(lastval);
	}
	if (justonce)
	    break;
    }
Exemplo n.º 6
0
int
main(int argc, char *argv[])
{
	int i;
	char *s;
	while(argc>1 && argv[1][0]=='-'){
		s=argv[1]+1;
		while(*s)
			switch(*s++){
			case 'b':	/* suppress become flattening */
				bflag=1;
				break;
			case 'c':	/* print constants */
				cflag=1;
				break;
			case 'C':	/* suppress constant compilation */
				Cflag=1;
				break;
			case 'e':	/* dump core on errors */
				eflag=1;
				break;
			case 'i':	/* print compiled instructions */
				iflag=1;
				break;
			case 'm':	/* trace message passing */
				mflag=1;
				break;
			case 'P':	/* set number of procs */
				if(*s==0){
					--argc, argv++;
					s=argv[1];
					if(s==0)
						goto Usage;
				}
				Nproc=atol(s);
				if(Nproc<=0)
					goto Usage;
				goto Out;
			case 'p':	/* trace process creation */
				pflag++;
				break;
			case 't':	/* dump parse trees */
				tflag=1;
				break;
			case 'x':	/* trace execution */
				xflag=1;
				break;
			default:
			Usage:
				fprint(2, "usage: squint [-ixpb -PNPROC] <files>\n");
				return 1;
			}
		Out:
		--argc; argv++;
	}
	interactive=argc==1;
	procinit();
	fmtinstall('b', bconv);
	fmtinstall('e', econv);
	fmtinstall('m', mconv);
	fmtinstall('n', nconv);
	fmtinstall('t', tconv);
	fmtinstall('i', iconv);
	fmtinstall('A', Aconv);
	fmtinstall('C', Cconv);
	fmtinstall('U', Uconv);
	fmtinstall('z', zconv);
	fmtinstall('Z', zconv);
	lexinit();
	typeinit();
	initializing=1;
	if(errmark()){
		fprint(2, "squint: error during initialization; exiting\n");
		exits("initialization error");
	}
	if(argc==1)
		newfile("<stdin>", 1);
	for(i=argc-1; i>0; --i)
		newfile(argv[i], 0);
	initializing=0;
	errmark();
/*	Fflush(1); */
	do; while(yyparse());
	return 0;
}
Exemplo n.º 7
0
/* GET_COMMAND -- Get command line from the input stream.  If not interactive,
 *   all we do is read the line into the cmdblk buffer.  If called when parsing
 *   command input to an interactive task, we must output a prompt before
 *   reading in the command line.  The prompt changes depending on whether or
 *   not the command is the first in a command block (whether or not we have
 *   closure).  After reading the command, we check if it is a history directive
 *   and process it if so.  Otherwise we must still process it to expand any
 *   history macros.  Ignore all blank or comment lines.  These are
 *   any line in which the first non-blank character is a newline or a
 *   '#'.  This will make some things a bit more efficient, but is
 *   actually to allow the if/else parsing to work properly.
 *
 * N.B.: We must directly or indirectly set ip_cmdblk so that yy_getc takes
 *   the next character from the right place.  This is either done directly
 *   or by a call to yy_startblock.
 */
int
get_command (
  FILE	*fp
)
{
	register char *ip, *op;
	char	raw_cmd[SZ_LINE+1];	/* buffer for raw command line	*/
	char	new_cmd[SZ_CMDBLK+1];	/* temporary for processed cmd	*/
	int	execute=1, temp, status;


	if (!(currentask->t_flags & T_INTERACTIVE)  ||
	    parse_state == PARSE_PARAMS) {

	    /* Ensure that searches through string terminate. */
	    cmdblk[SZ_LINE] = '\0';
	    ip_cmdblk = cmdblk;

	    while (YES) {
 		currentask->t_scriptln++;	/* noninteractive mode	*/

		status = (fgets (cmdblk, SZ_LINE, fp) == NULL ? EOF : OK);
		if (status == EOF) {
		    cmdblk[0] = '\0';
		    break;
		}

		/* Check if this is a blank line. */
		for (ip = cmdblk;  *ip == ' ' || *ip == '\t';  ip++)
		    ;
		if (*ip == '\n' || *ip == '\0')
		    continue;

		/* Check for the #{ ... #} lexmode toggle sequences.  These
		 * are matched only at the beginning of a line.  #{ sets
		 * command mode on the command input stream and #} clears it.
		 */
		if (*ip == '#') {
		    if (ip == cmdblk) {
			if (*(ip+1) == '{') {
			    lex_setcpumode (fp);
			    lexinit();
			} else if (*(ip+1) == '}') {
			    lex_clrcpumode (fp);
			    lexinit();
			}
		    }
		    continue;
		}

		break;
	    }

	    if (cldebug || echocmds())
		eprintf ("%s", status == EOF ? "bye\n" : cmdblk);

	    return (status);
	}

	raw_cmd[SZ_LINE] = '\0';
	while (YES) {
	    /* Prompt the user for a new command if the input buffer is empty.
	     * The CL prompt clears raw mode in case it is left in effect by a
	     * program abort.
	     */
input_:
	    if (c_fstati (fileno(fp), F_UNREAD) == 0) {
		if (c_fstati ((XINT)STDIN, F_RAW) == YES)
		    c_fseti ((XINT)STDIN, F_RAW, NO);
		if (cmdblk_line == 0)
		    pprompt (curpack->pk_name);
		else
		    pprompt (NOCLOSURE);
	    }

	    /* Read the next command line. */
	    if (fgets (raw_cmd, SZ_LINE, fp) == NULL)
		return (EOF);

	    /* Check for the #{ ... #} lexmode toggle sequences.  These
	     * are matched only at the beginning of a line.  #{ sets
	     * command mode on the command input stream and #} clears it.
	     */
	    if (*(ip=raw_cmd) == '#') {
		if (*(ip+1) == '{') {
		    lex_setcpumode (fp);
		    lexinit();
		} else if (*(ip+1) == '}') {
		    lex_clrcpumode (fp);
		    lexinit();
		}
	    }

	    /* Skip leading whitespace. */
	    for (ip=raw_cmd;  *ip == ' ' || *ip == '\t';  ip++)
		;

	    /* For interactive comments, make sure we store them in the
	     * history and the logfile.  This is so that users can add
	     * comments into the logfile interactively.
	     */
	    if (*ip == '#') {
		put_history (raw_cmd);
	  	if (log_commands())
		    put_logfile (raw_cmd);
	    } else if (*ip != '\n' && *ip != '\0') {
		cmdblk_line++;
		break;
	    }
	}

	/* If history directive, transform the directive into an executable
	 * command block using the history data.  Echo the new command as
	 * if the user had typed it, for verification.
	 */
	if (*raw_cmd == HISTCHAR) {
	    /* Use screen style history editing only if the CL parameter
	     * "ehinit" contains the boolean variable "verify" (or if the 
	     * cmd is "ehistory", below).
	     */
	    if (eh_verify)
		execute = edit_history_directive (raw_cmd+1, new_cmd);
	    else {
		execute = process_history_directive (raw_cmd, new_cmd);
		fputs (new_cmd, currentask->t_stdout);
	    }

	} else if (expand_history_macros (raw_cmd, new_cmd)) {
	    fputs (new_cmd, currentask->t_stdout);

	} else {
	    static  char ehist[] = "ehistory";
	    int     n;

	    for (n=0, ip=raw_cmd, op=ehist;  (*ip == *op);  ip++, op++)
		n++;
	    if (n > 0 && isspace (*ip)) {
		while (isspace (*ip))
		    ip++;
		execute = edit_history_directive (ip, new_cmd);
	    }
	}

	/* If user deletes entire line go back and get another command.  */
	for (ip=new_cmd;  isspace (*ip);  ip++)
	    ;
	if (*ip == EOS) {
	    cmdblk_line = 0;
	    execute = 1;
	    goto input_;
	}

	/* Now move the processed command into the cmdblk buffer.  If there
	 * is not enough storage remaining in the cmdblk buffer, we have to
	 * break the actual (large) command block up, calling yy_startblock to
	 * start a new block, but without changing the line number within the
	 * block.  We must not let the history mechanism limit the size of a
	 * command block.
	 */
	op_cmdblk = ip_cmdblk - 1;		/* back up to EOS	*/
	if (strlen (new_cmd) > (cmdblk + SZ_CMDBLK - op_cmdblk)) {
	    temp = cmdblk_line;
	    yy_startblock (LOG);
	    cmdblk_line = temp;
	}
	ip_cmdblk = op = op_cmdblk;
	for (ip=new_cmd;  (*op++ = *ip++) != EOS;  )
	    ;

	/* Save the "raw command" here for use in yy_startblock.  This is
	 * to handle the problem of procedure script parsing overwriting
	 * the raw command in cmdblk.
	 */
	strcpy (raw_cmdblk, cmdblk);

	if (!execute)
	    yy_startblock (NOLOG);

	fflush (currentask->t_stdout);
	return (OK);
}
Exemplo n.º 8
0
// Call this to get the tokens.
//  The number of returned tokens is returned in *plen.
Token*
_gettoks(uchar* data, int datalen, int chset, int mtype, int* plen)
{
	TokenSource*	ts;
	Token*		a;
	int	alen;
	int	ai;
	int	starti;
	int	c;
	int	tag;

	if(!lexinited)
		lexinit();
	ts = newtokensource(data, datalen, chset, mtype);
	if(dbglex)
		fprint(2, "_gettoks starts, ts.i=%d, ts.edata=%d\n", ts->i, ts->edata);
	alen = 0;
	ai = 0;
	a = 0;
	if(ts->mtype == TextHtml) {
		for(;;) {
			if(alen - ai < ToksChunk/32) {
				alen += ToksChunk;
				a = erealloc(a, alen*sizeof *a);
			}
			starti = ts->i;
			c = getchar(ts);
			if(c < 0)
				break;
			if(c == '<') {
				tag = gettag(ts, starti, a, &ai);
				if(tag == Tscript || tag == Tstyle) {
					// special rules for getting Data after....
					starti = ts->i;
					c = getchar(ts);
					tag = getscriptdata(ts, c, starti, a, &ai, tag);
				}
			}
			else
				tag = getdata(ts, c, starti, a, &ai);
			if(tag == -1)
				break;
			else if(dbglex > 1 && tag != Comment)
				fprint(2, "lex: got token %T\n", &a[ai-1]);
		}
	}
	else {
		// plain text (non-html) tokens
		for(;;) {
			if(alen - ai < ToksChunk/32) {
				alen += ToksChunk;
				a = erealloc(a, alen*sizeof *a);
			}
			tag = getplaindata(ts, a, &ai);
			if(tag == -1)
				break;
			if(dbglex > 1)
				fprint(2, "lex: got token %T\n", &a[ai]);
		}
	}
	free(ts);
	if(dbglex)
		fprint(2, "lex: returning %d tokens\n", ai);
	*plen = ai;
	if(ai == 0){
		free(a);
		a = 0;
	}
	return a;
}
Exemplo n.º 9
0
Arquivo: exec.c Projeto: geechee/iraf
/* CALLNEWTASK -- Called from CALL instruction to push and setup a new task
 *   structure.  If find a known ltask with given name create a new task on
 *   control stack, set up newtask and defaults for the pseudofiles.
 *   Pseudofiles may be effected by other instructions before it gets to exec.
 * Make sure we have a pfile list; either try to read it if task is 
 *   supposed to have a real one or manufacture the beginnings of one if it
 *   isn't and set PF_FAKE.  New task runs with a copy of the pfile if it
 *   wasn't fake.  Guard against making more than one copy.  Also, don't dup
 *   the cl's params to maintain the meaning of "firstask".  Things like mode,
 *   logfile and abbreviations should be global and permanent.
 * Special case for package names essentially runs a cl but with a new curpack,
 *   the only real semantic intent of "running" a package.
 *   This lets a package name given as a command appear to change the current
 *   package and yet remain interactive.  Since it really is a new task, state
 *   saving and restoring on error will work right and we also achieve an
 *   ability to have multiple package defn's in a script ltask.
 *   Any parameter references will refer to the cl's also.
 */
void
callnewtask (
  char	*name
)
{
	/* x1 and x2 are just place holders to call breakout().
	 */
	char	*x1, *pk, *t, *x2;	
	struct	ltask *ltp;
	int	flags, ltflags;

	if (cldebug)
	    eprintf ("callnewtask: name=%s, currentask=%x\n", name, currentask);

	/* Save current dictionary and stack pointers. they get restored when
	 * the new task dies normally and the current task is to continue.
	 * save pc when get to the EXEC instruction so it continues from there.
	 */
	currentask->t_topos = topos;	/* save these two just in case 	*/
	currentask->t_basos = basos;	/* something is left on the stk	*/
	currentask->t_topcs = topcs;	/* save before adding newtask	*/
	currentask->t_topd  = topd;	/* save before adding pfile	*/
	currentask->t_curpack = curpack;/* save in case changing to a new one*/
	c_envmark (&currentask->t_envp);/* save env stack pointer	*/
	currentask->t_pno = 0;		/* set only if task defines pkg	*/

	newtask = pushtask();
	flags = 0;

	/* Search for the command to run.  A leading '$' signifies that
	 * execution is to be time but is not part of the name.  Set ltp
	 * and newtask->t_pfp depending on whether we are running a task or
	 * a package.
	 */
	if (*name == '$') {
	    flags |= T_TIMEIT;
	    name++;
	}

	breakout (name, &x1, &pk, &t, &x2);
	ltp = cmdsrch (pk, t);

	if (ltp->lt_flags & LT_CL) {
	    /* Change curpack if LT_PACCL. (cmdsrch() set lt_pkp).  Just
	     * changing packages; use cl's ltask and pfile.  Push a new cl()
	     * on the control stack, with the T_PKGCL and T_CL flags set.
	     */
	    if (ltp->lt_flags & LT_PACCL) {
		flags |= T_PKGCL;
		curpack = ltp->lt_pkp;
	    } else if (ltp->lt_flags & LT_CLEOF)
		flags |= T_CLEOF;

	    ltp = firstask->t_ltp;
	    newtask->t_pfp = firstask->t_pfp;

	    /* Initialize the lexical analyzer (necessary to recognize BOL).
	     */
	    lexinit();

	} else {
	    if (ltp->lt_flags & LT_PFILE) {
		register struct pfile *pfp;

		/* This task has a real pfile. read in if not already in
		 * core.  Copy if not already one and not just cl.
		 */
		newtask->t_pfp = NULL;
		if ((pfp = pfilefind (ltp)) == NULL)
		    pfp = pfileload (ltp);
		if (!(pfp->pf_flags & PF_COPY) && ltp != firstask->t_ltp)
		    pfp = pfilecopy (pfp);
		newtask->t_pfp = pfp;

		/* Also load any pset files associated with the main pfile.
		 * These are linked into a list with the main pfile at the
		 * head of the list, pointed to by the task descriptor.
		 */
		if (pfp->pf_flags & PF_PSETREF) {
		    register struct param *pp;
		    struct  operand o;
		    char    *pset;

		    for (pp = pfp->pf_pp;  pp != NULL;  pp = pp->p_np) {
			if (!(pp->p_type & PT_PSET))
			    continue;
			o = pp->p_valo;
			if (opundef(&o) || *(pset = o.o_val.v_s) == EOS)
			    pset = pp->p_name;
			pfp = pfp->pf_npset = pfilecopy (pfilesrch (pset));
			pfp->pf_psetp = pp;
		    }
		}

	    } else {
		/* This task does not have a real pfile so start a fake one.
		 */
		newtask->t_pfp = newpfile (ltp);
		newtask->t_pfp->pf_flags = PF_FAKE;
	    }
	}

	newtask->t_pfp->pf_n = 0;	/* init number of command line args */
	newtask->t_ltp = ltp;
	newtask->t_pid = -1;		/* gets set if do a real exec	*/
	newtask->t_stdin = currentask->t_stdin;	/* inherit files	*/
	newtask->t_stdout = currentask->t_stdout;
	newtask->t_stderr = currentask->t_stderr;
	newtask->t_stdgraph = currentask->t_stdgraph;
	newtask->t_stdimage = currentask->t_stdimage;
	newtask->t_stdplot = currentask->t_stdplot;

	/* Init i/o redirection for a foreign task.
	 */
	newtask->ft_in = newtask->ft_out = newtask->ft_err = NULL;

	/* Set up flags describing the kind of task we are about to run. the
	 * absence of any of these flags will imply a genuine executable task.
	 * the flags in t_flags are more of a convenience than anything since
	 * later tests could use the same tests used here.
	 */
	ltflags = ltp->lt_flags;

	if (ltflags & LT_PSET) {
	    flags = (T_SCRIPT|T_PSET);
	} else if (ltflags & LT_SCRIPT) {
	    newtask->t_scriptln = 0;
	    flags = T_SCRIPT;
	} else if (ltflags & LT_FOREIGN) {
	    flags = T_BUILTIN | T_FOREIGN;	/* a type of builtin */
	} else if (ltflags & LT_BUILTIN) {
	    flags = T_BUILTIN;
	} else if (ltflags & LT_CL) {
	    /* Or, not assign: preserve T_PKGCL and T_CLEOF flags if set. */
	    flags |= T_CL;
	}

	if (ltflags & LT_STDINB)
	    flags |= T_STDINB;
	if (ltflags & LT_STDOUTB)
	    flags |= T_STDOUTB;

	newtask->t_flags = flags;
}
Exemplo n.º 10
0
Arquivo: init.c Projeto: Lujaw/zsh
enum loop_return
loop(int toplevel, int justonce)
{
    Eprog prog;
    int err, non_empty = 0;

    pushheap();
    if (!toplevel)
	lexsave();
    for (;;) {
	freeheap();
	if (stophist == 3)	/* re-entry via preprompt() */
	    hend(NULL);
	hbegin(1);		/* init history mech        */
	if (isset(SHINSTDIN)) {
	    setblock_stdin();
	    if (interact && toplevel) {
	        int hstop = stophist;
		stophist = 3;
		preprompt();
		if (stophist != 3)
		    hbegin(1);
		else
		    stophist = hstop;
		errflag = 0;
	    }
	}
	use_exit_printed = 0;
	intr();			/* interrupts on            */
	lexinit();              /* initialize lexical state */
	if (!(prog = parse_event())) {	/* if we couldn't parse a list */
	    hend(NULL);
	    if ((tok == ENDINPUT && !errflag) ||
		(tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) ||
		justonce)
		break;
	    if (exit_pending) {
		/*
		 * Something down there (a ZLE function?) decided
		 * to exit when there was stuff to clear up.
		 * Handle that now.
		 */
		stopmsg = 1;
		zexit(exit_pending >> 1, 0);
	    }
	    if (tok == LEXERR && !lastval)
		lastval = 1;
	    continue;
	}
	if (hend(prog)) {
	    int toksav = tok;

	    non_empty = 1;
	    if (toplevel &&
		(getshfunc("preexec") ||
		 paramtab->getnode(paramtab, "preexec" HOOK_SUFFIX))) {
		LinkList args;
		char *cmdstr;

		/*
		 * As we're about to freeheap() or popheap()
		 * anyway, there's no gain in using permanent
		 * storage here.
		 */
		args = newlinklist();
		addlinknode(args, "preexec");
		/* If curline got dumped from the history, we don't know
		 * what the user typed. */
		if (hist_ring && curline.histnum == curhist)
		    addlinknode(args, hist_ring->node.nam);
		else
		    addlinknode(args, "");
		addlinknode(args, dupstring(getjobtext(prog, NULL)));
		addlinknode(args, cmdstr = getpermtext(prog, NULL, 0));

		callhookfunc("preexec", args, 1, NULL);

		/* The only permanent storage is from getpermtext() */
		zsfree(cmdstr);
		errflag = 0;
	    }
	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
		stopmsg--;
	    execode(prog, 0, 0, toplevel ? "toplevel" : "file");
	    tok = toksav;
	    if (toplevel)
		noexitct = 0;
	}
	if (ferror(stderr)) {
	    zerr("write error");
	    clearerr(stderr);
	}
	if (subsh)		/* how'd we get this far in a subshell? */
	    exit(lastval);
	if (((!interact || sourcelevel) && errflag) || retflag)
	    break;
	if (isset(SINGLECOMMAND) && toplevel) {
	    if (sigtrapped[SIGEXIT])
		dotrap(SIGEXIT);
	    exit(lastval);
	}
	if (justonce)
	    break;
    }