Esempio n. 1
0
/* listify -- turn an argc/argv vector into a list */
extern List *listify(int argc, char **argv) {
    Ref(List *, list, NULL);
    while (argc > 0) {
        Term *term = mkterm(argv[--argc], NULL);
        list = mklist(term, list);
    }
    RefReturn(list);
}
Esempio n. 2
0
extern List *endsplit(void) {
    List *result;

    if (buffer != NULL) {
        Term *term = mkterm(sealcountedbuffer(buffer), NULL);
        value = mklist(term, value);
        buffer = NULL;
    }
    result = reverse(value);
    value = NULL;
    return result;
}
Esempio n. 3
0
extern int esopt(const char *options) {
	int c;
	const char *arg, *opt;

	assert(usage != NULL);
	assert(termarg == NULL);
	if (nextchar == 0) {
		if (args == NULL)
			return EOF;
		assert(args->term != NULL);
		arg = getstr(args->term);
		if (*arg != '-')
			return EOF;
		if (arg[1] == '-' && arg[2] == '\0') {
			args = args->next;
			return EOF;
		}
		nextchar = 1;
	} else {
		assert(args != NULL && args->term != NULL);
		arg = getstr(args->term);
	}

	c = arg[nextchar++];
	opt = strchr(options, c);
	if (opt == NULL) {
		const char *msg = usage;
		usage = NULL;
		args = NULL;
		nextchar = 0;
		fail(invoker, "illegal option: -%c -- usage: %s", c, msg);
	}

	if (arg[nextchar] == '\0') {
		nextchar = 0;
		args = args->next;
	}

	if (opt[1] == ':') {
		if (args == NULL) {
			const char *msg = usage;
			fail(invoker, "option -%c expects an argument -- usage: %s", c, msg);
		}
		termarg = (nextchar == 0)
				? args->term
				: mkterm(gcdup(arg + nextchar), NULL);
		nextchar = 0;
		args = args->next;
	}
	return c;
}
Esempio n. 4
0
extern void splitstring(char *in, size_t len, Boolean endword) {
    Buffer *buf = buffer;
    unsigned char *s = (unsigned char *) in, *inend = s + len;

    if (splitchars) {
        assert(buf == NULL);
        while (s < inend) {
            Term *term = mkterm(gcndup((char *) s++, 1), NULL);
            value = mklist(term, value);
        }
        return;
    }

    if (!coalesce && buf == NULL)
        buf = openbuffer(0);

    while (s < inend) {
        int c = *s++;
        if (buf != NULL)
            if (isifs[c]) {
                Term *term = mkterm(sealcountedbuffer(buf), NULL);
                value = mklist(term, value);
                buf = coalesce ? NULL : openbuffer(0);
            } else
                buf = bufputc(buf, c);
        else if (!isifs[c])
            buf = bufputc(openbuffer(0), c);
    }

    if (endword && buf != NULL) {
        Term *term = mkterm(sealcountedbuffer(buf), NULL);
        value = mklist(term, value);
        buf = NULL;
    }
    buffer = buf;
}
Esempio n. 5
0
/* forkexec -- fork (if necessary) and exec */
extern List *forkexec(char *file, List *list, Boolean inchild) {
	int pid, status;
	Vector *env;
	gcdisable();
	env = mkenv();
	pid = efork(!inchild, FALSE);
	if (pid == 0) {
		execve(file, vectorize(list)->vector, env->vector);
		failexec(file, list);
	}
	gcenable();
	status = ewaitfor(pid);
	if ((status & 0xff) == 0) {
		sigint_newline = FALSE;
		SIGCHK();
		sigint_newline = TRUE;
	} else
		SIGCHK();
	printstatus(0, status);
	return mklist(mkterm(mkstatus(status), NULL), NULL);
}
Esempio n. 6
0
/* eval -- evaluate a list, producing a list */
extern List *eval(List *list0, Binding *binding0, int flags) {
	Closure *volatile cp;
	List *fn;

	if (++evaldepth >= maxevaldepth)
		fail("es:eval", "max-eval-depth exceeded");

	Ref(List *, list, list0);
	Ref(Binding *, binding, binding0);
	Ref(char *, funcname, NULL);

restart:
	if (list == NULL) {
		RefPop3(funcname, binding, list);
		--evaldepth;
		return true;
	}
	assert(list->term != NULL);

	if ((cp = getclosure(list->term)) != NULL) {
		switch (cp->tree->kind) {
		    case nPrim:
			assert(cp->binding == NULL);
			list = prim(cp->tree->u[0].s, list->next, binding, flags);
			break;
		    case nThunk:
			list = walk(cp->tree->u[0].p, cp->binding, flags);
			break;
		    case nLambda:
			ExceptionHandler

				Push p;
				Ref(Tree *, tree, cp->tree);
				Ref(Binding *, context,
					       bindargs(tree->u[0].p,
							list->next,
							cp->binding));
				if (funcname != NULL)
					varpush(&p, "0",
						    mklist(mkterm(funcname,
								  NULL),
							   NULL));
				list = walk(tree->u[1].p, context, flags);
				if (funcname != NULL)
					varpop(&p);
				RefEnd2(context, tree);
	
			CatchException (e)

				if (termeq(e->term, "return")) {
					list = e->next;
					goto done;
				}
				throw(e);

			EndExceptionHandler
			break;
		    case nList: {
			list = glom(cp->tree, cp->binding, TRUE);
			list = append(list, list->next);
			goto restart;
		    }
		    default:
			panic("eval: bad closure node kind %d",
			      cp->tree->kind);
		    }
		goto done;
	}

	/* the logic here is duplicated in $&whatis */

	Ref(char *, name, getstr(list->term));
	fn = varlookup2("fn-", name, binding);
	if (fn != NULL) {
		funcname = name;
		list = append(fn, list->next);
		RefPop(name);
		goto restart;
	}
	if (isabsolute(name)) {
		char *error = checkexecutable(name);
		if (error != NULL)
			fail("$&whatis", "%s: %s", name, error);
		list = forkexec(name, list, flags & eval_inchild);
		RefPop(name);
		goto done;
	}
	RefEnd(name);

	fn = pathsearch(list->term);
	if (fn != NULL && fn->next == NULL
	    && (cp = getclosure(fn->term)) == NULL) {
		char *name = getstr(fn->term);
		list = forkexec(name, list, flags & eval_inchild);
		goto done;
	}

	list = append(fn, list->next);
	goto restart;

done:
	--evaldepth;
	if ((flags & eval_exitonfalse) && !istrue(list))
		exit(exitstatus(list));
	RefEnd2(funcname, binding);
	RefReturn(list);
}