diff options
Diffstat (limited to 'Src/init.c')
-rw-r--r-- | Src/init.c | 936 |
1 files changed, 936 insertions, 0 deletions
diff --git a/Src/init.c b/Src/init.c new file mode 100644 index 000000000..33496adc6 --- /dev/null +++ b/Src/init.c @@ -0,0 +1,936 @@ +/* + * init.c - main loop and initialization routines + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1992-1997 Paul Falstad + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Paul Falstad or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Paul Falstad and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Paul Falstad and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Paul Falstad and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "zsh.mdh" +#include "init.pro" + +#include "zshpaths.h" +#include "zshxmods.h" + +/**/ +int noexitct = 0; + +/* what level of sourcing we are at */ + +/**/ +int sourcelevel; + +/* the shell tty fd */ + +/**/ +int SHTTY; + +/* the FILE attached to the shell tty */ + +/**/ +FILE *shout; + +/* termcap strings */ + +/**/ +char *tcstr[TC_COUNT]; + +/* lengths of each termcap string */ + +/**/ +int tclen[TC_COUNT]; + +/* Values of the li, co and am entries */ + +/**/ +int tclines, tccolumns, hasam; + +#ifdef DEBUG +/* depth of allocation type stack */ + +/**/ +int alloc_stackp; +#endif + +/* keep executing lists until EOF found */ + +/**/ +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) || + (tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) || + 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; + } + popheap(); +} + +static char *cmd; +static int restricted; + +/**/ +void +parseargs(char **argv) +{ + char **x; + int action, optno; + LinkList paramlist; + int bourne = (emulation == EMULATE_KSH || emulation == EMULATE_SH); + + argzero = *argv++; + SHIN = 0; + + /* There's a bit of trickery with opts[INTERACTIVE] here. It starts * + * at a value of 2 (instead of 1) or 0. If it is explicitly set on * + * the command line, it goes to 1 or 0. If input is coming from * + * somewhere that normally makes the shell non-interactive, we do * + * "opts[INTERACTIVE] &= 1", so that only a *default* on state will * + * be changed. At the end of the function, a value of 2 gets * + * changed to 1. */ + opts[INTERACTIVE] = isatty(0) ? 2 : 0; + opts[SHINSTDIN] = 0; + opts[SINGLECOMMAND] = 0; + + /* loop through command line options (begins with "-" or "+") */ + while (*argv && (**argv == '-' || **argv == '+')) { + action = (**argv == '-'); + if(!argv[0][1]) + *argv = "--"; + while (*++*argv) { + /* The pseudo-option `--' signifies the end of options. * + * `-b' does too, csh-style, unless we're emulating a * + * Bourne style shell. */ + if (**argv == '-' || (!bourne && **argv == 'b')) { + argv++; + goto doneoptions; + } + + if (**argv == 'c') { /* -c command */ + if (!*++argv) { + zerr("string expected after -c", NULL, 0); + exit(1); + } + cmd = *argv++; + opts[INTERACTIVE] &= 1; + opts[SHINSTDIN] = 0; + goto doneoptions; + } else if (**argv == 'o') { + if (!*++*argv) + argv++; + if (!*argv) { + zerr("string expected after -o", NULL, 0); + exit(1); + } + if(!(optno = optlookup(*argv))) + zerr("no such option: %s", *argv, 0); + else if (optno == RESTRICTED) + restricted = action; + else + dosetopt(optno, action, 1); + break; + } else { + if (!(optno = optlookupc(**argv))) { + zerr("bad option: -%c", NULL, **argv); + exit(1); + } else if (optno == RESTRICTED) + restricted = action; + else + dosetopt(optno, action, 1); + } + } + argv++; + } + doneoptions: + paramlist = newlinklist(); + if (*argv) { + if (unset(SHINSTDIN)) { + argzero = *argv; + if (!cmd) + SHIN = movefd(open(unmeta(argzero), O_RDONLY | O_NOCTTY)); + if (SHIN == -1) { + zerr("can't open input file: %s", argzero, 0); + exit(1); + } + opts[INTERACTIVE] &= 1; + argv++; + } + while (*argv) + addlinknode(paramlist, ztrdup(*argv++)); + } else + opts[SHINSTDIN] = 1; + if(isset(SINGLECOMMAND)) + opts[INTERACTIVE] &= 1; + opts[INTERACTIVE] = !!opts[INTERACTIVE]; + pparams = x = (char **) zcalloc((countlinknodes(paramlist) + 1) * sizeof(char *)); + + while ((*x++ = (char *)getlinknode(paramlist))); + free(paramlist); + argzero = ztrdup(argzero); +} + + +/**/ +void +init_io(void) +{ + long ttpgrp; + static char outbuf[BUFSIZ], errbuf[BUFSIZ]; + +#ifdef RSH_BUG_WORKAROUND + int i; +#endif + +/* stdout, stderr fully buffered */ +#ifdef _IOFBF + setvbuf(stdout, outbuf, _IOFBF, BUFSIZ); + setvbuf(stderr, errbuf, _IOFBF, BUFSIZ); +#else + setbuffer(stdout, outbuf, BUFSIZ); + setbuffer(stderr, errbuf, BUFSIZ); +#endif + +/* This works around a bug in some versions of in.rshd. * + * Currently this is not defined by default. */ +#ifdef RSH_BUG_WORKAROUND + if (cmd) { + for (i = 3; i < 10; i++) + close(i); + } +#endif + + if (shout) { + fclose(shout); + shout = 0; + } + if (SHTTY != -1) { + zclose(SHTTY); + SHTTY = -1; + } + + /* Make sure the tty is opened read/write. */ + if (isatty(0)) { + zsfree(ttystrname); + if ((ttystrname = ztrdup(ttyname(0)))) + SHTTY = movefd(open(ttystrname, O_RDWR | O_NOCTTY)); + } + if (SHTTY == -1 && + (SHTTY = movefd(open("/dev/tty", O_RDWR | O_NOCTTY))) != -1) { + zsfree(ttystrname); + ttystrname = ztrdup("/dev/tty"); + } + if (SHTTY == -1) { + zsfree(ttystrname); + ttystrname = ztrdup(""); + } + + /* We will only use zle if shell is interactive, * + * SHTTY != -1, and shout != 0 */ + if (interact && SHTTY != -1) { + init_shout(); + if(!shout) + opts[USEZLE] = 0; + } else + opts[USEZLE] = 0; + +#ifdef JOB_CONTROL + /* If interactive, make the shell the foreground process */ + if (opts[MONITOR] && interact && (SHTTY != -1)) { + attachtty(GETPGRP()); + if ((mypgrp = GETPGRP()) > 0) { + while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) { + sleep(1); + mypgrp = GETPGRP(); + if (mypgrp == gettygrp()) + break; + killpg(mypgrp, SIGTTIN); + mypgrp = GETPGRP(); + } + } else + opts[MONITOR] = 0; + } else + opts[MONITOR] = 0; +#else + opts[MONITOR] = 0; +#endif +} + +/**/ +void +init_shout(void) +{ + static char shoutbuf[BUFSIZ]; +#if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC) + int ldisc = NTTYDISC; + + ioctl(SHTTY, TIOCSETD, (char *)&ldisc); +#endif + + /* Associate terminal file descriptor with a FILE pointer */ + shout = fdopen(SHTTY, "w"); +#ifdef _IOFBF + setvbuf(shout, shoutbuf, _IOFBF, BUFSIZ); +#endif + + gettyinfo(&shttyinfo); /* get tty state */ +#if defined(__sgi) + if (shttyinfo.tio.c_cc[VSWTCH] <= 0) /* hack for irises */ + shttyinfo.tio.c_cc[VSWTCH] = CSWTCH; +#endif +} + +/* names of the termcap strings we want */ + +static char *tccapnams[TC_COUNT] = { + "cl", "le", "LE", "nd", "RI", "up", "UP", "do", + "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta", + "md", "so", "us", "me", "se", "ue" +}; + +/* Initialise termcap */ + +/**/ +int +init_term(void) +{ +#ifndef TGETENT_ACCEPTS_NULL + static char termbuf[2048]; /* the termcap buffer */ +#endif + + if (!*term) { + termflags |= TERM_UNKNOWN; + return 0; + } + + /* 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; + termflags |= TERM_BAD; + return 0; + } else { + char tbuf[1024], *pp; + int t0; + + termflags &= ~TERM_BAD; + termflags &= ~TERM_UNKNOWN; + 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"); + + tclines = tgetnum("li"); + tccolumns = tgetnum("co"); + + /* if there's no termcap entry for cursor up, use single line mode: * + * this is flagged by termflags which is examined in zle_refresh.c * + */ + if (tccan(TCUP)) + termflags &= ~TERM_NOUP; + else { + tcstr[TCUP] = NULL; + termflags |= 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 1; +} + +/* Initialize lots of global variables and hash tables */ + +/**/ +void +setupvals(void) +{ +#ifdef HAVE_GETPWUID + struct passwd *pswd; +#endif + struct timezone dummy_tz; + char *ptr; +#ifdef HAVE_GETRLIMIT + int i; +#endif + + noeval = 0; + curhist = 0; + histsiz = DEFAULT_HISTSIZE; + inithist(); + + cmdstack = (unsigned char *) zalloc(256); + cmdsp = 0; + + bangchar = '!'; + hashchar = '#'; + hatchar = '^'; + termflags = TERM_UNKNOWN; + 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(unset(INTERACTIVE)) { + prompt = ztrdup(""); + prompt2 = ztrdup(""); + } else if (emulation == EMULATE_KSH || emulation == EMULATE_SH) { + prompt = ztrdup(privasserted() ? "# " : "$ "); + prompt2 = ztrdup("> "); + } else { + prompt = ztrdup("%m%# "); + 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; + + ppid = (long) getppid(); + mypid = (long) getpid(); + term = ztrdup(""); + + /* 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' */ +#ifdef HAVE_GETPWUID + if ((pswd = getpwuid(cached_uid))) { + home = metafy(pswd->pw_dir, -1, META_DUP); + cached_username = ztrdup(pswd->pw_name); + } else +#endif /* HAVE_GETPWUID */ + { + 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_DUP); + + oldpwd = ztrdup(pwd); /* initialize `OLDPWD' = `PWD' */ + + 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 TIOCGWINSZ + adjustwinsize(); +#else + /* Using zero below sets the defaults from termcap */ + setiparam("COLUMNS", 0); + setiparam("LINES", 0); +#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); + locallevel = sourcelevel = 0; + trapreturn = 0; + noerrexit = -1; + nohistsave = 1; + dirstack = newlinklist(); + bufstack = newlinklist(); + prepromptfns = 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); +#ifdef SIGWINCH + install_handler(SIGWINCH); +#endif + if (interact) { + install_handler(SIGALRM); + signal_ignore(SIGTERM); + } + if (jobbing) { + long ttypgrp; + + while ((ttypgrp = gettygrp()) != -1 && ttypgrp != mypgrp) + kill(0, SIGTTIN); + if (ttypgrp == -1) { + opts[MONITOR] = 0; + } else { + signal_ignore(SIGTTOU); + signal_ignore(SIGTSTP); + signal_ignore(SIGTTIN); + 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); + } +} + +/* Source the init scripts. If called as "ksh" or "sh" * + * then we source the standard sh/ksh scripts instead of * + * the standard zsh scripts */ + +/**/ +void +run_init_scripts(void) +{ + noerrexit = -1; + + if (emulation == EMULATE_KSH || emulation == EMULATE_SH) { + if (islogin) + source("/etc/profile"); + if (unset(PRIVILEGED)) { + char *s = getsparam("ENV"); + if (islogin) + sourcehome(".profile"); + noerrs = 1; + if (s && !parsestr(s)) { + singsub(&s); + noerrs = 0; + source(s); + } + noerrs = 0; + } else + source("/etc/suid_profile"); + } else { +#ifdef GLOBAL_ZSHENV + source(GLOBAL_ZSHENV); +#endif + if (isset(RCS)) { + if (unset(PRIVILEGED)) + sourcehome(".zshenv"); + if (islogin) { +#ifdef GLOBAL_ZPROFILE + source(GLOBAL_ZPROFILE); +#endif + if (unset(PRIVILEGED)) + sourcehome(".zprofile"); + } + if (interact) { +#ifdef GLOBAL_ZSHRC + source(GLOBAL_ZSHRC); +#endif + if (unset(PRIVILEGED)) + sourcehome(".zshrc"); + } + if (islogin) { +#ifdef GLOBAL_ZLOGIN + source(GLOBAL_ZLOGIN); +#endif + if (unset(PRIVILEGED)) + sourcehome(".zlogin"); + } + } + } + noerrexit = 0; + nohistsave = 0; +} + +/* Miscellaneous initializations that happen after init scripts are run */ + +/**/ +void +init_misc(void) +{ + if (*zsh_name == 'r' || restricted) + dosetopt(RESTRICTED, 1, 0); + if (cmd) { + if (SHIN >= 10) + fclose(bshin); + SHIN = movefd(open("/dev/null", O_RDONLY | O_NOCTTY)); + bshin = fdopen(SHIN, "r"); + execstring(cmd, 0, 1); + stopmsg = 1; + zexit(lastval, 0); + } + + if (interact && isset(RCS)) + readhistfile(getsparam("HISTFILE"), 0); +} + +/* source a file */ + +/**/ +int +source(char *s) +{ + int tempfd, fd, cj, oldlineno; + int oldshst, osubsh, oloops; + FILE *obshin; + char *old_scriptname = scriptname; + + if (!s || (tempfd = movefd(open(unmeta(s), O_RDONLY | O_NOCTTY))) == -1) { + return 1; + } + + /* save the current shell state */ + fd = SHIN; /* store the shell input fd */ + obshin = bshin; /* store file handle for buffered shell input */ + osubsh = subsh; /* store whether we are in a subshell */ + cj = thisjob; /* store our current job number */ + oldlineno = lineno; /* store our current lineno */ + oloops = loops; /* stored the # of nested loops we are in */ + oldshst = opts[SHINSTDIN]; /* store current value of this option */ + + SHIN = tempfd; + bshin = fdopen(SHIN, "r"); + subsh = 0; + lineno = 0; + loops = 0; + dosetopt(SHINSTDIN, 0, 1); + scriptname = s; + + sourcelevel++; + loop(0, 0); /* loop through the file to be sourced */ + sourcelevel--; + fclose(bshin); + fdtable[SHIN] = 0; + + /* restore the current shell state */ + SHIN = fd; /* the shell input fd */ + bshin = obshin; /* file handle for buffered shell input */ + subsh = osubsh; /* whether we are in a subshell */ + thisjob = cj; /* current job number */ + lineno = oldlineno; /* our current lineno */ + loops = oloops; /* the # of nested loops we are in */ + dosetopt(SHINSTDIN, oldshst, 1); /* SHINSTDIN option */ + errflag = 0; + retflag = 0; + scriptname = old_scriptname; + + return 0; +} + +/* Try to source a file in the home directory */ + +/**/ +void +sourcehome(char *s) +{ + char buf[PATH_MAX]; + char *h; + + if (emulation == EMULATE_SH || emulation == EMULATE_KSH || + !(h = getsparam("ZDOTDIR"))) + h = home; + if (strlen(h) + strlen(s) + 1 >= PATH_MAX) { + zerr("path too long: %s", s, 0); + return; + } + sprintf(buf, "%s/%s", h, s); + source(buf); +} + +/**/ +void +init_bltinmods(void) +{ + static struct module mod = { NULL, 0, NULL, NULL }; +#include "bltinmods.list" + mod.nam = NULL; +} + +/* ZLE entry point pointers. They are defined here because the initial * + * values depend on whether ZLE is linked in or not -- if it is, we * + * avoid wasting space with the fallback functions. No other source * + * file needs to know which modules are linked in. */ + +#ifdef LINKED_XMOD_zle + +/**/ +ZleVoidFn trashzleptr; +/**/ +ZleVoidFn gotwordptr; +/**/ +ZleVoidFn refreshptr; +/**/ +ZleVoidIntFn spaceinlineptr; +/**/ +ZleReadFn zlereadptr; + +#else /* !LINKED_XMOD_zle */ + +ZleVoidFn trashzleptr = noop_function; +ZleVoidFn gotwordptr = noop_function; +ZleVoidFn refreshptr = noop_function; +ZleVoidIntFn spaceinlineptr = noop_function_int; +# ifdef UNLINKED_XMOD_zle +ZleReadFn zlereadptr = autoload_zleread; +# else /* !UNLINKED_XMOD_zle */ +ZleReadFn zlereadptr = fallback_zleread; +# endif /* !UNLINKED_XMOD_zle */ + +/**/ +void +noop_function(void) +{ + /* do nothing */ +} + +/**/ +void +noop_function_int(int nothing) +{ + /* do nothing */ +} + +# ifdef UNLINKED_XMOD_zle + +/**/ +static unsigned char * +autoload_zleread(char *lp, char *rp, int ha) +{ + zlereadptr = fallback_zleread; + load_module("zle"); + return zleread(lp, rp, ha); +} + +# endif /* UNLINKED_XMOD_zle */ + +/**/ +unsigned char * +fallback_zleread(char *lp, char *rp, int ha) +{ + char *pptbuf; + int pptlen; + + pptbuf = unmetafy(promptexpand(lp, 0, NULL, NULL), &pptlen); + write(2, (WRITE_ARG_2_T)pptbuf, pptlen); + free(pptbuf); + return (unsigned char *)shingetline(); +} + +#endif /* !LINKED_XMOD_zle */ + +/* compctl entry point pointers. Similar to the ZLE ones. */ + +#ifdef LINKED_XMOD_comp1 + +/**/ +CompctlReadFn compctlreadptr; + +#else /* !LINKED_XMOD_comp1 */ + +CompctlReadFn compctlreadptr = fallback_compctlread; + +/**/ +int +fallback_compctlread(char *name, char **args, char *ops, char *reply) +{ + zwarnnam(name, "option valid only in functions called from completion", + NULL, 0); + return 1; +} + +#endif /* !LINKED_XMOD_comp1 */ |