Exemplo n.º 1
0
/* tw_prlist():
 *	Pretty print a list of variables
 */
static void
tw_prlist(struct varent *p)
{
    struct varent *c;

    for (;;) {
	while (p->v_left)
	    p = p->v_left;
x:
	if (p->v_parent == 0)	/* is it the header? */
	    break;
	if (setintr) {
	    int old_pintr_disabled;

	    pintr_push_enable(&old_pintr_disabled);
	    cleanup_until(&old_pintr_disabled);
	}
	xprintf("%s\t", short2str(p->v_name));
	if (p->vec)
	    tw_pr(p->vec);
	xputchar('\n');
	if (p->v_right) {
	    p = p->v_right;
	    continue;
	}
	do {
	    c = p;
	    p = p->v_parent;
	} while (p->v_right == c);
	goto x;
    }
} /* end tw_prlist */
Exemplo n.º 2
0
/*
 * Karl Kleinpaste, 18 Jan 1984.
 * Added period_cmd(), which executes the alias "periodic" every
 * $tperiod minutes.  Useful for occasional checking of msgs and such.
 */
void
period_cmd(void)
{
    Char *vp;
    time_t  t, interval;

    pintr_disabled++;
    cleanup_push(&pintr_disabled, disabled_cleanup);
    if (periodic_active) {	/* an error must have been caught */
	aliasrun(2, STRunalias, STRperiodic);
	xprintf("%s", CGETS(22, 6, "Faulty alias 'periodic' removed.\n"));
	goto leave;
    }
    periodic_active = 1;
    if (!whyles && adrof1(STRperiodic, &aliases)) {
	vp = varval(STRtperiod);
	if (vp == STRNULL) {
	    aliasrun(1, STRperiodic, NULL);
	    goto leave;
	}
	interval = getn(vp);
	(void) time(&t);
	if (t - t_period >= interval * 60) {
	    t_period = t;
	    aliasrun(1, STRperiodic, NULL);
	}
    }
leave:
    periodic_active = 0;
    cleanup_until(&pintr_disabled);
}
Exemplo n.º 3
0
Arquivo: sh.dir.c Projeto: lukem/tcsh
static Char *
dgoto(Char *cp)
{
    Char *dp, *ret;

    if (!ABSOLUTEP(cp))
    {
	Char *p, *q;
	size_t cwdlen;

	cwdlen = Strlen(dcwd->di_name);
	if (cwdlen == 1)	/* root */
	    cwdlen = 0;
	dp = xmalloc((cwdlen + Strlen(cp) + 2) * sizeof(Char));
	for (p = dp, q = dcwd->di_name; (*p++ = *q++) != '\0';)
	    continue;
	if (cwdlen)
	    p[-1] = '/';
	else
	    p--;		/* don't add a / after root */
	Strcpy(p, cp);
	xfree(cp);
	cp = dp;
	dp += cwdlen;
    }
    else
	dp = cp;

#if defined(WINNT_NATIVE)
    return agetcwd();
#elif defined(__CYGWIN__)
    if (ABSOLUTEP(cp) && cp[1] == ':') { /* Only DOS paths are treated that way */
	return agetcwd();
    } else {
	cleanup_push(cp, xfree);
    	ret = dcanon(cp, dp);
	cleanup_ignore(cp);
	cleanup_until(cp);
    }
#else /* !WINNT_NATIVE */
    cleanup_push(cp, xfree);
    ret = dcanon(cp, dp);
    cleanup_ignore(cp);
    cleanup_until(cp);
#endif /* WINNT_NATIVE */
    return ret;
}
Exemplo n.º 4
0
Arquivo: ntfunc.c Projeto: phase/tcsh
void dotitle(Char **vc, struct command * c) {

	int k;
	char titlebuf[512];
	char errbuf[128],err2[128];
	char **v;
	Char **nvc;

	UNREFERENCED_PARAMETER(c);
	vc++;
	nvc = glob_all_or_error(vc);
	if (nvc == NULL)
		return;
	if (nvc != vc)
		cleanup_push(nvc, blk_cleanup);

	if ((k = GetConsoleTitle(titlebuf, sizeof(titlebuf))) != 0) {
		setcopy(STRoldtitle,str2short(titlebuf),
		    VAR_READWRITE|VAR_NOGLOB);
	}

	titlebuf[0] = '\0';
	v = short2blk(nvc);
	if (nvc != vc)
		cleanup_until(nvc);
	cleanup_push((Char **)v, blk_cleanup);
	for (k = 0; v[k] != NULL ; k++){
		__try {
			StringCbCat(titlebuf,sizeof(titlebuf),v[k]);
			StringCbCat(titlebuf,sizeof(titlebuf)," ");
		}
		__except(GetExceptionCode()) {
			stderror(ERR_TOOMANY);
		}
	}

	if (!SetConsoleTitle(titlebuf) ) {
		make_err_str(GetLastError(),errbuf,128);
		(void)StringCbPrintf(err2,sizeof(err2),"%s",v[k]);
		stderror(ERR_SYSTEM,err2,errbuf);
	}
	cleanup_until((Char **)v);
	return;
}
Exemplo n.º 5
0
/*
 * Print the termcap string out with variable substitution
 */
	void
EchoTC(Char **v)
{
	Char **globbed;
	char    cv[BUFSIZE];/*FIXBUF*/
	int     verbose = 0, silent = 0;
	static char *fmts = "%s\n", *fmtd = "%d\n";
	int li,co;


	setname("echotc");

	v = glob_all_or_error(v);
	globbed = v;
	cleanup_push(globbed, blk_cleanup);

	if (!v || !*v || *v[0] == '\0')
		goto end;
	if (v[0][0] == '-') {
		switch (v[0][1]) {
			case 'v':
				verbose = 1;
				break;
			case 's':
				silent = 1;
				break;
			default:
				stderror(ERR_NAME | ERR_TCUSAGE);
				break;
		}
		v++;
	}
	if (!*v || *v[0] == '\0')
		goto end;
	(void) StringCbCopy(cv,sizeof(cv), short2str(*v));

	GetSize(&li,&co);

	if(!lstrcmp(cv,"rows") || !lstrcmp(cv,"lines") ) {
		xprintf(fmtd,T_Lines);
		goto end;
	}
	else if(!lstrcmp(cv,"cols") ) {
		xprintf(fmtd,T_ActualWindowSize);
		goto end;
	}
	else if(!lstrcmp(cv,"buffer") ) {
		xprintf(fmtd,T_Cols);
		goto end;
	}
	else
		stderror(ERR_SYSTEM, "EchoTC","Sorry, this function is not supported");

end:
	cleanup_until(globbed);
}
Exemplo n.º 6
0
void
setcopy(const Char *var, const Char *val, int flags)
{
    Char *copy;

    copy = Strsave(val);
    cleanup_push(copy, xfree);
    setv(var, copy, flags);
    cleanup_ignore(copy);
    cleanup_until(copy);
}
Exemplo n.º 7
0
Char   *
globone(Char *str, int action)
{
    Char   *v[2], **vl, **vo;
    int gflg, noglob;

    noglob = adrof(STRnoglob) != 0;
    v[0] = str;
    v[1] = 0;
    gflg = tglob(v);
    if (gflg == G_NONE)
	return (strip(Strsave(str)));

    if (gflg & G_CSH) {
	/*
	 * Expand back-quote, tilde and brace
	 */
	vo = globexpand(v, noglob);
	if (noglob || (gflg & G_GLOB) == 0) {
	    vl = vo;
	    goto result;
	}
	cleanup_push(vo, blk_cleanup);
    }
    else if (noglob || (gflg & G_GLOB) == 0)
	return (strip(Strsave(str)));
    else
	vo = v;

    vl = libglob(vo);
    if (gflg & G_CSH) {
    	if (vl != vo)
	    cleanup_until(vo);
	else
	    cleanup_ignore(vo);
    }
    if (vl == NULL) {
	setname(short2str(str));
	stderror(ERR_NAME | ERR_NOMATCH);
    }
 result:
    if (vl && vl[0] == NULL) {
	xfree(vl);
	return (Strsave(STRNULL));
    }
    if (vl && vl[1]) 
	return (handleone(str, vl, action));
    else {
	str = strip(*vl);
	xfree(vl);
	return (str);
    }
}
Exemplo n.º 8
0
static void
asx(Char *vp, int subscr, Char *p)
{
    struct varent *v = getvx(vp, subscr);
    Char *prev;

    if (v->v_flags & VAR_READONLY)
	stderror(ERR_READONLY|ERR_NAME, v->v_name);
    prev = v->vec[subscr - 1];
    cleanup_push(prev, xfree);
    v->vec[subscr - 1] = globone(p, G_APPEND);
    cleanup_until(prev);
}
Exemplo n.º 9
0
/* put_color():
 */
static void
put_color(const Str *color)
{
    size_t  i;
    const char	 *c = color->s;
    int	   original_output_raw = output_raw;

    output_raw = TRUE;
    cleanup_push(&original_output_raw, output_raw_restore);
    for (i = color->len; 0 < i; i--)
	xputchar(*c++);
    cleanup_until(&original_output_raw);
}
Exemplo n.º 10
0
/*ARGSUSED*/
void
doucb(Char **v, struct command *c)
{
    Char *cp = v[1];
    char    ubuf[100];

    if (cp == 0)
	(void) setuniverse("ucb");
    else {
	(void) getuniverse(ubuf);
	(void) setuniverse("ucb");
	cleanup_push(ubuf, setuniverse_cleanup);
	if (setintr) {
	    pintr_disabled++;
	    cleanup_push(&pintr_disabled, disabled_cleanup);
	}
	lshift(v, 1);
	if (setintr)
	    cleanup_until(&pintr_disabled);
	reexecute(c);
	cleanup_until(ubuf);
    }
}
Exemplo n.º 11
0
/*ARGSUSED*/
void
doinlib(Char **v, struct command *c)
{
    Char **globbed;

    setname(short2str(*v++));
    v = glob_all_or_error(v);
    globbed = v;
    cleanup_push(globbed, blk_cleanup);

    while (v && *v) 
	llib(*v++);
    cleanup_until(globbed);
}
Exemplo n.º 12
0
Arquivo: sh.dir.c Projeto: lukem/tcsh
void
loaddirs(Char *fname)
{
    static Char *loaddirs_cmd[] = { STRsource, NULL, NULL };

    bequiet = 1;
    cleanup_push(&bequiet, bequiet_cleanup);
    if (fname)
	loaddirs_cmd[1] = fname;
    else if ((fname = varval(STRdirsfile)) != STRNULL)
	loaddirs_cmd[1] = fname;
    else
	loaddirs_cmd[1] = STRtildotdirs;
    dosource(loaddirs_cmd, NULL);
    cleanup_until(&bequiet);
}
Exemplo n.º 13
0
/*ARGSUSED*/
void
dosettc(Char **v, struct command *c)
{
    char    *tv[2];

    USE(c);
    if (!GotTermCaps)
	GetTermCaps();

    tv[0] = strsave(short2str(v[1]));
    cleanup_push(tv[0], xfree);
    tv[1] = strsave(short2str(v[2]));
    cleanup_push(tv[1], xfree);
    SetTC(tv[0], tv[1]);
    cleanup_until(tv[0]);
}
Exemplo n.º 14
0
/*
 * Joachim Hoenig  07/16/91  Added beep_cmd, run every time tcsh wishes 
 * to beep the terminal bell. Useful for playing nice sounds instead.
 */
void
beep_cmd(void)
{
    pintr_disabled++;
    cleanup_push(&pintr_disabled, disabled_cleanup);
    if (beepcmd_active) {	/* an error must have been caught */
	aliasrun(2, STRunalias, STRbeepcmd);
	xprintf("%s", CGETS(22, 5, "Faulty alias 'beepcmd' removed.\n"));
    }
    else {
	beepcmd_active = 1;
	if (!whyles && adrof1(STRbeepcmd, &aliases))
	    aliasrun(1, STRbeepcmd, NULL);
    }
    beepcmd_active = 0;
    cleanup_until(&pintr_disabled);
}
Exemplo n.º 15
0
/*
 * Paul Placeway  11/24/87  Added cwd_cmd by hacking precmd() into
 * submission...  Run every time $cwd is set (after it is set).  Useful
 * for putting your machine and cwd (or anything else) in an xterm title
 * space.
 */
void
cwd_cmd(void)
{
    pintr_disabled++;
    cleanup_push(&pintr_disabled, disabled_cleanup);
    if (cwdcmd_active) {	/* an error must have been caught */
	aliasrun(2, STRunalias, STRcwdcmd);
	xprintf("%s", CGETS(22, 4, "Faulty alias 'cwdcmd' removed.\n"));
	goto leave;
    }
    cwdcmd_active = 1;
    if (!whyles && adrof1(STRcwdcmd, &aliases))
	aliasrun(1, STRcwdcmd, NULL);
leave:
    cwdcmd_active = 0;
    cleanup_until(&pintr_disabled);
}
Exemplo n.º 16
0
static void
exportpath(Char **val)
{
    struct Strbuf buf = Strbuf_INIT;
    Char    	*exppath;

    if (val)
	while (*val) {
	    Strbuf_append(&buf, *val++);
	    if (*val == 0 || eq(*val, STRRparen))
		break;
	    Strbuf_append1(&buf, PATHSEP);
	}
    exppath = Strbuf_finish(&buf);
    cleanup_push(exppath, xfree);
    tsetenv(STRKPATH, exppath);
    cleanup_until(exppath);
}
Exemplo n.º 17
0
/* 
 * GrP Greg Parker May 2001
 * Added job_cmd(), which is run every time a job is started or 
 * foregrounded. The command is passed a single argument, the string 
 * used to start the job originally. With precmd, useful for setting 
 * xterm titles.
 * Cloned from cwd_cmd().
 */
void
job_cmd(Char *args)
{
    pintr_disabled++;
    cleanup_push(&pintr_disabled, disabled_cleanup);
    if (jobcmd_active) {	/* an error must have been caught */
	aliasrun(2, STRunalias, STRjobcmd);
	xprintf("%s", CGETS(22, 14, "Faulty alias 'jobcmd' removed.\n"));
	goto leave;
    }
    jobcmd_active = 1;
    if (!whyles && adrof1(STRjobcmd, &aliases)) {
	struct process *pp = pcurrjob; /* put things back after the hook */
	aliasrun(2, STRjobcmd, args);
	pcurrjob = pp;
    }
leave:
    jobcmd_active = 0;
    cleanup_until(&pintr_disabled);
}
Exemplo n.º 18
0
static char *
xgetpass(const char *prm)
{
    static struct strbuf pass; /* = strbuf_INIT; */
    int fd;
    sigset_t oset, set;
    struct sigaction sa, osa;

    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    (void)sigaction(SIGINT, &sa, &osa);

    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    (void)sigprocmask(SIG_UNBLOCK, &set, &oset);

    cleanup_push(&osa, sigint_cleanup);
    cleanup_push(&oset, sigprocmask_cleanup);
    (void) Rawmode();	/* Make sure, cause we want echo off */
    fd = xopen("/dev/tty", O_RDWR|O_LARGEFILE);
    if (fd == -1)
	fd = SHIN;
    else
	cleanup_push(&fd, open_cleanup);

    xprintf("%s", prm); flush();
    pass.len = 0;
    for (;;)  {
	char c;

	if (xread(fd, &c, 1) < 1 || c == '\n') 
	    break;
	strbuf_append1(&pass, c);
    }
    strbuf_terminate(&pass);

    cleanup_until(&osa);

    return pass.s;
}
Exemplo n.º 19
0
int
Gnmatch(const Char *string, const Char *pattern, const Char **endstr)
{
    Char ***fblk, **p;
    const Char *tstring = string;
    int	   gpol = 1, gres = 0;

    if (*pattern == '^') {
	gpol = 0;
	pattern++;
    }

    fblk = xmalloc(sizeof(Char ***));
    *fblk = xmalloc(GLOBSPACE * sizeof(Char *));
    (*fblk)[0] = Strsave(pattern);
    (*fblk)[1] = NULL;

    cleanup_push(fblk, blk_indirect_cleanup);
    expbrace(fblk, NULL, GLOBSPACE);

    if (endstr == NULL)
	/* Exact matches only */
	for (p = *fblk; *p; p++) 
	    gres |= t_pmatch(string, *p, &tstring, 1) == 2 ? 1 : 0;
    else {
	const Char *end;

	/* partial matches */
        end = Strend(string);
	for (p = *fblk; *p; p++)
	    if (t_pmatch(string, *p, &tstring, 1) != 0) {
		gres |= 1;
		if (end > tstring)
		    end = tstring;
	    }
	*endstr = end;
    }

    cleanup_until(fblk);
    return(gres == gpol);
} 
Exemplo n.º 20
0
Arquivo: sh.dir.c Projeto: lukem/tcsh
static void
dgetstack(void)
{
    int i = 0;
    Char **dblk, **dbp;
    struct directory *dn;

    if (adrof(STRdirstack) == NULL) 
    	return;

    for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, i++)
	continue;
    dbp = dblk = xmalloc((i + 1) * sizeof(Char *));
    for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, dbp++)
	 *dbp = Strsave(dn->di_name);
    *dbp = NULL;
    cleanup_push(dblk, blk_cleanup);
    setq(STRdirstack, dblk, &shvhed, VAR_READWRITE);
    cleanup_ignore(dblk);
    cleanup_until(dblk);
}
Exemplo n.º 21
0
Arquivo: sh.sem.c Projeto: lukem/tcsh
/*
 * Expand and glob the words after an i/o redirection.
 * If more than one word is generated, then update the command vector.
 *
 * This is done differently in all the shells:
 * 1. in the bourne shell and ksh globbing is not performed
 * 2. Bash/csh say ambiguous
 * 3. zsh does i/o to/from all the files
 * 4. itcsh concatenates the words.
 *
 * I don't know what is best to do. I think that Ambiguous is better
 * than restructuring the command vector, because the user can get
 * unexpected results. In any case, the command vector restructuring 
 * code is present and the user can choose it by setting noambiguous
 */
static Char *
splicepipe(struct command *t, Char *cp)
{
    Char *blk[2];

    if (adrof(STRnoambiguous)) {
	Char **pv;
	int gflag;

	blk[0] = Dfix1(cp); /* expand $ */
	blk[1] = NULL;

	gflag = tglob(blk);
	if (gflag) {
	    pv = globall(blk, gflag);
	    if (pv == NULL) {
		setname(short2str(blk[0]));
		xfree(blk[0]);
		stderror(ERR_NAME | ERR_NOMATCH);
	    }
	    if (pv[1] != NULL) { /* we need to fix the command vector */
		Char **av = blkspl(t->t_dcom, &pv[1]);
		xfree(t->t_dcom);
		t->t_dcom = av;
	    }
	    xfree(blk[0]);
	    blk[0] = pv[0];
	    xfree(pv);
	}
    }
    else {
	Char *buf;

	buf = Dfix1(cp);
	cleanup_push(buf, xfree);
	blk[0] = globone(buf, G_ERROR);
	cleanup_until(buf);
    }
    return(blk[0]);
}
Exemplo n.º 22
0
void
plist(struct varent *p, int what)
{
    struct varent *c;
    int len;

    for (;;) {
	while (p->v_left)
	    p = p->v_left;
x:
	if (p->v_parent == 0)	/* is it the header? */
	    break;
	if ((p->v_flags & what) != 0) {
	    if (setintr) {
		int old_pintr_disabled;

		pintr_push_enable(&old_pintr_disabled);
		cleanup_until(&old_pintr_disabled);
	    }
	    len = blklen(p->vec);
	    xprintf("%S\t", p->v_name);
	    if (len != 1)
		xputchar('(');
	    blkpr(p->vec);
	    if (len != 1)
		xputchar(')');
	    xputchar('\n');
	}
	if (p->v_right) {
	    p = p->v_right;
	    continue;
	}
	do {
	    c = p;
	    p = p->v_parent;
	} while (p->v_right == c);
	goto x;
    }
}
Exemplo n.º 23
0
static void
update_vars(Char *vp)
{
    if (eq(vp, STRpath)) {
	struct varent *p = adrof(STRpath); 
	if (p == NULL)
	    stderror(ERR_NAME | ERR_UNDVAR);
	else {
	    exportpath(p->vec);
	    dohash(NULL, NULL);
	}
    }
    else if (eq(vp, STRnoclobber)) {
	struct varent *p = adrof(STRnoclobber);
	if (p == NULL)
	    stderror(ERR_NAME | ERR_UNDVAR);
	else
	    no_clobber = set_noclobber(p->vec);
    }
    else if (eq(vp, STRhistchars)) {
	Char *pn = varval(vp);

	HIST = *pn++;
	if (HIST)
	    HISTSUB = *pn;
	else
	    HISTSUB = HIST;
    }
    else if (eq(vp, STRpromptchars)) {
	Char *pn = varval(vp);

	PRCH = *pn++;
	if (PRCH)
	    PRCHROOT = *pn;
	else
	    PRCHROOT = PRCH;
    }
    else if (eq(vp, STRhistlit)) {
	HistLit = 1;
    }
    else if (eq(vp, STRuser)) {
	tsetenv(STRKUSER, varval(vp));
	tsetenv(STRLOGNAME, varval(vp));
    }
    else if (eq(vp, STRgroup)) {
	tsetenv(STRKGROUP, varval(vp));
    }
    else if (eq(vp, STRwordchars)) {
	word_chars = varval(vp);
    }
    else if (eq(vp, STRloginsh)) {
	loginsh = 1;
    }
    else if (eq(vp, STRanyerror)) {
	anyerror = 1;
    }
    else if (eq(vp, STRsymlinks)) {
	Char *pn = varval(vp);

	if (eq(pn, STRignore))
	    symlinks = SYM_IGNORE;
	else if (eq(pn, STRexpand))
	    symlinks = SYM_EXPAND;
	else if (eq(pn, STRchase))
	    symlinks = SYM_CHASE;
	else
	    symlinks = 0;
    }
    else if (eq(vp, STRterm)) {
	Char *cp = varval(vp);
	tsetenv(STRKTERM, cp);
#ifdef DOESNT_WORK_RIGHT
	cp = getenv("TERMCAP");
	if (cp && (*cp != '/'))	/* if TERMCAP and not a path */
	    Unsetenv(STRTERMCAP);
#endif /* DOESNT_WORK_RIGHT */
	GotTermCaps = 0;
	if (noediting && Strcmp(cp, STRnetwork) != 0 &&
	    Strcmp(cp, STRunknown) != 0 && Strcmp(cp, STRdumb) != 0) {
	    editing = 1;
	    noediting = 0;
	    setNS(STRedit);
	}
	ed_Init();		/* reset the editor */
    }
    else if (eq(vp, STRhome)) {
	Char *cp, *canon;

	cp = Strsave(varval(vp));	/* get the old value back */
	cleanup_push(cp, xfree);

	/*
	 * convert to cononical pathname (possibly resolving symlinks)
	 */
	canon = dcanon(cp, cp);
	cleanup_ignore(cp);
	cleanup_until(cp);
	cleanup_push(canon, xfree);

	setcopy(vp, canon, VAR_READWRITE);	/* have to save the new val */

	/* and now mirror home with HOME */
	tsetenv(STRKHOME, canon);
	/* fix directory stack for new tilde home */
	dtilde();
	cleanup_until(canon);
    }
    else if (eq(vp, STRedit)) {
	editing = 1;
	noediting = 0;
	/* PWP: add more stuff in here later */
    }
    else if (eq(vp, STRvimode)) {
	VImode = 1;
	update_wordchars();
    }
    else if (eq(vp, STRshlvl)) {
	tsetenv(STRKSHLVL, varval(vp));
    }
    else if (eq(vp, STRignoreeof)) {
	Char *cp;
	numeof = 0;
    	for ((cp = varval(STRignoreeof)); cp && *cp; cp++) {
	    if (!Isdigit(*cp)) {
		numeof = 0;
		break;
	    }
	    numeof = numeof * 10 + *cp - '0';
	}
	if (numeof <= 0) numeof = 26;	/* Sanity check */
    } 
    else if (eq(vp, STRbackslash_quote)) {
	bslash_quote = 1;
    }
    else if (eq(vp, STRcompat_expr)) {
	compat_expr = 1;
    }
    else if (eq(vp, STRdirstack)) {
	dsetstack();
    }
    else if (eq(vp, STRrecognize_only_executables)) {
	tw_cmd_free();
    }
    else if (eq(vp, STRkillring)) {
	SetKillRing((int)getn(varval(vp)));
    }
    else if (eq(vp, STRhistory)) {
	sethistory((int)getn(varval(vp)));
    }
#ifndef HAVENOUTMP
    else if (eq(vp, STRwatch)) {
	resetwatch();
    }
#endif /* HAVENOUTMP */
    else if (eq(vp, STRimplicitcd)) {
	implicit_cd = ((eq(varval(vp), STRverbose)) ? 2 : 1);
    }
    else if (eq(vp, STRcdtohome)) {
	cdtohome = 1;
    }
#ifdef COLOR_LS_F
    else if (eq(vp, STRcolor)) {
	set_color_context();
    }
#endif /* COLOR_LS_F */
#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE)
    else if(eq(vp, CHECK_MBYTEVAR) || eq(vp, STRnokanji)) {
	update_dspmbyte_vars();
    }
#endif
#ifdef NLS_CATALOGS
    else if (eq(vp, STRcatalog)) {
	nlsclose();
	nlsinit();
    }
#if defined(FILEC) && defined(TIOCSTI)
    else if (eq(vp, STRfilec))
	filec = 1;
#endif
#endif /* NLS_CATALOGS */
}
Exemplo n.º 24
0
/*ARGSUSED*/
void
dolet(Char **v, struct command *dummy)
{
    Char *p;
    Char   *vp, c, op;
    int    hadsub;
    int     subscr;

    USE(dummy);
    v++;
    p = *v++;
    if (p == 0) {
	prvars();
	return;
    }
    do {
	hadsub = 0;
	vp = p;
	if (letter(*p))
	    for (; alnum(*p); p++)
		continue;
	if (vp == p || !letter(*vp))
	    stderror(ERR_NAME | ERR_VARBEGIN);
	if (*p == '[') {
	    hadsub++;
	    p = getinx(p, &subscr);
	}
	if (*p == 0 && *v)
	    p = *v++;
	if ((op = *p) != 0)
	    *p++ = 0;
	else
	    stderror(ERR_NAME | ERR_ASSIGN);

	/*
	 * if there is no expression after the '=' then print a "Syntax Error"
	 * message - strike
	 */
	if (*p == '\0' && *v == NULL)
	    stderror(ERR_NAME | ERR_ASSIGN);

	vp = Strsave(vp);
	cleanup_push(vp, xfree);
	if (op == '=') {
	    c = '=';
	    p = xset(p, &v);
	}
	else {
	    c = *p++;
	    if (any("+-", c)) {
		if (c != op || *p)
		    stderror(ERR_NAME | ERR_UNKNOWNOP);
		p = Strsave(STR1);
	    }
	    else {
		if (any("<>", op)) {
		    if (c != op)
			stderror(ERR_NAME | ERR_UNKNOWNOP);
		    stderror(ERR_NAME | ERR_SYNTAX);
		}
		if (c != '=')
		    stderror(ERR_NAME | ERR_UNKNOWNOP);
		p = xset(p, &v);
	    }
	}
	cleanup_push(p, xfree);
	if (op == '=') {
	    if (hadsub)
		asx(vp, subscr, p);
	    else
		setv(vp, p, VAR_READWRITE);
	    cleanup_ignore(p);
	}
	else if (hadsub) {
	    struct varent *gv = getvx(vp, subscr);
	    Char *val;

	    val = operate(op, gv->vec[subscr - 1], p);
	    cleanup_push(val, xfree);
	    asx(vp, subscr, val);
	    cleanup_ignore(val);
	    cleanup_until(val);
	}
	else {
	    Char *val;

	    val = operate(op, varval(vp), p);
	    cleanup_push(val, xfree);
	    setv(vp, val, VAR_READWRITE);
	    cleanup_ignore(val);
	    cleanup_until(val);
	}
	update_vars(vp);
	cleanup_until(vp);
    } while ((p = *v++) != NULL);
}
Exemplo n.º 25
0
/*ARGSUSED*/
void
doset(Char **v, struct command *c)
{
    Char *p;
    Char   *vp;
    Char  **vecp;
    int    hadsub;
    int     subscr;
    int	    flags = VAR_READWRITE;
    int    first_match = 0;
    int    last_match = 0;
    int    changed = 0;

    USE(c);
    v++;
    do {
	changed = 0;
	/*
	 * Readonly addition From: Tim P. Starrin <*****@*****.**>
	 */
	if (*v && eq(*v, STRmr)) {
	    flags = VAR_READONLY;
	    v++;
	    changed = 1;
	}
	if (*v && eq(*v, STRmf) && !last_match) {
	    first_match = 1;
	    v++;
	    changed = 1;
	}
	if (*v && eq(*v, STRml) && !first_match) {
	    last_match = 1;
	    v++;
	    changed = 1;
	}
    } while(changed);
    p = *v++;
    if (p == 0) {
	plist(&shvhed, flags);
	return;
    }
    do {
	hadsub = 0;
	vp = p;
	if (!letter(*p))
	    stderror(ERR_NAME | ERR_VARBEGIN);
	do {
	    p++;
	} while (alnum(*p));
	if (*p == '[') {
	    hadsub++;
	    p = getinx(p, &subscr);
	}
	if (*p != '\0' && *p != '=')
	    stderror(ERR_NAME | ERR_VARALNUM);
	if (*p == '=') {
	    *p++ = '\0';
	    if (*p == '\0' && *v != NULL && **v == '(')
		p = *v++;
	}
	else if (*v && eq(*v, STRequal)) {
	    if (*++v != NULL)
		p = *v++;
	}
	if (eq(p, STRLparen)) {
	    Char **e = v;

	    if (hadsub)
		stderror(ERR_NAME | ERR_SYNTAX);
	    for (;;) {
		if (!*e)
		    stderror(ERR_NAME | ERR_MISSING, ')');
		if (**e == ')')
		    break;
		e++;
	    }
	    p = *e;
	    *e = 0;
	    vecp = saveblk(v);
	    if (first_match)
	       flags |= VAR_FIRST;
	    else if (last_match)
	       flags |= VAR_LAST;

	    set1(vp, vecp, &shvhed, flags);
	    *e = p;
	    v = e + 1;
	}
	else if (hadsub) {
	    Char *copy;

	    copy = Strsave(p);
	    cleanup_push(copy, xfree);
	    asx(vp, subscr, copy);
	    cleanup_ignore(copy);
	    cleanup_until(copy);
	}
	else
	    setv(vp, Strsave(p), flags);
	update_vars(vp);
    } while ((p = *v++) != NULL);
}
Exemplo n.º 26
0
/* fix_version():
 *	Print a reasonable version string, printing all compile time
 *	options that might affect the user.
 */
void
fix_version(void)
{
#ifdef WIDE_STRINGS
# define SSSTR "wide"
#elif defined (SHORT_STRINGS)
# define SSSTR "8b"
#else
# define SSSTR "7b"
#endif 
#ifdef NLS
# define NLSSTR ",nls"
#else
# define NLSSTR ""
#endif 
#ifdef LOGINFIRST
# define LFSTR ",lf"
#else
# define LFSTR ""
#endif 
#ifdef DOTLAST
# define DLSTR ",dl"
#else
# define DLSTR ""
#endif 
#ifdef VIDEFAULT
# define VISTR ",vi"
#else
# define VISTR ""
#endif 
#ifdef TESLA
# define DTRSTR ",dtr"
#else
# define DTRSTR ""
#endif 
#ifdef KAI
# define BYESTR ",bye"
#else
# define BYESTR ""
#endif 
#ifdef AUTOLOGOUT
# define ALSTR ",al"
#else
# define ALSTR ""
#endif 
#ifdef KANJI
# define KANSTR ",kan"
#else
# define KANSTR ""
#endif 
#ifdef SYSMALLOC
# define SMSTR	",sm"
#else
# define SMSTR  ""
#endif 
#ifdef HASHBANG
# define HBSTR	",hb"
#else
# define HBSTR  ""
#endif 
#ifdef NEWGRP
# define NGSTR	",ng"
#else
# define NGSTR	""
#endif
#ifdef REMOTEHOST
# define RHSTR	",rh"
#else
# define RHSTR	""
#endif
#ifdef AFS
# define AFSSTR	",afs"
#else
# define AFSSTR	""
#endif
#ifdef NODOT
# define NDSTR	",nd"
#else
# define NDSTR	""
#endif
#ifdef COLOR_LS_F
# define COLORSTR ",color"
#else /* ifndef COLOR_LS_F */
# define COLORSTR ""
#endif /* COLOR_LS_F */
#ifdef DSPMBYTE
# define DSPMSTR ",dspm"
#else
# define DSPMSTR ""
#endif
#ifdef COLORCAT
# define CCATSTR ",ccat"
#else
# define CCATSTR ""
#endif
#if defined(FILEC) && defined(TIOCSTI)
# define FILECSTR ",filec"
#else
# define FILECSTR ""
#endif
/* if you want your local version to say something */
#ifndef LOCALSTR
# define LOCALSTR ""
#endif /* LOCALSTR */
    char    *version;
    const Char *machtype = tgetenv(STRMACHTYPE);
    const Char *vendor   = tgetenv(STRVENDOR);
    const Char *ostype   = tgetenv(STROSTYPE);

    if (vendor == NULL)
	vendor = STRunknown;
    if (machtype == NULL)
	machtype = STRunknown;
    if (ostype == NULL)
	ostype = STRunknown;


    version = xasprintf(
                        "%s"
#ifdef CATCH_EXEC
   "(%s)"
#endif
" %d.%.2d.%.2d (%s) %s (%S-%S-%S) options %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",    PROG_NAME,
#ifdef CATCH_EXEC
        GDI_VERSION,
#endif
	     REV, VERS, PATCHLEVEL, ORIGIN, DATE, machtype, vendor, ostype,
	     SSSTR, NLSSTR, LFSTR, DLSTR, VISTR, DTRSTR, BYESTR,
	     ALSTR, KANSTR, SMSTR, HBSTR, NGSTR, RHSTR, AFSSTR, NDSTR,
	     COLORSTR, DSPMSTR, CCATSTR, FILECSTR, LOCALSTR);
    cleanup_push(version, xfree);
    setcopy(STRversion, str2short(version), VAR_READWRITE);
    cleanup_until(version);
    version = xasprintf("%d.%.2d.%.2d", REV, VERS, PATCHLEVEL);
    cleanup_push(version, xfree);
    setcopy(STRtcsh, str2short(version), VAR_READWRITE);
    cleanup_until(version);
}
Exemplo n.º 27
0
/*ARGSUSED*/
void
dolist(Char **v, struct command *c)
{
    Char **globbed;
    int     i, k, ret = 0;
    struct stat st;

    USE(c);
    if (*++v == NULL) {
	struct Strbuf word = Strbuf_INIT;

	Strbuf_terminate(&word);
	cleanup_push(&word, Strbuf_cleanup);
	(void) t_search(&word, LIST, TW_ZERO, 0, STRNULL, 0);
	cleanup_until(&word);
	return;
    }
    v = glob_all_or_error(v);
    globbed = v;
    cleanup_push(globbed, blk_cleanup);
    for (k = 0; v[k] != NULL && v[k][0] != '-'; k++)
	continue;
    if (v[k]) {
	/*
	 * We cannot process a flag therefore we let ls do it right.
	 */
	Char *lspath;
	struct command *t;
	struct wordent cmd, *nextword, *lastword;
	Char   *cp;
	struct varent *vp;

	if (setintr) {
	    pintr_disabled++;
	    cleanup_push(&pintr_disabled, disabled_cleanup);
	}
	if (seterr) {
	    xfree(seterr);
	    seterr = NULL;
	}

	lspath = STRls;
	STRmCF[1] = 'C';
	STRmCF[3] = '\0';
	/* Look at listflags, to add -A to the flags, to get a path
	   of ls if necessary */
	if ((vp = adrof(STRlistflags)) != NULL && vp->vec != NULL &&
	    vp->vec[0] != STRNULL) {
	    if (vp->vec[1] != NULL && vp->vec[1][0] != '\0')
		lspath = vp->vec[1];
	    for (cp = vp->vec[0]; *cp; cp++)
		switch (*cp) {
		case 'x':
		    STRmCF[1] = 'x';
		    break;
		case 'a':
		    STRmCF[3] = 'a';
		    break;
		case 'A':
		    STRmCF[3] = 'A';
		    break;
		default:
		    break;
		}
	}

	cmd.word = STRNULL;
	lastword = &cmd;
	nextword = xcalloc(1, sizeof cmd);
	nextword->word = Strsave(lspath);
	lastword->next = nextword;
	nextword->prev = lastword;
	lastword = nextword;
	nextword = xcalloc(1, sizeof cmd);
	nextword->word = Strsave(STRmCF);
	lastword->next = nextword;
	nextword->prev = lastword;
#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE)
	if (dspmbyte_ls) {
	    lastword = nextword;
	    nextword = xcalloc(1, sizeof cmd);
	    nextword->word = Strsave(STRmmliteral);
	    lastword->next = nextword;
	    nextword->prev = lastword;
	}
#endif
#ifdef COLOR_LS_F
	if (color_context_ls) {
	    lastword = nextword;
	    nextword = xcalloc(1, sizeof cmd);
	    nextword->word = Strsave(STRmmcolormauto);
	    lastword->next = nextword;
	    nextword->prev = lastword;
	}
#endif /* COLOR_LS_F */
	lastword = nextword;
	for (cp = *v; cp; cp = *++v) {
	    nextword = xcalloc(1, sizeof cmd);
	    nextword->word = quote(Strsave(cp));
	    lastword->next = nextword;
	    nextword->prev = lastword;
	    lastword = nextword;
	}
	lastword->next = &cmd;
	cmd.prev = lastword;
	cleanup_push(&cmd, lex_cleanup);

	/* build a syntax tree for the command. */
	t = syntax(cmd.next, &cmd, 0);
	cleanup_push(t, syntax_cleanup);
	if (seterr)
	    stderror(ERR_OLD);
	/* expand aliases like process() does */
	/* alias(&cmd); */
	/* execute the parse tree. */
	execute(t, tpgrp > 0 ? tpgrp : -1, NULL, NULL, FALSE);
	/* done. free the lex list and parse tree. */
	cleanup_until(&cmd);
	if (setintr)
	    cleanup_until(&pintr_disabled);
    }
    else {
	Char   *dp, *tmp;
	struct Strbuf buf = Strbuf_INIT;

	cleanup_push(&buf, Strbuf_cleanup);
	for (k = 0, i = 0; v[k] != NULL; k++) {
	    tmp = dnormalize(v[k], symlinks == SYM_IGNORE);
	    cleanup_push(tmp, xfree);
	    dp = Strend(tmp) - 1;
	    if (*dp == '/' && dp != tmp)
#ifdef apollo
		if (dp != &tmp[1])
#endif /* apollo */
		*dp = '\0';
	    if (stat(short2str(tmp), &st) == -1) {
		int err;

		err = errno;
		if (k != i) {
		    if (i != 0)
			xputchar('\n');
		    print_by_column(STRNULL, &v[i], k - i, FALSE);
		}
		haderr = 1;
		xprintf("%S: %s.\n", tmp, strerror(err));
		haderr = 0;
		i = k + 1;
		ret = 1;
	    }
	    else if (S_ISDIR(st.st_mode)) {
		Char   *cp;

		if (k != i) {
		    if (i != 0)
			xputchar('\n');
		    print_by_column(STRNULL, &v[i], k - i, FALSE);
		}
		if (k != 0 && v[1] != NULL)
		    xputchar('\n');
		xprintf("%S:\n", tmp);
		buf.len = 0;
		for (cp = tmp; *cp; cp++)
		    Strbuf_append1(&buf, (*cp | QUOTE));
		Strbuf_terminate(&buf);
		dp = &buf.s[buf.len - 1];
		if (
#ifdef WINNT_NATIVE
		    (*dp != (Char) (':' | QUOTE)) &&
#endif /* WINNT_NATIVE */
		    (*dp != (Char) ('/' | QUOTE))) {
		    Strbuf_append1(&buf, '/');
		    Strbuf_terminate(&buf);
		} else 
		    *dp &= TRIM;
		(void) t_search(&buf, LIST, TW_ZERO, 0, STRNULL, 0);
		i = k + 1;
	    }
	    cleanup_until(tmp);
	}
	cleanup_until(&buf);
	if (k != i) {
	    if (i != 0)
		xputchar('\n');
	    print_by_column(STRNULL, &v[i], k - i, FALSE);
	}
	if (ret)
	    stderror(ERR_SILENT);
    }

    cleanup_until(globbed);
}
Exemplo n.º 28
0
/*
 * Karl Kleinpaste, 21oct1983.
 * Set up a one-word alias command, for use for special things.
 * This code is based on the mainline of process().
 */
void
aliasrun(int cnt, Char *s1, Char *s2)
{
    struct wordent w, *new1, *new2;	/* for holding alias name */
    struct command *t = NULL;
    jmp_buf_t osetexit;
    int status;
    size_t omark;

    getexit(osetexit);
    if (seterr) {
	xfree(seterr);
	seterr = NULL;	/* don't repeatedly print err msg. */
    }
    w.word = STRNULL;
    new1 = xcalloc(1, sizeof w);
    new1->word = Strsave(s1);
    if (cnt == 1) {
	/* build a lex list with one word. */
	w.next = w.prev = new1;
	new1->next = new1->prev = &w;
    }
    else {
	/* build a lex list with two words. */
	new2 = xcalloc(1, sizeof w);
	new2->word = Strsave(s2);
	w.next = new2->prev = new1;
	new1->next = w.prev = new2;
	new1->prev = new2->next = &w;
    }
    cleanup_push(&w, lex_cleanup);

    /* Save the old status */
    status = getn(varval(STRstatus));

    /* expand aliases like process() does. */
    alias(&w);
    /* build a syntax tree for the command. */
    t = syntax(w.next, &w, 0);
    cleanup_push(t, syntax_cleanup);
    if (seterr)
	stderror(ERR_OLD);

    psavejob();
    cleanup_push(&cnt, psavejob_cleanup); /* cnt is used only as a marker */

    /* catch any errors here */
    omark = cleanup_push_mark();
    if (setexit() == 0)
	/* execute the parse tree. */
	/*
	 * From: Michael Schroeder <*****@*****.**>
	 * was execute(t, tpgrp);
	 */
	execute(t, tpgrp > 0 ? tpgrp : -1, NULL, NULL, TRUE);
    /* reset the error catcher to the old place */
    cleanup_pop_mark(omark);
    resexit(osetexit);
    if (haderr) {
	haderr = 0;
	/*
	 * Either precmd, or cwdcmd, or periodic had an error. Call it again so
	 * that it is removed
	 */
	if (precmd_active)
	    precmd();
	if (postcmd_active)
	    postcmd();
#ifdef notdef
	/*
	 * XXX: On the other hand, just interrupting them causes an error too.
	 * So if we hit ^C in the middle of cwdcmd or periodic the alias gets
	 * removed. We don't want that. Note that we want to remove precmd
	 * though, cause that could lead into an infinite loop. This should be
	 * fixed correctly, but then haderr should give us the whole exit
	 * status not just true or false.
	 */
	else if (cwdcmd_active)
	    cwd_cmd();
	else if (beepcmd_active)
	    beep_cmd();
	else if (periodic_active)
	    period_cmd();
#endif /* notdef */
    }
    cleanup_until(&w);
    pendjob();
    /* Restore status */
    setv(STRstatus, putn((tcsh_number_t)status), VAR_READWRITE);
}
Exemplo n.º 29
0
static void
backeval(struct blk_buf *bb, struct Strbuf *word, Char *cp, int literal)
{
    ssize_t icnt;
    Char c, *ip;
    struct command faket;
    int    hadnl;
    int     pvec[2], quoted;
    Char   *fakecom[2], ibuf[BUFSIZE];
    char    tibuf[BUFSIZE];

    hadnl = 0;
    icnt = 0;
    quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0;
    faket.t_dtyp = NODE_COMMAND;
    faket.t_dflg = F_BACKQ;
    faket.t_dlef = 0;
    faket.t_drit = 0;
    faket.t_dspr = 0;
    faket.t_dcom = fakecom;
    fakecom[0] = STRfakecom1;
    fakecom[1] = 0;

    /*
     * We do the psave job to temporarily change the current job so that the
     * following fork is considered a separate job.  This is so that when
     * backquotes are used in a builtin function that calls glob the "current
     * job" is not corrupted.  We only need one level of pushed jobs as long as
     * we are sure to fork here.
     */
    psavejob();
    cleanup_push(&faket, psavejob_cleanup); /* faket is only a marker */

    /*
     * It would be nicer if we could integrate this redirection more with the
     * routines in sh.sem.c by doing a fake execute on a builtin function that
     * was piped out.
     */
    mypipe(pvec);
    cleanup_push(&pvec[0], open_cleanup);
    cleanup_push(&pvec[1], open_cleanup);
    if (pfork(&faket, -1) == 0) {
	jmp_buf_t osetexit;
	struct command *t;
	size_t omark;

	xclose(pvec[0]);
	(void) dmove(pvec[1], 1);
	(void) dmove(SHDIAG,  2);
	initdesc();
	closem();
	arginp = cp;
	for (arginp = cp; *cp; cp++) {
	    *cp &= TRIM;
	    if (is_set(STRcsubstnonl) && (*cp == '\n' || *cp == '\r'))
		*cp = ' ';
	}

        /*
	 * In the child ``forget'' everything about current aliases or
	 * eval vectors.
	 */
	alvec = NULL;
	evalvec = NULL;
	alvecp = NULL;
	evalp = NULL;

	omark = cleanup_push_mark();
	getexit(osetexit);
	for (;;) {
	    (void) setexit();
	    justpr = 0;
	    
	    if (haderr) {
		/* unwind */
		doneinp = 0;
		cleanup_pop_mark(omark);
		resexit(osetexit);
		reset();
	    }
	    if (seterr) {
		xfree(seterr);
		seterr = NULL;
	    }

	    (void) lex(&paraml);
	    cleanup_push(&paraml, lex_cleanup);
	    if (seterr)
		stderror(ERR_OLD);
	    alias(&paraml);
	    t = syntax(paraml.next, &paraml, 0);
	    if (t == NULL)
		return;
	    cleanup_push(t, syntax_cleanup);
	    /* The F_BACKQ flag must set so the job output is correct if
	     * printexitvalue is set.  If it's not set, the job output
	     * will have "Exit N" appended where N is the exit status. */
	    t->t_dflg = F_BACKQ|F_NOFORK;
	    if (seterr)
		stderror(ERR_OLD);
#ifdef SIGTSTP
	    signal(SIGTSTP, SIG_IGN);
#endif
#ifdef SIGTTIN
	    signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTTOU
	    signal(SIGTTOU, SIG_IGN);
#endif
	    execute(t, -1, NULL, NULL, TRUE);

	    cleanup_until(&paraml);
	}
    }
    cleanup_until(&pvec[1]);
    c = 0;
    ip = NULL;
    do {
	ssize_t     cnt = 0;
	char   *tmp;

	tmp = tibuf;
	for (;;) {
	    while (icnt == 0) {
		int     i, eof;

		ip = ibuf;
		icnt = xread(pvec[0], tmp, tibuf + BUFSIZE - tmp);
		eof = 0;
		if (icnt <= 0) {
		    if (tmp == tibuf)
			goto eof;
		    icnt = 0;
		    eof = 1;
		}
		icnt += tmp - tibuf;
		i = 0;
		tmp = tibuf;
		while (tmp < tibuf + icnt) {
		    int len;

		    len = normal_mbtowc(&ip[i], tmp, tibuf + icnt - tmp);
		    if (len == -1) {
		        reset_mbtowc();
		        if (!eof && (size_t)(tibuf + icnt - tmp) < MB_CUR_MAX) {
			    break; /* Maybe a partial character */
			}
			ip[i] = (unsigned char) *tmp | INVALID_BYTE; /* Error */
		    }
		    if (len <= 0)
		        len = 1;
		    i++;
		    tmp += len;
		}
		if (tmp != tibuf)
		    memmove (tibuf, tmp, tibuf + icnt - tmp);
		tmp = tibuf + (tibuf + icnt - tmp);
		icnt = i;
	    }
	    if (hadnl)
		break;
	    --icnt;
	    c = (*ip++ & TRIM);
	    if (c == 0)
		break;
#if defined(WINNT_NATIVE) || defined(__CYGWIN__)
	    if (c == '\r')
	    	c = ' ';
#endif /* WINNT_NATIVE || __CYGWIN__ */
	    if (c == '\n') {
		/*
		 * Continue around the loop one more time, so that we can eat
		 * the last newline without terminating this word.
		 */
		hadnl = 1;
		continue;
	    }
	    if (!quoted && (c == ' ' || c == '\t'))
		break;
	    cnt++;
	    Strbuf_append1(word, c | quoted);
	}
	/*
	 * Unless at end-of-file, we will form a new word here if there were
	 * characters in the word, or in any case when we take text literally.
	 * If we didn't make empty words here when literal was set then we
	 * would lose blank lines.
	 */
	if (c != 0 && (cnt || literal))
	    pword(bb, word);
	hadnl = 0;
    } while (c > 0);
 eof:
    cleanup_until(&pvec[0]);
    pwait();
    cleanup_until(&faket); /* psavejob_cleanup(); */
}
Exemplo n.º 30
0
/* tw_complete():
 *	Return the appropriate completion for the command
 *
 *	valid completion strings are:
 *	p/<range>/<completion>/[<suffix>/]	positional
 *	c/<pattern>/<completion>/[<suffix>/]	current word ignore pattern
 *	C/<pattern>/<completion>/[<suffix>/]	current word with pattern
 *	n/<pattern>/<completion>/[<suffix>/]	next word
 *	N/<pattern>/<completion>/[<suffix>/]	next-next word
 */
int
tw_complete(const Char *line, Char **word, Char **pat, int looking, eChar *suf)
{
    Char *buf, **vec, **wl;
    static Char nomatch[2] = { (Char) ~0, 0x00 };
    const Char *ptr;
    size_t wordno;
    int n;

    buf = Strsave(line);
    cleanup_push(buf, xfree);
    /* Single-character words, empty current word, terminating NULL */
    wl = xmalloc(((Strlen(line) + 1) / 2 + 2) * sizeof (*wl));
    cleanup_push(wl, xfree);

    /* find the command */
    if ((wl[0] = tw_tok(buf)) == NULL || wl[0] == INVPTR) {
	cleanup_until(buf);
	return TW_ZERO;
    }

    /*
     * look for hardwired command completions using a globbing
     * search and for arguments using a normal search.
     */
    if ((vec = tw_find(wl[0], &completions, (looking == TW_COMMAND)))
	== NULL) {
	cleanup_until(buf);
	return looking;
    }

    /* tokenize the line one more time :-( */
    for (wordno = 1; (wl[wordno] = tw_tok(NULL)) != NULL &&
		      wl[wordno] != INVPTR; wordno++)
	continue;

    if (wl[wordno] == INVPTR) {		/* Found a meta character */
	cleanup_until(buf);
	return TW_ZERO;			/* de-activate completions */
    }
#ifdef TDEBUG
    {
	size_t i;
	for (i = 0; i < wordno; i++)
	    xprintf("'%s' ", short2str(wl[i]));
	xprintf("\n");
    }
#endif /* TDEBUG */

    /* if the current word is empty move the last word to the next */
    if (**word == '\0') {
	wl[wordno] = *word;
	wordno++;
    }
    wl[wordno] = NULL;
	

#ifdef TDEBUG
    xprintf("\r\n");
    xprintf("  w#: %lu\n", (unsigned long)wordno);
    xprintf("line: %s\n", short2str(line));
    xprintf(" cmd: %s\n", short2str(wl[0]));
    xprintf("word: %s\n", short2str(*word));
    xprintf("last: %s\n", wordno >= 2 ? short2str(wl[wordno-2]) : "n/a");
    xprintf("this: %s\n", wordno >= 1 ? short2str(wl[wordno-1]) : "n/a");
#endif /* TDEBUG */
    
    for (;vec != NULL && (ptr = vec[0]) != NULL; vec++) {
	Char  *ran,	        /* The pattern or range X/<range>/XXXX/ */
	      *com,	        /* The completion X/XXXXX/<completion>/ */
	     *pos = NULL;	/* scratch pointer 			*/
	int   cmd, res;
        Char  sep;		/* the command and separator characters */
	int   exact;

	if (ptr[0] == '\0')
	    continue;

#ifdef TDEBUG
	xprintf("match %s\n", short2str(ptr));
#endif /* TDEBUG */

	switch (cmd = ptr[0]) {
	case 'N':
	    pos = (wordno < 3) ? nomatch : wl[wordno - 3];
	    break;
	case 'n':
	    pos = (wordno < 2) ? nomatch : wl[wordno - 2];
	    break;
	case 'c':
	case 'C':
	    pos = (wordno < 1) ? nomatch : wl[wordno - 1];
	    break;
	case 'p':
	    break;
	default:
	    stderror(ERR_COMPINV, CGETS(27, 1, "command"), cmd);
	    return TW_ZERO;
	}

	sep = ptr[1];
	if (!Ispunct(sep)) {
	    /* Truncates data if WIDE_STRINGS */
	    stderror(ERR_COMPINV, CGETS(27, 2, "separator"), (int)sep);
	    return TW_ZERO;
	}

	ptr = tw_dollar(&ptr[2], wl, wordno, &ran, sep,
			CGETS(27, 3, "pattern"));
	cleanup_push(ran, xfree);
	if (ran[0] == '\0')	/* check for empty pattern (disallowed) */
	{
	    stderror(ERR_COMPINC, cmd == 'p' ?  CGETS(27, 4, "range") :
		     CGETS(27, 3, "pattern"), "");
	    return TW_ZERO;
	}

	ptr = tw_dollar(ptr, wl, wordno, &com, sep,
			CGETS(27, 5, "completion"));
	cleanup_push(com, xfree);

	if (*ptr != '\0') {
	    if (*ptr == sep)
		*suf = CHAR_ERR;
	    else
		*suf = *ptr;
	}
	else
	    *suf = '\0';

#ifdef TDEBUG
	xprintf("command:    %c\nseparator:  %c\n", cmd, (int)sep);
	xprintf("pattern:    %s\n", short2str(ran));
	xprintf("completion: %s\n", short2str(com));
	xprintf("suffix:     ");
        switch (*suf) {
	case 0:
	    xprintf("*auto suffix*\n");
	    break;
	case CHAR_ERR:
	    xprintf("*no suffix*\n");
	    break;
	default:
	    xprintf("%c\n", (int)*suf);
	    break;
	}
#endif /* TDEBUG */

	exact = 0;
	switch (cmd) {
	case 'p':			/* positional completion */
#ifdef TDEBUG
	    xprintf("p: tw_pos(%s, %lu) = ", short2str(ran),
		    (unsigned long)wordno - 1);
	    xprintf("%d\n", tw_pos(ran, wordno - 1));
#endif /* TDEBUG */
	    if (!tw_pos(ran, wordno - 1)) {
		cleanup_until(ran);
		continue;
	    }
	    break;

	case 'N':			/* match with the next-next word */
	case 'n':			/* match with the next word */
	    exact = 1;
	    /*FALLTHROUGH*/
	case 'c':			/* match with the current word */
	case 'C':
#ifdef TDEBUG
	    xprintf("%c: ", cmd);
#endif /* TDEBUG */
	    if ((n = tw_match(pos, ran, exact)) < 0) {
		cleanup_until(ran);
		continue;
	    }
	    if (cmd == 'c')
		*word += n;
	    break;

	default:
	    abort();		       /* Cannot happen */
	}
	tsetenv(STRCOMMAND_LINE, line);
	res = tw_result(com, pat);
	Unsetenv(STRCOMMAND_LINE);
	cleanup_until(buf);
	return res;
    }
    cleanup_until(buf);
    *suf = '\0';
    return TW_ZERO;
} /* end tw_complete */