Example #1
0
mod_export void
trashzle(void)
{
    if (zleactive && !trashedzle) {
	/* This zrefresh() is just to get the main editor display right and *
	 * get the cursor in the right place.  For that reason, we disable  *
	 * list display (which would otherwise result in infinite           *
	 * recursion [at least, it would if zrefresh() didn't have its      *
	 * extra `inlist' check]).                                          */
	int sl = showinglist;
	showinglist = 0;
	trashedzle = 1;
	zrefresh();
	showinglist = sl;
	moveto(nlnct, 0);
	if (clearflag && tccan(TCCLEAREOD)) {
	    tcout(TCCLEAREOD);
	    clearflag = listshown = 0;
	}
	if (postedit)
	    fprintf(shout, "%s", unmeta(postedit));
	fflush(shout);
	resetneeded = 1;
	if (!(zlereadflags & ZLRF_NOSETTY))
	  settyinfo(&shttyinfo);
    }
    if (errflag)
	kungetct = 0;
}
Example #2
0
mod_export int
match_colour(const char **teststrp, int is_fg, int colour)
{
    int shft, on, named = 0, tc;

    if (teststrp) {
	if ((named = ialpha(**teststrp))) {
	    colour = match_named_colour(teststrp);
	    if (colour == 8) {
		/* default */
		return is_fg ? TXTNOFGCOLOUR : TXTNOBGCOLOUR;
	    }
	}
	else
	    colour = (int)zstrtol(*teststrp, (char **)teststrp, 10);
    }
    if (colour < 0 || colour >= 256)
	return -1;
    if (is_fg) {
	shft = TXT_ATTR_FG_COL_SHIFT;
	on = TXTFGCOLOUR;
	tc = TCFGCOLOUR;
    } else {
	shft = TXT_ATTR_BG_COL_SHIFT;
	on = TXTBGCOLOUR;
	tc = TCBGCOLOUR;
    }
    /*
     * Try termcap for numbered characters if posible.
     * Don't for named characters, since our best bet
     * of getting the names right is with ANSI sequences.
     */
    if (!named && tccan(tc)) {
	if (tccolours >= 0 && colour >= tccolours) {
	    /*
	     * Out of range of termcap colours.
	     * Can we assume ANSI colours work?
	     */
	    if (colour > 7)
		return -1; /* No. */
	} else {
	    /*
	     * We can handle termcap colours and the number
	     * is in range, so use termcap.
	     */
	    on |= is_fg ? TXT_ATTR_FG_TERMCAP :
		TXT_ATTR_BG_TERMCAP;
	}
    }
    return on | (colour << shft);
}
Example #3
0
mod_export void
tsetcap(int cap, int flags)
{
    if (tccan(cap) && !isset(SINGLELINEZLE) &&
        !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) {
	switch (flags & TSC_OUTPUT_MASK) {
	case TSC_RAW:
	    tputs(tcstr[cap], 1, putraw);
	    break;
	case 0:
	default:
	    tputs(tcstr[cap], 1, putshout);
	    break;
	case TSC_PROMPT:
	    if (!bv->dontcount) {
		addbufspc(1);
		*bv->bp++ = Inpar;
	    }
	    tputs(tcstr[cap], 1, putstr);
	    if (!bv->dontcount) {
		int glitch = 0;

		if (cap == TCSTANDOUTBEG || cap == TCSTANDOUTEND)
		    glitch = tgetnum("sg");
		else if (cap == TCUNDERLINEBEG || cap == TCUNDERLINEEND)
		    glitch = tgetnum("ug");
		if(glitch < 0)
		    glitch = 0;
		addbufspc(glitch + 1);
		while(glitch--)
		    *bv->bp++ = Nularg;
		*bv->bp++ = Outpar;
	    }
	    break;
	}

	if (flags & TSC_DIRTY) {
	    flags &= ~TSC_DIRTY;
	    if (txtisset(TXTBOLDFACE) && cap != TCBOLDFACEBEG)
		tsetcap(TCBOLDFACEBEG, flags);
	    if (txtisset(TXTSTANDOUT))
		tsetcap(TCSTANDOUTBEG, flags);
	    if (txtisset(TXTUNDERLINE))
		tsetcap(TCUNDERLINEBEG, flags);
	}
    }
}
Example #4
0
mod_export void
set_colour_attribute(int atr, int fg_bg, int flags)
{
    char *ptr;
    int do_free, is_prompt = (flags & TSC_PROMPT) ? 1 : 0;
    int colour, tc, def, use_termcap;

    if (fg_bg == COL_SEQ_FG) {
	colour = txtchangeget(atr, TXT_ATTR_FG_COL);
	tc = TCFGCOLOUR;
	def = txtchangeisset(atr, TXTNOFGCOLOUR);
	use_termcap = txtchangeisset(atr, TXT_ATTR_FG_TERMCAP);
    } else {
	colour = txtchangeget(atr, TXT_ATTR_BG_COL);
	tc = TCBGCOLOUR;
	def = txtchangeisset(atr, TXTNOBGCOLOUR);
	use_termcap = txtchangeisset(atr, TXT_ATTR_BG_TERMCAP);
    }

    /*
     * If we're not restoring the default, and either have a
     * colour value that is too large for ANSI, or have been told
     * to use the termcap sequence, try to use the termcap sequence.
     *
     * We have already sanitised the values we allow from the
     * highlighting variables, so much of this shouldn't be
     * necessary at this point, but we might as well be safe.
     */
    if (!def && (colour > 7 || use_termcap)) {
	/*
	 * We can if it's available, and either we couldn't get
	 * the maximum number of colours, or the colour is in range.
	 */
	if (tccan(tc) && (tccolours < 0 || colour < tccolours))
	{
	    if (is_prompt)
	    {
		if (!bv->dontcount) {
		    addbufspc(1);
		    *bv->bp++ = Inpar;
		}
		tputs(tgoto(tcstr[tc], colour, colour), 1, putstr);
		if (!bv->dontcount) {
		    addbufspc(1);
		    *bv->bp++ = Outpar;
		}
	    } else {
		tputs(tgoto(tcstr[tc], colour, colour), 1, putshout);
	    }
	    /* That worked. */
	    return;
	}
	/*
	 * Nope, that didn't work.
	 * If 0 to 7, assume standard ANSI works, otherwise it won't.
	 */
	if (colour > 7)
	    return;
    }

    if ((do_free = (colseq_buf == NULL))) {
	/* This can happen when moving the cursor in trashzle() */
	allocate_colour_buffer();
    }

    strcpy(colseq_buf, fg_bg_sequences[fg_bg].start);

    ptr = colseq_buf + strlen(colseq_buf);
    if (def) {
	strcpy(ptr, fg_bg_sequences[fg_bg].def);
	while (*ptr)
	    ptr++;
    } else
	*ptr++ = colour + '0';
    strcpy(ptr, fg_bg_sequences[fg_bg].end);

    if (is_prompt) {
	if (!bv->dontcount) {
	    addbufspc(1);
	    *bv->bp++ = Inpar;
	}
	tputs(colseq_buf, 1, putstr);
	if (!bv->dontcount) {
	    addbufspc(1);
	    *bv->bp++ = Outpar;
	}
    } else
	tputs(colseq_buf, 1, putshout);

    if (do_free)
	free_colour_buffer();
}
Example #5
0
void
refresh(void)
{
    static int inlist;		/* avoiding recursion                        */
    int canscroll = 0,		/* number of lines we are allowed to scroll  */
        ln = 0,			/* current line we're working on	     */
        more_status = 0,	/* more stuff in status line		     */
        nvcs = 0, nvln = -1,	/* video cursor column and line		     */
        t0 = -1,		/* tmp					     */
        tosln = 0;		/* tmp in statusline stuff		     */
    unsigned char *s,		/* pointer into the video buffer	     */
             *t,			/* pointer into the real buffer		     */
             *sen,			/* pointer to end of the video buffer (eol)  */
             *scs;			/* pointer to cursor position in real buffer */
    char **qbuf;		/* tmp					     */

    /* If this is called from listmatches() (indirectly via trashzle()), and *
     * that was called from the end of refresh(), then we don't need to do   *
     * anything.  All this `inlist' code is actually unnecessary, but it     *
     * improves speed a little in a common case.                             */
    if (inlist)
        return;

#ifdef HAVE_SELECT
    cost = 0;			/* reset */
#endif

#ifndef WINNT
    /* Nov 96: <mason>  I haven't checked how complete this is.  sgtty stuff may
       or may not work */
    oxtabs = ((SGTTYFLAG & SGTABTYPE) == SGTABTYPE);

#else WINNT
    oxtabs = 0;
#endif WINNT
    cleareol = 0;		/* unset */
    more_start = more_end = 0;	/* unset */
    if (isset(SINGLELINEZLE) || lines < 3
            || (termflags & (TERM_NOUP | TERM_BAD | TERM_UNKNOWN)))
        termflags |= TERM_SHORT;
    else
        termflags &= ~TERM_SHORT;
    if (resetneeded) {
        onumscrolls = 0;
        setterm();
#if defined( TIOCGWINSZ) || defined(WINNT)
        if (winchanged) {
            moveto(0, 0);
            t0 = olnct;		/* this is to clear extra lines even when */
            winchanged = 0;	/* the terminal cannot TCCLEAREOD	  */
        }
#endif
        resetvideo();
        resetneeded = 0;	/* unset */
        oput_rpmpt = 0;		/* no right-prompt currently on screen */

        /* we probably should only have explicitly set attributes */
        tsetcap(TCALLATTRSOFF, 0);
        tsetcap(TCSTANDOUTEND, 0);
        tsetcap(TCUNDERLINEEND, 0);

        if (!clearflag)
            if (tccan(TCCLEAREOD))
                tcout(TCCLEAREOD);
            else
                cleareol = 1;   /* request: clear to end of line */
        if (t0 > -1)
            olnct = t0;
        if (termflags & TERM_SHORT)
            vcs = 0;
        else if (!clearflag && lpptlen)
            zwrite(lpptbuf, lpptlen, 1, shout);
        if (clearflag) {
            zputc('\r', shout);
            vcs = 0;
            moveto(0, pptw);
        }
        fflush(shout);
        clearf = clearflag;
    } else if (winw != columns || rwinh != lines)
        resetvideo();

    /* now winw equals columns and winh equals lines
       width comparisons can be made with winw, height comparisons with winh */

    if (termflags & TERM_SHORT) {
        singlerefresh();
        return;
    }

    if (cs < 0) {
#ifdef DEBUG
        fprintf(stderr, "BUG: negative cursor position\n");
        fflush(stderr);
#endif
        cs = 0;
    }
    scs = line + cs;
    numscrolls = 0;

    /* first, we generate the video line buffers so we know what to put on
       the screen - also determine final cursor position (nvln, nvcs) */

    /* Deemed necessary by PWS 1995/05/15 due to kill-line problems */
    if (!*nbuf)
        *nbuf = (char *)zalloc(winw + 2);

    s = (unsigned char *)(nbuf[ln = 0] + pptw);
    t = line;
    sen = (unsigned char *)(*nbuf + winw);
    for (; t < line+ll; t++) {
        if (t == scs)			/* if cursor is here, remember it */
            nvcs = s - (unsigned char *)(nbuf[nvln = ln]);

        if (*t == '\n')	{		/* newline */
            nbuf[ln][winw + 1] = '\0';	/* text not wrapped */
            nextline
        } else if (*t == '\t') {		/* tab */
Example #6
0
int
init_term(void)
{
#ifndef TGETENT_ACCEPTS_NULL
    static char termbuf[2048];	/* the termcap buffer */
#endif

    if (!*term)
	return termok = TERM_BAD;

    /* unset zle if using zsh under emacs */
    if (!strcmp(term, "emacs"))
	opts[USEZLE] = 0;

#ifdef TGETENT_ACCEPTS_NULL
    /* If possible, we let tgetent allocate its own termcap buffer */
    if (tgetent(NULL, term) != 1) {
#else
    if (tgetent(termbuf, term) != 1) {
#endif

	if (isset(INTERACTIVE))
	    zerr("can't find termcap info for %s", term, 0);
	errflag = 0;
	return termok = TERM_BAD;
    } else {
	char tbuf[1024], *pp;
	int t0;

	termok = TERM_OK;
	for (t0 = 0; t0 != TC_COUNT; t0++) {
	    pp = tbuf;
	    zsfree(tcstr[t0]);
	/* AIX tgetstr() ignores second argument */
	    if (!(pp = tgetstr(tccapnams[t0], &pp)))
		tcstr[t0] = NULL, tclen[t0] = 0;
	    else {
		tclen[t0] = strlen(pp);
		tcstr[t0] = (char *) zalloc(tclen[t0] + 1);
		memcpy(tcstr[t0], pp, tclen[t0] + 1);
	    }
	}

	/* check whether terminal has automargin (wraparound) capability */
	hasam = tgetflag("am");

	/* if there's no termcap entry for cursor up, use single line mode: *
	 * this is flagged by termok which is examined in zle_refresh.c     *
	 */
	if (!tccan(TCUP)) {
		tcstr[TCUP] = NULL;
		termok = TERM_NOUP;
	}

	/* if there's no termcap entry for cursor left, use \b. */
	if (!tccan(TCLEFT)) {
	    tcstr[TCLEFT] = ztrdup("\b");
	    tclen[TCLEFT] = 1;
	}

	/* if the termcap entry for down is \n, don't use it. */
	if (tccan(TCDOWN) && tcstr[TCDOWN][0] == '\n') {
	    tclen[TCDOWN] = 0;
	    zsfree(tcstr[TCDOWN]);
	    tcstr[TCDOWN] = NULL;
	}

	/* if there's no termcap entry for clear, use ^L. */
	if (!tccan(TCCLEARSCREEN)) {
	    tcstr[TCCLEARSCREEN] = ztrdup("\14");
	    tclen[TCCLEARSCREEN] = 1;
	}
    }
    return termok;
}

/* Initialize lots of global variables and hash tables */

/**/
void
setupvals(void)
{
    struct passwd *pswd;
    struct timezone dummy_tz;
    char *ptr;
#ifdef HAVE_GETRLIMIT
    int i;
#endif

    noeval = 0;
    curhist = 0;
    histsiz = DEFAULT_HISTSIZE;
    inithist();
    clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *));

    cmdstack = (unsigned char *) zalloc(256);
    cmdsp = 0;

    bangchar = '!';
    hashchar = '#';
    hatchar = '^';
    termok = TERM_BAD;
    curjob = prevjob = coprocin = coprocout = -1;
    gettimeofday(&shtimer, &dummy_tz);	/* init $SECONDS */
    srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */

    hostnam     = (char *) zalloc(256);
    gethostname(hostnam, 256);

    /* Set default path */
    path    = (char **) zalloc(sizeof(*path) * 5);
    path[0] = ztrdup("/bin");
    path[1] = ztrdup("/usr/bin");
    path[2] = ztrdup("/usr/ucb");
    path[3] = ztrdup("/usr/local/bin");
    path[4] = NULL;

    cdpath   = mkarray(NULL);
    manpath  = mkarray(NULL);
    fignore  = mkarray(NULL);
    fpath    = mkarray(NULL);
    mailpath = mkarray(NULL);
    watch    = mkarray(NULL);
    psvar    = mkarray(NULL);
#ifdef DYNAMIC
    module_path = mkarray(ztrdup(MODULE_DIR));
    modules = newlinklist();
#endif

    /* Set default prompts */
    if (opts[INTERACTIVE]) {
	prompt  = ztrdup("%m%# ");
	prompt2 = ztrdup("%_> ");
    } else {
	prompt = ztrdup("");
	prompt2 = ztrdup("");
    }
    prompt3 = ztrdup("?# ");
    prompt4 = ztrdup("+ ");
    sprompt = ztrdup("zsh: correct '%R' to '%r' [nyae]? ");

    ifs         = ztrdup(DEFAULT_IFS);
    wordchars   = ztrdup(DEFAULT_WORDCHARS);
    postedit    = ztrdup("");
    underscore  = ztrdup("");

    zoptarg = ztrdup("");
    zoptind = 1;
    schedcmds = NULL;

    ppid  = (long) getppid();
    mypid = (long) getpid();
    term  = ztrdup("");

#ifdef TIOCGWINSZ
    if (!(columns = shttyinfo.winsize.ws_col))
	columns = 80;
    if (columns < 2)
	opts[USEZLE] = 0;
    if (!(lines = shttyinfo.winsize.ws_row))
	lines = 24;
    if (lines < 2)
	opts[SINGLELINEZLE] = 1;
#else
    columns = 80;
    lines = 24;
#endif

    /* The following variable assignments cause zsh to behave more *
     * like Bourne and Korn shells when invoked as "sh" or "ksh".  *
     * NULLCMD=":" and READNULLCMD=":"                             */

    if (emulation == EMULATE_KSH || emulation == EMULATE_SH) {
	nullcmd     = ztrdup(":");
	readnullcmd = ztrdup(":");
    } else {
	nullcmd     = ztrdup("cat");
	readnullcmd = ztrdup("more");
    }

    /* We cache the uid so we know when to *
     * recheck the info for `USERNAME'     */
    cached_uid = getuid();

    /* Get password entry and set info for `HOME' and `USERNAME' */
    if ((pswd = getpwuid(cached_uid))) {
	home = metafy(pswd->pw_dir, -1, META_DUP);
	cached_username = ztrdup(pswd->pw_name);
    } else {
	home = ztrdup("/");
	cached_username = ztrdup("");
    }

    /* Try a cheap test to see if we can *
     * initialize `PWD' from `HOME'      */
    if (ispwd(home))
	pwd = ztrdup(home);
    else if ((ptr = zgetenv("PWD")) && ispwd(ptr))
	pwd = ztrdup(ptr);
    else
	pwd = metafy(zgetcwd(), -1, META_REALLOC);

    oldpwd = ztrdup(pwd);  /* initialize `OLDPWD' = `PWD' */
#ifdef __EMX__
    *cdrive = _getdrive();
    strcat(cdrive+1,":");
#endif

    inittyptab();     /* initialize the ztypes table */
    initlextabs();    /* initialize lexing tables    */

    createreswdtable();     /* create hash table for reserved words    */
    createaliastable();     /* create hash table for aliases           */
    createcmdnamtable();    /* create hash table for external commands */
    createshfunctable();    /* create hash table for shell functions   */
    createbuiltintable();   /* create hash table for builtin commands  */
    createnameddirtable();  /* create hash table for named directories */
    createparamtable();     /* create paramater hash table             */

#ifdef ZLE_MODULE
    add_dep("compctl", "zle");
    addbuiltin("bindkey", 0, NULL, 0, -1, "zle");
    addbuiltin("vared", 0, NULL, 1, 7, "zle");
    addbuiltin("compctl", 0, NULL, 0, -1, "compctl");
#endif

#ifdef HAVE_GETRLIMIT
    for (i = 0; i != RLIM_NLIMITS; i++) {
	getrlimit(i, current_limits + i);
	limits[i] = current_limits[i];
    }
#endif

    breaks = loops = 0;
    lastmailcheck = time(NULL);
    locallist = NULL;
    locallevel = sourcelevel = 0;
    trapreturn = 0;
    noerrexit = 0;
    nohistsave = 1;
    dirstack = newlinklist();
    bufstack = newlinklist();
    hsubl = hsubr = NULL;
    lastpid = 0;
    bshin = SHIN ? fdopen(SHIN, "r") : stdin;
    if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) {
#ifdef _IONBF
	setvbuf(stdin, NULL, _IONBF, 0);
#else
	setlinebuf(stdin);
#endif
    }

    times(&shtms);
}

/* Initialize signal handling */

/**/
void
init_signals(void)
{
    intr();

#ifndef QDEBUG
    signal_ignore(SIGQUIT);
#endif

    install_handler(SIGHUP);
    install_handler(SIGCHLD);
    if (interact) {
	install_handler(SIGALRM);
#ifdef SIGWINCH
	install_handler(SIGWINCH);
#endif
	signal_ignore(SIGTERM);
    }
    if (jobbing) {
	long ttypgrp;

#ifndef __EMX__
	while ((ttypgrp = gettygrp()) != -1 && ttypgrp != mypgrp)
	    kill(0, SIGTTIN);
#endif
	if (ttypgrp == -1) {
	    opts[MONITOR] = 0;
	} else {
#ifndef __EMX__
	    signal_ignore(SIGTTOU);
	    signal_ignore(SIGTSTP);
	    signal_ignore(SIGTTIN);
#endif
	    signal_ignore(SIGPIPE);
	    attachtty(mypgrp);
	}
    }
    if (islogin) {
	signal_setmask(signal_mask(0));
    } else if (interact) {
	sigset_t set;

	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGQUIT);
	signal_unblock(set);
    }
}