static void scangdbmkeys(HashTable ht, ScanFunc func, int flags) { Param pm = NULL; datum key, content; GDBM_FILE dbf = (GDBM_FILE)(ht->tmpdata); pm = (Param) hcalloc(sizeof(struct param)); pm->node.flags = PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; key = gdbm_firstkey(dbf); while(key.dptr) { content = gdbm_fetch(dbf, key); pm->node.nam = key.dptr; pm->u.str = content.dptr; pm->gsu.s = &nullsetscalar_gsu; func(&pm->node, flags); key = gdbm_nextkey(dbf, key); } }
static HashNode getlanginfo(UNUSED(HashTable ht), const char *name) { int len, *elem; char *listr, *nameu; Param pm = NULL; nameu = dupstring(name); unmetafy(nameu, &len); pm = (Param) hcalloc(sizeof(struct param)); pm->node.nam = nameu; pm->node.flags = PM_READONLY | PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; if(name) elem = liitem(name); else elem = NULL; if (elem && (listr = nl_langinfo(*elem))) { pm->u.str = dupstring(listr); } else { /* zwarn("no such lang info: %s", name); */ pm->u.str = dupstring(""); pm->node.flags |= PM_UNSET; } return &pm->node; }
int quoteregion(UNUSED(char **args)) { ZLE_STRING_T str; size_t len; int extra = invicmdmode(); if (mark > zlell) mark = zlell; if (region_active == 2) { int a, b; regionlines(&a, &b); zlecs = a; mark = b; extra = 0; } else if (mark < zlecs) { int tmp = mark; mark = zlecs; zlecs = tmp; } if (extra) INCPOS(mark); str = (ZLE_STRING_T)hcalloc((len = mark - zlecs) * ZLE_CHAR_SIZE); ZS_memcpy(str, zleline + zlecs, len); foredel(len, CUT_RAW); str = makequote(str, &len); spaceinline(len); ZS_memcpy(zleline + zlecs, str, len); mark = zlecs; zlecs += len; return 0; }
static HashNode getpmsysparams(UNUSED(HashTable ht), const char *name) { Param pm; pm = (Param) hcalloc(sizeof(struct param)); fillpmsysparams(pm, name); return &pm->node; }
static Cpattern parse_pattern(char *name, char **sp, int *lp, char e, int *err) { Cpattern ret = NULL, r = NULL, n; char *s = *sp; convchar_t inchar; int l = 0, inlen; *err = 0; MB_METACHARINIT(); while (*s && (e ? (*s != e) : !inblank(*s))) { n = (Cpattern) hcalloc(sizeof(*n)); n->next = NULL; if (*s == '[' || *s == '{') { s = parse_class(n, s); if (!*s) { *err = 1; zwarnnam(name, "unterminated character class"); return NULL; } s++; } else if (*s == '?') { n->tp = CPAT_ANY; s++; } else if (*s == '*' || *s == '(' || *s == ')' || *s == '=') { *err = 1; zwarnnam(name, "invalid pattern character `%c'", *s); return NULL; } else { if (*s == '\\' && s[1]) s++; inlen = MB_METACHARLENCONV(s, &inchar); #ifdef MULTIBYTE_SUPPORT if (inchar == WEOF) inchar = (convchar_t)(*s == Meta ? s[1] ^ 32 : *s); #endif s += inlen; n->tp = CPAT_CHAR; n->u.chr = inchar; } if (ret) r->next = n; else ret = n; r = n; l++; } *sp = (char *) s; *lp = l; return ret; }
static HashNode gettermcap(UNUSED(HashTable ht), char *name) { int len, num; char *tcstr, buf[2048], *u; Param pm = NULL; /* This depends on the termcap stuff in init.c */ if (termflags & TERM_BAD) return NULL; if ((termflags & TERM_UNKNOWN) && (isset(INTERACTIVE) || !init_term())) return NULL; unmetafy(name, &len); pm = (Param) hcalloc(sizeof(struct param)); pm->nam = dupstring(name); pm->flags = PM_READONLY; u = buf; /* logic in the following cascade copied from echotc, above */ if ((num = tgetnum(name)) != -1) { pm->gsu.i = &nullsetinteger_gsu; pm->u.val = num; pm->flags |= PM_INTEGER; return (HashNode) pm; } pm->gsu.s = &nullsetscalar_gsu; switch (ztgetflag(name)) { case -1: break; case 0: pm->u.str = dupstring("no"); pm->flags |= PM_SCALAR; return (HashNode) pm; default: pm->u.str = dupstring("yes"); pm->flags |= PM_SCALAR; return (HashNode) pm; } if ((tcstr = (char*)tgetstr(name, &u)) != NULL && tcstr != (char *)-1) { pm->u.str = dupstring(tcstr); pm->flags |= PM_SCALAR; } else { /* zwarn("no such capability: %s", name, 0); */ pm->u.str = dupstring(""); pm->flags |= PM_UNSET; } return (HashNode) pm; }
static char * pps_getfn(Param pm) { struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.s); GsuScalar gsu = (GsuScalar)(c->g); if (locallevel >= pm->level) return gsu->getfn(pm); else return (char *) hcalloc(1); }
static HashNode getgdbmnode(HashTable ht, const char *name) { int len; char *nameu; Param pm = NULL; nameu = dupstring(name); unmetafy(nameu, &len); pm = (Param) hcalloc(sizeof(struct param)); pm->node.nam = nameu; pm->node.flags = PM_SCALAR; pm->gsu.s = &gdbm_gsu; pm->u.hash = ht; return &pm->node; }
static void scanlanginfo(UNUSED(HashTable ht), ScanFunc func, int flags) { Param pm = NULL; char **element, *langstr; nl_item *nlcode; pm = (Param) hcalloc(sizeof(struct param)); pm->gsu.s = &nullsetscalar_gsu; pm->node.flags = PM_READONLY | PM_SCALAR; nlcode = &nl_vals[0]; for (element = (char **)nl_names; *element; element++, nlcode++) { if ((langstr = nl_langinfo(*nlcode)) != NULL) { pm->u.str = dupstring(langstr); pm->node.nam = dupstring(*element); func(&pm->node, flags); } } }
static HashNode getpmmapfile(UNUSED(HashTable ht), char *name) { char *contents; Param pm = NULL; pm = (Param) hcalloc(sizeof(struct param)); pm->nam = dupstring(name); pm->flags = PM_SCALAR; pm->gsu.s = &mapfile_gsu; pm->flags |= (mapfile_pm->flags & PM_READONLY); /* Set u.str to contents of file given by name */ if ((contents = get_contents(pm->nam))) pm->u.str = contents; else { pm->u.str = ""; pm->flags |= PM_UNSET; } return (HashNode) pm; }
static HashNode getterminfo(UNUSED(HashTable ht), const char *name) { int len, num; char *tistr, *nameu; Param pm = NULL; /* This depends on the termcap stuff in init.c */ if (termflags & TERM_BAD) return NULL; if ((termflags & TERM_UNKNOWN) && (isset(INTERACTIVE) || !init_term())) return NULL; nameu = dupstring(name); unmetafy(nameu, &len); pm = (Param) hcalloc(sizeof(struct param)); pm->node.nam = nameu; pm->node.flags = PM_READONLY; if (((num = tigetnum(nameu)) != -1) && (num != -2)) { pm->u.val = num; pm->node.flags |= PM_INTEGER; pm->gsu.i = &nullsetinteger_gsu; } else if ((num = tigetflag(nameu)) != -1) { pm->u.str = num ? dupstring("yes") : dupstring("no"); pm->node.flags |= PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; } else if ((tistr = (char *)tigetstr(nameu)) != NULL && tistr != (char *)-1) { pm->u.str = dupstring(tistr); pm->node.flags |= PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; } else { /* zwarn("no such capability: %s", name); */ pm->u.str = dupstring(""); pm->node.flags |= PM_UNSET; pm->gsu.s = &nullsetscalar_gsu; } return &pm->node; }
void quoteregion() /**/ { char *s,*t; int x,y; if (mark > ll) mark = ll; if (mark < cs) { x = mark; mark = cs; cs = x; } s = hcalloc((y = mark-cs)+1); strncpy(s,(char *) line+cs,y); s[y] = '\0'; foredel(mark-cs); t = makequote(s); spaceinline(x = strlen(t)); strncpy((char *) line+cs,t,x); mark = cs; cs += x; }
int quoteregion(UNUSED(char **args)) { ZLE_STRING_T str; size_t len; if (mark > zlell) mark = zlell; if (mark < zlecs) { int tmp = mark; mark = zlecs; zlecs = tmp; } str = (ZLE_STRING_T)hcalloc((len = mark - zlecs) * ZLE_CHAR_SIZE); ZS_memcpy(str, zleline + zlecs, len); foredel(len, CUT_RAW); str = makequote(str, &len); spaceinline(len); ZS_memcpy(zleline + zlecs, str, len); mark = zlecs; zlecs += len; return 0; }
static enum lextok gettok(void) { int c, d; int peekfd = -1; enum lextok peek; beginning: tokstr = NULL; while (iblank(c = hgetc()) && !lexstop); toklineno = lineno; if (lexstop) return (errflag) ? LEXERR : ENDINPUT; isfirstln = 0; if ((lexflags & LEXFLAGS_ZLE)) wordbeg = inbufct - (qbang && c == bangchar); hwbegin(-1-(qbang && c == bangchar)); /* word includes the last character read and possibly \ before ! */ if (dbparens) { lexbuf.len = 0; lexbuf.ptr = tokstr = (char *) hcalloc(lexbuf.siz = LEX_HEAP_SIZE); hungetc(c); cmdpush(CS_MATH); c = dquote_parse(infor ? ';' : ')', 0); cmdpop(); *lexbuf.ptr = '\0'; if (!c && infor) { infor--; return DINPAR; } if (c || (c = hgetc()) != ')') { hungetc(c); return LEXERR; } dbparens = 0; return DOUTPAR; } else if (idigit(c)) { /* handle 1< foo */ d = hgetc(); if(d == '&') { d = hgetc(); if(d == '>') { peekfd = c - '0'; hungetc('>'); c = '&'; } else { hungetc(d); lexstop = 0; hungetc('&'); } } else if (d == '>' || d == '<') { peekfd = c - '0'; c = d; } else { hungetc(d); lexstop = 0; } } /* chars in initial position in word */ /* * Handle comments. There are some special cases when this * is not normal command input: lexflags implies we are examining * a line lexically without it being used for normal command input. */ if (c == hashchar && !nocomments && (isset(INTERACTIVECOMMENTS) || ((!lexflags || (lexflags & LEXFLAGS_COMMENTS)) && !expanding && (!interact || unset(SHINSTDIN) || strin)))) { /* History is handled here to prevent extra * * newlines being inserted into the history. */ if (lexflags & LEXFLAGS_COMMENTS_KEEP) { lexbuf.len = 0; lexbuf.ptr = tokstr = (char *)hcalloc(lexbuf.siz = LEX_HEAP_SIZE); add(c); } hwend(); while ((c = ingetc()) != '\n' && !lexstop) { hwaddc(c); addtoline(c); if (lexflags & LEXFLAGS_COMMENTS_KEEP) add(c); } if (errflag) peek = LEXERR; else { if (lexflags & LEXFLAGS_COMMENTS_KEEP) { *lexbuf.ptr = '\0'; if (!lexstop) hungetc(c); peek = STRING; } else { hwend(); hwbegin(0); hwaddc('\n'); addtoline('\n'); /* * If splitting a line and removing comments, * we don't want a newline token since it's * treated specially. */ if ((lexflags & LEXFLAGS_COMMENTS_STRIP) && lexstop) peek = ENDINPUT; else peek = NEWLIN; } } return peek; } switch (lexact1[STOUC(c)]) { case LX1_BKSLASH: d = hgetc(); if (d == '\n') goto beginning; hungetc(d); lexstop = 0; break; case LX1_NEWLIN: return NEWLIN; case LX1_SEMI: d = hgetc(); if(d == ';') return DSEMI; else if(d == '&') return SEMIAMP; else if (d == '|') return SEMIBAR; hungetc(d); lexstop = 0; return SEMI; case LX1_AMPER: d = hgetc(); if (d == '&') return DAMPER; else if (d == '!' || d == '|') return AMPERBANG; else if (d == '>') { tokfd = peekfd; d = hgetc(); if (d == '!' || d == '|') return OUTANGAMPBANG; else if (d == '>') { d = hgetc(); if (d == '!' || d == '|') return DOUTANGAMPBANG; hungetc(d); lexstop = 0; return DOUTANGAMP; } hungetc(d); lexstop = 0; return AMPOUTANG; } hungetc(d); lexstop = 0; return AMPER; case LX1_BAR: d = hgetc(); if (d == '|') return DBAR; else if (d == '&') return BARAMP; hungetc(d); lexstop = 0; return BAR; case LX1_INPAR: d = hgetc(); if (d == '(') { if (infor) { dbparens = 1; return DINPAR; } if (incmdpos || (isset(SHGLOB) && !isset(KSHGLOB))) { lexbuf.len = 0; lexbuf.ptr = tokstr = (char *) hcalloc(lexbuf.siz = LEX_HEAP_SIZE); switch (cmd_or_math(CS_MATH)) { case CMD_OR_MATH_MATH: return DINPAR; case CMD_OR_MATH_CMD: /* * Not math, so we don't return the contents * as a string in this case. */ tokstr = NULL; return INPAR; case CMD_OR_MATH_ERR: /* * LEXFLAGS_ACTIVE means we came from bufferwords(), * so we treat as an incomplete math expression */ if (lexflags & LEXFLAGS_ACTIVE) tokstr = dyncat("((", tokstr ? tokstr : ""); /* fall through */ default: return LEXERR; } } } else if (d == ')') return INOUTPAR; hungetc(d); lexstop = 0; if (!(isset(SHGLOB) || incond == 1 || incmdpos)) break; return INPAR; case LX1_OUTPAR: return OUTPAR; case LX1_INANG: d = hgetc(); if (d == '(') { hungetc(d); lexstop = 0; unpeekfd: if(peekfd != -1) { hungetc(c); c = '0' + peekfd; } break; } if (d == '>') { peek = INOUTANG; } else if (d == '<') { int e = hgetc(); if (e == '(') { hungetc(e); hungetc(d); peek = INANG; } else if (e == '<') peek = TRINANG; else if (e == '-') peek = DINANGDASH; else { hungetc(e); lexstop = 0; peek = DINANG; } } else if (d == '&') { peek = INANGAMP; } else { hungetc(d); if(isnumglob()) goto unpeekfd; peek = INANG; } tokfd = peekfd; return peek; case LX1_OUTANG: d = hgetc(); if (d == '(') { hungetc(d); goto unpeekfd; } else if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = OUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = OUTANGAMP; } } else if (d == '!' || d == '|') peek = OUTANGBANG; else if (d == '>') { d = hgetc(); if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = DOUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = DOUTANGAMP; } } else if (d == '!' || d == '|') peek = DOUTANGBANG; else if (d == '(') { hungetc(d); hungetc('>'); peek = OUTANG; } else { hungetc(d); lexstop = 0; peek = DOUTANG; if (isset(HISTALLOWCLOBBER)) hwaddc('|'); } } else { hungetc(d); lexstop = 0; peek = OUTANG; if (!incond && isset(HISTALLOWCLOBBER)) hwaddc('|'); } tokfd = peekfd; return peek; } /* we've started a string, now get the * * rest of it, performing tokenization */ return gettokstr(c, 0); }
mod_export Cmatcher parse_cmatcher(char *name, char *s) { Cmatcher ret = NULL, r = NULL, n; Cpattern line, word, left, right; int fl, fl2, ll, wl, lal, ral, err, both; if (!*s) return NULL; while (*s) { lal = ral = both = fl2 = 0; left = right = NULL; while (*s && inblank(*s)) s++; if (!*s) break; switch (*s) { case 'b': fl2 = CMF_INTER; case 'l': fl = CMF_LEFT; break; case 'e': fl2 = CMF_INTER; case 'r': fl = CMF_RIGHT; break; case 'm': fl = 0; break; case 'B': fl2 = CMF_INTER; case 'L': fl = CMF_LEFT | CMF_LINE; break; case 'E': fl2 = CMF_INTER; case 'R': fl = CMF_RIGHT | CMF_LINE; break; case 'M': fl = CMF_LINE; break; default: if (name) zwarnnam(name, "unknown match specification character `%c'", *s); return pcm_err; } if (s[1] != ':') { if (name) zwarnnam(name, "missing `:'"); return pcm_err; } s += 2; if (!*s) { if (name) zwarnnam(name, "missing patterns"); return pcm_err; } if ((fl & CMF_LEFT) && !fl2) { left = parse_pattern(name, &s, &lal, '|', &err); if (err) return pcm_err; if ((both = (*s && s[1] == '|'))) s++; if (!*s || !*++s) { if (name) zwarnnam(name, "missing line pattern"); return pcm_err; } } else left = NULL; line = parse_pattern(name, &s, &ll, (((fl & CMF_RIGHT) && !fl2) ? '|' : '='), &err); if (err) return pcm_err; if (both) { right = line; ral = ll; line = NULL; ll = 0; } if ((fl & CMF_RIGHT) && !fl2 && (!*s || !*++s)) { if (name) zwarnnam(name, "missing right anchor"); } else if (!(fl & CMF_RIGHT) || fl2) { if (!*s) { if (name) zwarnnam(name, "missing word pattern"); return pcm_err; } s++; } if ((fl & CMF_RIGHT) && !fl2) { if (*s == '|') { left = line; lal = ll; line = NULL; ll = 0; s++; } right = parse_pattern(name, &s, &ral, '=', &err); if (err) return pcm_err; if (!*s) { if (name) zwarnnam(name, "missing word pattern"); return pcm_err; } s++; } else right = NULL; if (*s == '*') { if (!(fl & (CMF_LEFT | CMF_RIGHT))) { if (name) zwarnnam(name, "need anchor for `*'"); return pcm_err; } word = NULL; if (*++s == '*') { s++; wl = -2; } else wl = -1; } else { word = parse_pattern(name, &s, &wl, 0, &err); if (!word && !line) { if (name) zwarnnam(name, "need non-empty word or line pattern"); return pcm_err; } } if (err) return pcm_err; n = (Cmatcher) hcalloc(sizeof(*ret)); n->next = NULL; n->flags = fl | fl2; n->line = line; n->llen = ll; n->word = word; n->wlen = wl; n->left = left; n->lalen = lal; n->right = right; n->ralen = ral; if (ret) r->next = n; else ret = n; r = n; } return ret; }
static void scanterminfo(UNUSED(HashTable ht), ScanFunc func, int flags) { Param pm = NULL; int num; char **capname, *tistr; #ifndef HAVE_BOOLNAMES static char *boolnames[] = { "bw", "am", "bce", "ccc", "xhp", "xhpa", "cpix", "crxm", "xt", "xenl", "eo", "gn", "hc", "chts", "km", "daisy", "hs", "hls", "in", "lpix", "da", "db", "mir", "msgr", "nxon", "xsb", "npc", "ndscr", "nrrmc", "os", "mc5i", "xvpa", "sam", "eslok", "hz", "ul", "xon", NULL}; #endif #ifndef HAVE_NUMNAMES static char *numnames[] = { "cols", "it", "lh", "lw", "lines", "lm", "xmc", "ma", "colors", "pairs", "wnum", "ncv", "nlab", "pb", "vt", "wsl", "bitwin", "bitype", "bufsz", "btns", "spinh", "spinv", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orhi", "orl", "orvi", "cps", "widcs", NULL}; #endif #ifndef HAVE_STRNAMES static char *strnames[] = { "acsc", "cbt", "bel", "cr", "cpi", "lpi", "chr", "cvr", "csr", "rmp", "tbc", "mgc", "clear", "el1", "el", "ed", "hpa", "cmdch", "cwin", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1", "ll", "cuu1", "cvvis", "defc", "dch1", "dl1", "dial", "dsl", "dclk", "hd", "enacs", "smacs", "smam", "blink", "bold", "smcup", "smdc", "dim", "swidm", "sdrfq", "smir", "sitm", "slm", "smicm", "snlq", "snrmq", "prot", "rev", "invis", "sshm", "smso", "ssubm", "ssupm", "smul", "sum", "smxon", "ech", "rmacs", "rmam", "sgr0", "rmcup", "rmdc", "rwidm", "rmir", "ritm", "rlm", "rmicm", "rshm", "rmso", "rsubm", "rsupm", "rmul", "rum", "rmxon", "pause", "hook", "flash", "ff", "fsl", "wingo", "hup", "is1", "is2", "is3", "if", "iprog", "initc", "initp", "ich1", "il1", "ip", "ka1", "ka3", "kb2", "kbs", "kbeg", "kcbt", "kc1", "kc3", "kcan", "ktbc", "kclr", "kclo", "kcmd", "kcpy", "kcrt", "kctab", "kdch1", "kdl1", "kcud1", "krmir", "kend", "kent", "kel", "ked", "kext", "kf0", "kf1", "kf10", "kf11", "kf12", "kf13", "kf14", "kf15", "kf16", "kf17", "kf18", "kf19", "kf2", "kf20", "kf21", "kf22", "kf23", "kf24", "kf25", "kf26", "kf27", "kf28", "kf29", "kf3", "kf30", "kf31", "kf32", "kf33", "kf34", "kf35", "kf36", "kf37", "kf38", "kf39", "kf4", "kf40", "kf41", "kf42", "kf43", "kf44", "kf45", "kf46", "kf47", "kf48", "kf49", "kf5", "kf50", "kf51", "kf52", "kf53", "kf54", "kf55", "kf56", "kf57", "kf58", "kf59", "kf6", "kf60", "kf61", "kf62", "kf63", "kf7", "kf8", "kf9", "kfnd", "khlp", "khome", "kich1", "kil1", "kcub1", "kll", "kmrk", "kmsg", "kmov", "knxt", "knp", "kopn", "kopt", "kpp", "kprv", "kprt", "krdo", "kref", "krfr", "krpl", "krst", "kres", "kcuf1", "ksav", "kBEG", "kCAN", "kCMD", "kCPY", "kCRT", "kDC", "kDL", "kslt", "kEND", "kEOL", "kEXT", "kind", "kFND", "kHLP", "kHOM", "kIC", "kLFT", "kMSG", "kMOV", "kNXT", "kOPT", "kPRV", "kPRT", "kri", "kRDO", "kRPL", "kRIT", "kRES", "kSAV", "kSPD", "khts", "kUND", "kspd", "kund", "kcuu1", "rmkx", "smkx", "lf0", "lf1", "lf10", "lf2", "lf3", "lf4", "lf5", "lf6", "lf7", "lf8", "lf9", "fln", "rmln", "smln", "rmm", "smm", "mhpa", "mcud1", "mcub1", "mcuf1", "mvpa", "mcuu1", "nel", "porder", "oc", "op", "pad", "dch", "dl", "cud", "mcud", "ich", "indn", "il", "cub", "mcub", "cuf", "mcuf", "rin", "cuu", "mcuu", "pfkey", "pfloc", "pfx", "pln", "mc0", "mc5p", "mc4", "mc5", "pulse", "qdial", "rmclk", "rep", "rfi", "rs1", "rs2", "rs3", "rf", "rc", "vpa", "sc", "ind", "ri", "scs", "sgr", "setb", "smgb", "smgbp", "sclk", "scp", "setf", "smgl", "smglp", "smgr", "smgrp", "hts", "smgt", "smgtp", "wind", "sbim", "scsd", "rbim", "rcsd", "subcs", "supcs", "ht", "docr", "tsl", "tone", "uc", "hu", "u0", "u1", "u2", "u3", "u4", "u5", "u6", "u7", "u8", "u9", "wait", "xoffc", "xonc", "zerom", "scesa", "bicr", "binel", "birep", "csnm", "csin", "colornm", "defbi", "devt", "dispc", "endbi", "smpch", "smsc", "rmpch", "rmsc", "getm", "kmous", "minfo", "pctrm", "pfxl", "reqmp", "scesc", "s0ds", "s1ds", "s2ds", "s3ds", "setab", "setaf", "setcolor", "smglr", "slines", "smgtb", "ehhlm", "elhlm", "elohlm", "erhlm", "ethlm", "evhlm", "sgr1", "slength", NULL}; #endif pm = (Param) hcalloc(sizeof(struct param)); pm->node.flags = PM_READONLY | PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; for (capname = (char **)boolnames; *capname; capname++) { if ((num = tigetflag(*capname)) != -1) { pm->u.str = num ? dupstring("yes") : dupstring("no"); pm->node.nam = dupstring(*capname); func(&pm->node, flags); } } pm->node.flags = PM_READONLY | PM_INTEGER; pm->gsu.i = &nullsetinteger_gsu; for (capname = (char **)numnames; *capname; capname++) { if (((num = tigetnum(*capname)) != -1) && (num != -2)) { pm->u.val = num; pm->node.nam = dupstring(*capname); func(&pm->node, flags); } } pm->node.flags = PM_READONLY | PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; for (capname = (char **)strnames; *capname; capname++) { if ((tistr = (char *)tigetstr(*capname)) != NULL && tistr != (char *)-1) { pm->u.str = dupstring(tistr); pm->node.nam = dupstring(*capname); func(&pm->node, flags); } } }
static void scantermcap(UNUSED(HashTable ht), ScanFunc func, int flags) { Param pm = NULL; int num; char **capcode, *tcstr, buf[2048], *u; #ifndef HAVE_NUMCODES static char *numcodes[] = { "co", "it", "lh", "lw", "li", "lm", "sg", "ma", "Co", "pa", "MW", "NC", "Nl", "pb", "vt", "ws", "Yo", "Yp", "Ya", "BT", "Yc", "Yb", "Yd", "Ye", "Yf", "Yg", "Yh", "Yi", "Yk", "Yj", "Yl", "Ym", "Yn", NULL}; #endif #ifndef HAVE_STRCODES static char *zstrcodes[] = { "ac", "bt", "bl", "cr", "ZA", "ZB", "ZC", "ZD", "cs", "rP", "ct", "MC", "cl", "cb", "ce", "cd", "ch", "CC", "CW", "cm", "do", "ho", "vi", "le", "CM", "ve", "nd", "ll", "up", "vs", "ZE", "dc", "dl", "DI", "ds", "DK", "hd", "eA", "as", "SA", "mb", "md", "ti", "dm", "mh", "ZF", "ZG", "im", "ZH", "ZI", "ZJ", "ZK", "ZL", "mp", "mr", "mk", "ZM", "so", "ZN", "ZO", "us", "ZP", "SX", "ec", "ae", "RA", "me", "te", "ed", "ZQ", "ei", "ZR", "ZS", "ZT", "ZU", "se", "ZV", "ZW", "ue", "ZX", "RX", "PA", "fh", "vb", "ff", "fs", "WG", "HU", "i1", "is", "i3", "if", "iP", "Ic", "Ip", "ic", "al", "ip", "K1", "K3", "K2", "kb", "@1", "kB", "K4", "K5", "@2", "ka", "kC", "@3", "@4", "@5", "@6", "kt", "kD", "kL", "kd", "kM", "@7", "@8", "kE", "kS", "@9", "k0", "k1", "k;", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "k2", "FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FI", "FJ", "k3", "FK", "FL", "FM", "FN", "FO", "FP", "FQ", "FR", "FS", "FT", "k4", "FU", "FV", "FW", "FX", "FY", "FZ", "Fa", "Fb", "Fc", "Fd", "k5", "Fe", "Ff", "Fg", "Fh", "Fi", "Fj", "Fk", "Fl", "Fm", "Fn", "k6", "Fo", "Fp", "Fq", "Fr", "k7", "k8", "k9", "@0", "%1", "kh", "kI", "kA", "kl", "kH", "%2", "%3", "%4", "%5", "kN", "%6", "%7", "kP", "%8", "%9", "%0", "&1", "&2", "&3", "&4", "&5", "kr", "&6", "&9", "&0", "*1", "*2", "*3", "*4", "*5", "*6", "*7", "*8", "*9", "kF", "*0", "#1", "#2", "#3", "#4", "%a", "%b", "%c", "%d", "%e", "%f", "kR", "%g", "%h", "%i", "%j", "!1", "!2", "kT", "!3", "&7", "&8", "ku", "ke", "ks", "l0", "l1", "la", "l2", "l3", "l4", "l5", "l6", "l7", "l8", "l9", "Lf", "LF", "LO", "mo", "mm", "ZY", "ZZ", "Za", "Zb", "Zc", "Zd", "nw", "Ze", "oc", "op", "pc", "DC", "DL", "DO", "Zf", "IC", "SF", "AL", "LE", "Zg", "RI", "Zh", "SR", "UP", "Zi", "pk", "pl", "px", "pn", "ps", "pO", "pf", "po", "PU", "QD", "RC", "rp", "RF", "r1", "r2", "r3", "rf", "rc", "cv", "sc", "sf", "sr", "Zj", "sa", "Sb", "Zk", "Zl", "SC", "sp", "Sf", "ML", "Zm", "MR", "Zn", "st", "Zo", "Zp", "wi", "Zq", "Zr", "Zs", "Zt", "Zu", "Zv", "ta", "Zw", "ts", "TO", "uc", "hu", "u0", "u1", "u2", "u3", "u4", "u5", "u6", "u7", "u8", "u9", "WA", "XF", "XN", "Zx", "S8", "Yv", "Zz", "Xy", "Zy", "ci", "Yw", "Yx", "dv", "S1", "Yy", "S2", "S4", "S3", "S5", "Gm", "Km", "Mi", "S6", "xl", "RQ", "S7", "s0", "s1", "s2", "s3", "AB", "AF", "Yz", "ML", "YZ", "MT", "Xh", "Xl", "Xo", "Xr", "Xt", "Xv", "sA", "sL", NULL}; #endif pm = (Param) hcalloc(sizeof(struct param)); u = buf; pm->node.flags = PM_READONLY | PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; for (capcode = (char **)boolcodes; *capcode; capcode++) { if ((num = ztgetflag(*capcode)) != -1) { pm->u.str = num ? dupstring("yes") : dupstring("no"); pm->node.nam = dupstring(*capcode); func(&pm->node, flags); } } pm->node.flags = PM_READONLY | PM_INTEGER; pm->gsu.i = &nullsetinteger_gsu; for (capcode = (char **)numcodes; *capcode; capcode++) { if ((num = tgetnum(*capcode)) != -1) { pm->u.val = num; pm->node.nam = dupstring(*capcode); func(&pm->node, flags); } } pm->node.flags = PM_READONLY | PM_SCALAR; pm->gsu.s = &nullsetscalar_gsu; for (capcode = (char **) #ifdef HAVE_STRCODES strcodes #else zstrcodes #endif ; *capcode; capcode++) { if ((tcstr = (char *)tgetstr(*capcode,&u)) != NULL && tcstr != (char *)-1) { pm->u.str = dupstring(tcstr); pm->node.nam = dupstring(*capcode); func(&pm->node, flags); } } }
static enum lextok gettokstr(int c, int sub) { int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0; int intpos = 1, in_brace_param = 0; int inquote, unmatched = 0; enum lextok peek; #ifdef DEBUG int ocmdsp = cmdsp; #endif peek = STRING; if (!sub) { lexbuf.len = 0; lexbuf.ptr = tokstr = (char *) hcalloc(lexbuf.siz = LEX_HEAP_SIZE); } for (;;) { int act; int e; int inbl = inblank(c); if (fdpar && !inbl && c != ')') fdpar = 0; if (inbl && !in_brace_param && !pct) act = LX2_BREAK; else { act = lexact2[STOUC(c)]; c = lextok2[STOUC(c)]; } switch (act) { case LX2_BREAK: if (!in_brace_param && !sub) goto brk; break; case LX2_META: c = hgetc(); #ifdef DEBUG if (lexstop) { fputs("BUG: input terminated by Meta\n", stderr); fflush(stderr); goto brk; } #endif add(Meta); break; case LX2_OUTPAR: if (fdpar) { /* this is a single word `( )', treat as INOUTPAR */ add(c); *lexbuf.ptr = '\0'; return INOUTPAR; } if ((sub || in_brace_param) && isset(SHGLOB)) break; if (!in_brace_param && !pct--) { if (sub) { pct = 0; break; } else goto brk; } c = Outpar; break; case LX2_BAR: if (!pct && !in_brace_param) { if (sub) break; else goto brk; } if (unset(SHGLOB) || (!sub && !in_brace_param)) c = Bar; break; case LX2_STRING: e = hgetc(); if (e == '[') { cmdpush(CS_MATHSUBST); add(String); add(Inbrack); c = dquote_parse(']', sub); cmdpop(); if (c) { peek = LEXERR; goto brk; } c = Outbrack; } else if (e == '(') { add(String); switch (cmd_or_math_sub()) { case CMD_OR_MATH_CMD: c = Outpar; break; case CMD_OR_MATH_MATH: c = Outparmath; break; default: peek = LEXERR; goto brk; } } else { if (e == '{') { add(c); c = Inbrace; ++bct; cmdpush(CS_BRACEPAR); if (!in_brace_param) { if ((in_brace_param = bct)) seen_brct = 0; } } else { hungetc(e); lexstop = 0; } } break; case LX2_INBRACK: if (!in_brace_param) { brct++; seen_brct = 1; } c = Inbrack; break; case LX2_OUTBRACK: if (!in_brace_param) brct--; if (brct < 0) brct = 0; c = Outbrack; break; case LX2_INPAR: if (isset(SHGLOB)) { if (sub || in_brace_param) break; if (incasepat && !lexbuf.len) return INPAR; if (!isset(KSHGLOB) && lexbuf.len) goto brk; } if (!in_brace_param) { if (!sub) { e = hgetc(); hungetc(e); lexstop = 0; /* For command words, parentheses are only * special at the start. But now we're tokenising * the remaining string. So I don't see what * the old incmdpos test here is for. * pws 1999/6/8 * * Oh, no. * func1( ) * is a valid function definition in [k]sh. The best * thing we can do, without really nasty lookahead tricks, * is break if we find a blank after a parenthesis. At * least this can't happen inside braces or brackets. We * only allow this with SHGLOB (set for both sh and ksh). * * Things like `print @( |foo)' should still * work, because [k]sh don't allow multiple words * in a function definition, so we only do this * in command position. * pws 1999/6/14 */ if (e == ')' || (isset(SHGLOB) && inblank(e) && !bct && !brct && !intpos && incmdpos)) { /* * Either a () token, or a command word with * something suspiciously like a ksh function * definition. * The current word isn't spellcheckable. */ nocorrect |= 2; goto brk; } } /* * This also handles the [k]sh `foo( )' function definition. * Maintain a variable fdpar, set as long as a single set of * parentheses contains only space. Then if we get to the * closing parenthesis and it is still set, we can assume we * have a function definition. Only do this at the start of * the word, since the (...) must be a separate token. */ if (!pct++ && isset(SHGLOB) && intpos && !bct && !brct) fdpar = 1; } c = Inpar; break; case LX2_INBRACE: if (isset(IGNOREBRACES) || sub) c = '{'; else { if (!lexbuf.len && incmdpos) { add('{'); *lexbuf.ptr = '\0'; return STRING; } if (in_brace_param) { cmdpush(CS_BRACE); } bct++; } break; case LX2_OUTBRACE: if ((isset(IGNOREBRACES) || sub) && !in_brace_param) break; if (!bct) break; if (in_brace_param) { cmdpop(); } if (bct-- == in_brace_param) in_brace_param = 0; c = Outbrace; break; case LX2_COMMA: if (unset(IGNOREBRACES) && !sub && bct > in_brace_param) c = Comma; break; case LX2_OUTANG: if (in_brace_param || sub) break; e = hgetc(); if (e != '(') { hungetc(e); lexstop = 0; goto brk; } add(OutangProc); if (skipcomm()) { peek = LEXERR; goto brk; } c = Outpar; break; case LX2_INANG: if (isset(SHGLOB) && sub) break; e = hgetc(); if (!(in_brace_param || sub) && e == '(') { add(Inang); if (skipcomm()) { peek = LEXERR; goto brk; } c = Outpar; break; } hungetc(e); if(isnumglob()) { add(Inang); while ((c = hgetc()) != '>') add(c); c = Outang; break; } lexstop = 0; if (in_brace_param || sub) break; goto brk; case LX2_EQUALS: if (!sub) { if (intpos) { e = hgetc(); if (e != '(') { hungetc(e); lexstop = 0; c = Equals; } else { add(Equals); if (skipcomm()) { peek = LEXERR; goto brk; } c = Outpar; } } else if (peek != ENVSTRING && (incmdpos || intypeset) && !bct && !brct) { char *t = tokstr; if (idigit(*t)) while (++t < lexbuf.ptr && idigit(*t)); else { int sav = *lexbuf.ptr; *lexbuf.ptr = '\0'; t = itype_end(t, IIDENT, 0); if (t < lexbuf.ptr) { skipparens(Inbrack, Outbrack, &t); } else { *lexbuf.ptr = sav; } } if (*t == '+') t++; if (t == lexbuf.ptr) { e = hgetc(); if (e == '(') { *lexbuf.ptr = '\0'; return ENVARRAY; } hungetc(e); lexstop = 0; peek = ENVSTRING; intpos = 2; } else c = Equals; } else c = Equals; } break; case LX2_BKSLASH: c = hgetc(); if (c == '\n') { c = hgetc(); if (!lexstop) continue; } else { add(Bnull); if (c == STOUC(Meta)) { c = hgetc(); #ifdef DEBUG if (lexstop) { fputs("BUG: input terminated by Meta\n", stderr); fflush(stderr); goto brk; } #endif add(Meta); } } if (lexstop) goto brk; break; case LX2_QUOTE: { int strquote = (lexbuf.len && lexbuf.ptr[-1] == String); add(Snull); cmdpush(CS_QUOTE); for (;;) { STOPHIST while ((c = hgetc()) != '\'' && !lexstop) { if (strquote && c == '\\') { c = hgetc(); if (lexstop) break; /* * Mostly we don't need to do anything special * with escape backslashes or closing quotes * inside $'...'; however in completion we * need to be able to strip multiple backslashes * neatly. */ if (c == '\\' || c == '\'') add(Bnull); else add('\\'); } else if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') { if (lexbuf.ptr[-1] == '\\') lexbuf.ptr--, lexbuf.len--; else break; } add(c); } ALLOWHIST if (c != '\'') { unmatched = '\''; peek = LEXERR; cmdpop(); goto brk; } e = hgetc(); if (e != '\'' || unset(RCQUOTES) || strquote) break; add(c); } cmdpop(); hungetc(e); lexstop = 0; c = Snull; break; } case LX2_DQUOTE: add(Dnull); cmdpush(CS_DQUOTE); c = dquote_parse('"', sub); cmdpop(); if (c) { unmatched = '"'; peek = LEXERR; goto brk; } c = Dnull; break; case LX2_BQUOTE: add(Tick); cmdpush(CS_BQUOTE); SETPARBEGIN inquote = 0; while ((c = hgetc()) != '`' && !lexstop) { if (c == '\\') { c = hgetc(); if (c != '\n') { add(c == '`' || c == '\\' || c == '$' ? Bnull : '\\'); add(c); } else if (!sub && isset(CSHJUNKIEQUOTES)) add(c); } else { if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') { break; } add(c); if (c == '\'') { if ((inquote = !inquote)) STOPHIST else ALLOWHIST } } } if (inquote) ALLOWHIST cmdpop(); if (c != '`') { unmatched = '`'; peek = LEXERR; goto brk; } c = Tick; SETPAREND break; case LX2_DASH: /* * - shouldn't be treated as a special character unless * we're in a pattern. Howeve,simply counting "[" doesn't * work as []a-z] is a valid expression and we don't know * down here what this "[" is for as $foo[stuff] is valid * in zsh. So just detect an opening [, which is enough * to turn this into a pattern; the Dash will be harmlessly * untokenised if not wanted. */ if (seen_brct) c = Dash; else c = '-'; break; case LX2_BANG: /* * Same logic as Dash, for ! to perform negation in range. */ if (seen_brct) c = Bang; else c = '!'; } add(c); c = hgetc(); if (intpos) intpos--; if (lexstop) break; } brk: if (errflag) { if (in_brace_param) { while(bct-- >= in_brace_param) cmdpop(); } return LEXERR; } hungetc(c); if (unmatched) zerr("unmatched %c", unmatched); if (in_brace_param) { while(bct-- >= in_brace_param) cmdpop(); zerr("closing brace expected"); } else if (unset(IGNOREBRACES) && !sub && lexbuf.len > 1 && peek == STRING && lexbuf.ptr[-1] == '}' && lexbuf.ptr[-2] != Bnull) { /* hack to get {foo} command syntax work */ lexbuf.ptr--; lexbuf.len--; lexstop = 0; hungetc('}'); } *lexbuf.ptr = '\0'; DPUTS(cmdsp != ocmdsp, "BUG: gettok: cmdstack changed."); return peek; }
static int gettokstr(int c, int sub) { int bct = 0, pct = 0, brct = 0, fdpar = 0; int intpos = 1, in_brace_param = 0; int peek, inquote, unmatched = 0; char endchar='"'; #ifdef DEBUG int ocmdsp = cmdsp; #endif peek = STRING; if (!sub) { len = 0; bptr = tokstr = (char *) hcalloc(bsiz = 32); } for (;;) { int act; int e; int inbl = inblank(c); if (fdpar && !inbl && c != ')') fdpar = 0; if (inbl && !in_brace_param && !pct) act = LX2_BREAK; else { act = lexact2[STOUC(c)]; c = lextok2[STOUC(c)]; } switch (act) { case LX2_BREAK: if (!in_brace_param && !sub) goto brk; break; case LX2_META: c = hgetc(); #ifdef DEBUG if (lexstop) { fputs("BUG: input terminated by Meta\n", stderr); fflush(stderr); goto brk; } #endif add(Meta); break; case LX2_OUTPAR: if (fdpar) { /* this is a single word `( )', treat as INOUTPAR */ add(c); *bptr = '\0'; return INOUTPAR; } if ((sub || in_brace_param) && isset(SHGLOB)) break; if (!in_brace_param && !pct--) { if (sub) { pct = 0; break; } else goto brk; } c = Outpar; break; case LX2_BAR: if (!pct && !in_brace_param) { if (sub) break; else goto brk; } if (unset(SHGLOB) || (!sub && !in_brace_param)) c = Bar; break; case LX2_STRING: e = hgetc(); if (e == '[') { cmdpush(CS_MATHSUBST); add(String); add(Inbrack); c = dquote_parse(']', sub); cmdpop(); if (c) { peek = LEXERR; goto brk; } c = Outbrack; } else if (e == '(') { add(String); c = cmd_or_math_sub(); if (c) { peek = LEXERR; goto brk; } c = Outpar; } else { if (e == '{') { add(c); c = Inbrace; ++bct; cmdpush(CS_BRACEPAR); if (!in_brace_param) in_brace_param = bct; } else { hungetc(e); lexstop = 0; } } break; case LX2_INBRACK: if (!in_brace_param) brct++; c = Inbrack; break; case LX2_OUTBRACK: if (!in_brace_param) brct--; if (brct < 0) brct = 0; c = Outbrack; break; case LX2_INPAR: if (isset(SHGLOB)) { if (sub || in_brace_param) break; if (incasepat && !len) return INPAR; } if (!in_brace_param) { if (!sub) { e = hgetc(); hungetc(e); lexstop = 0; /* For command words, parentheses are only * special at the start. But now we're tokenising * the remaining string. So I don't see what * the old incmdpos test here is for. * pws 1999/6/8 * * Oh, no. * func1( ) * is a valid function definition in [k]sh. The best * thing we can do, without really nasty lookahead tricks, * is break if we find a blank after a parenthesis. At * least this can't happen inside braces or brackets. We * only allow this with SHGLOB (set for both sh and ksh). * * Things like `print @( |foo)' should still * work, because [k]sh don't allow multiple words * in a function definition, so we only do this * in command position. * pws 1999/6/14 */ if (e == ')' || (isset(SHGLOB) && inblank(e) && !bct && !brct && !intpos && incmdpos)) goto brk; } /* * This also handles the [k]sh `foo( )' function definition. * Maintain a variable fdpar, set as long as a single set of * parentheses contains only space. Then if we get to the * closing parenthesis and it is still set, we can assume we * have a function definition. Only do this at the start of * the word, since the (...) must be a separate token. */ if (!pct++ && isset(SHGLOB) && intpos && !bct && !brct) fdpar = 1; } c = Inpar; break; case LX2_INBRACE: if (isset(IGNOREBRACES) || sub) c = '{'; else { if (!len && incmdpos) { add('{'); *bptr = '\0'; return STRING; } if (in_brace_param) { cmdpush(CS_BRACE); } bct++; } break; case LX2_OUTBRACE: if ((isset(IGNOREBRACES) || sub) && !in_brace_param) break; if (!bct) break; if (in_brace_param) { cmdpop(); } if (bct-- == in_brace_param) in_brace_param = 0; c = Outbrace; break; case LX2_COMMA: if (unset(IGNOREBRACES) && !sub && bct > in_brace_param) c = Comma; break; case LX2_OUTANG: if (!intpos) { if (in_brace_param || sub) break; else goto brk; } e = hgetc(); if (e != '(') { hungetc(e); lexstop = 0; goto brk; } add(Outang); if (skipcomm()) { peek = LEXERR; goto brk; } c = Outpar; break; case LX2_INANG: if (isset(SHGLOB) && sub) break; e = hgetc(); if(e == '(' && intpos) { add(Inang); if (skipcomm()) { peek = LEXERR; goto brk; } c = Outpar; break; } hungetc(e); if(isnumglob()) { add(Inang); while ((c = hgetc()) != '>') add(c); c = Outang; break; } lexstop = 0; if (in_brace_param || sub) break; goto brk; case LX2_EQUALS: if (intpos) { e = hgetc(); if (e != '(') { hungetc(e); lexstop = 0; c = Equals; } else { add(Equals); if (skipcomm()) { peek = LEXERR; goto brk; } c = Outpar; } } else if (!sub && peek != ENVSTRING && incmdpos && !bct && !brct) { char *t = tokstr; if (idigit(*t)) while (++t < bptr && idigit(*t)); else { while (iident(*t) && ++t < bptr); if (t < bptr) { *bptr = '\0'; skipparens(Inbrack, Outbrack, &t); } } if (*t == '+') t++; if (t == bptr) { e = hgetc(); if (e == '(' && incmdpos) { *bptr = '\0'; return ENVARRAY; } hungetc(e); lexstop = 0; peek = ENVSTRING; intpos = 2; } else c = Equals; } else c = Equals; break; #ifndef __SYMBIAN32__ case LX2_BKSLASH: c = hgetc(); if (c == '\n') { c = hgetc(); if (!lexstop) continue; } else add(Bnull); if (lexstop) goto brk; break; #endif case LX2_QUOTE: { int strquote = (len && bptr[-1] == String); add(Snull); cmdpush(CS_QUOTE); for (;;) { STOPHIST while ((c = hgetc()) != '\'' && !lexstop) { if (strquote && c == '\\') { add(c); c = hgetc(); if (lexstop) break; } else if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') { if (bptr[-1] == '\\') bptr--, len--; else break; } add(c); } ALLOWHIST if (c != '\'') { unmatched = '\''; peek = LEXERR; cmdpop(); goto brk; } e = hgetc(); if (e != '\'' || unset(RCQUOTES) || strquote) break; add(c); } cmdpop(); hungetc(e); lexstop = 0; c = Snull; break; } case LX2_DQUOTE: add(Dnull); cmdpush(CS_DQUOTE); c = dquote_parse('"', sub); cmdpop(); if (c) { unmatched = '"'; peek = LEXERR; goto brk; } c = Dnull; break; case LX2_BQUOTE: add(Tick); cmdpush(CS_BQUOTE); SETPARBEGIN inquote = 0; while ((c = hgetc()) != '`' && !lexstop) { if (c == '\\') { c = hgetc(); if (c != '\n') { add(c == '`' || c == '\\' || c == '$' ? Bnull : '\\'); add(c); } else if (!sub && isset(CSHJUNKIEQUOTES)) add(c); } else { if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') { break; } add(c); if (c == '\'') { if ((inquote = !inquote)) STOPHIST else ALLOWHIST } } } if (inquote) ALLOWHIST cmdpop(); if (c != '`') { unmatched = '`'; peek = LEXERR; goto brk; } c = Tick; SETPAREND break; } #ifdef __SYMBIAN32__ if(c=='\\') { c = hgetc(); if (c != '\n') { if (c == endchar) add(Bnull); else { /* lexstop is implicitly handled here */ add('\\'); } } } #endif add(c); c = hgetc(); if (intpos) intpos--; if (lexstop) break; } brk: hungetc(c); if (unmatched) zerr("unmatched %c", NULL, unmatched); if (in_brace_param) { while(bct-- >= in_brace_param) cmdpop(); zerr("closing brace expected", NULL, 0); } else if (unset(IGNOREBRACES) && !sub && len > 1 && peek == STRING && bptr[-1] == '}' && bptr[-2] != Bnull) { /* hack to get {foo} command syntax work */ bptr--; len--; lexstop = 0; hungetc('}'); } *bptr = '\0'; DPUTS(cmdsp != ocmdsp, "BUG: gettok: cmdstack changed."); return peek; }
int gettok(void) { int c, d; int peekfd = -1, peek; beginning: tokstr = NULL; while (iblank(c = hgetc()) && !lexstop); if (lexstop) return (errflag) ? LEXERR : ENDINPUT; isfirstln = 0; wordbeg = inbufct - (qbang && c == bangchar); hwbegin(-1-(qbang && c == bangchar)); /* word includes the last character read and possibly \ before ! */ if (dbparens) { len = 0; bptr = tokstr = (char *) hcalloc(bsiz = 32); hungetc(c); cmdpush(CS_MATH); c = dquote_parse(infor ? ';' : ')', 0); cmdpop(); *bptr = '\0'; if (!c && infor) { infor--; return DINPAR; } if (c || (c = hgetc()) != ')') { hungetc(c); return LEXERR; } dbparens = 0; return DOUTPAR; } else if (idigit(c)) { /* handle 1< foo */ d = hgetc(); if(d == '&') { d = hgetc(); if(d == '>') { peekfd = c - '0'; hungetc('>'); c = '&'; } else { hungetc(d); lexstop = 0; hungetc('&'); } } else if (d == '>' || d == '<') { peekfd = c - '0'; c = d; } else { hungetc(d); lexstop = 0; } } /* chars in initial position in word */ if (c == hashchar && !nocomments && (isset(INTERACTIVECOMMENTS) || (!zleparse && !expanding && (!interact || unset(SHINSTDIN) || strin)))) { /* History is handled here to prevent extra * * newlines being inserted into the history. */ while ((c = ingetc()) != '\n' && !lexstop) { hwaddc(c); addtoline(c); } if (errflag) peek = LEXERR; else { hwend(); hwbegin(0); hwaddc('\n'); addtoline('\n'); peek = NEWLIN; } return peek; } switch (lexact1[STOUC(c)]) { case LX1_BKSLASH: d = hgetc(); if (d == '\n') goto beginning; hungetc(d); lexstop = 0; break; case LX1_NEWLIN: return NEWLIN; case LX1_SEMI: d = hgetc(); if(d == ';') return DSEMI; else if(d == '&') return SEMIAMP; hungetc(d); lexstop = 0; return SEMI; case LX1_AMPER: d = hgetc(); if (d == '&') return DAMPER; else if (d == '!' || d == '|') return AMPERBANG; else if (d == '>') { tokfd = peekfd; d = hgetc(); if (d == '!' || d == '|') return OUTANGAMPBANG; else if (d == '>') { d = hgetc(); if (d == '!' || d == '|') return DOUTANGAMPBANG; hungetc(d); lexstop = 0; return DOUTANGAMP; } hungetc(d); lexstop = 0; return AMPOUTANG; } hungetc(d); lexstop = 0; return AMPER; case LX1_BAR: d = hgetc(); if (d == '|') return DBAR; else if (d == '&') return BARAMP; hungetc(d); lexstop = 0; return BAR; case LX1_INPAR: d = hgetc(); if (d == '(') { if (infor) { dbparens = 1; return DINPAR; } if (incmdpos) { len = 0; bptr = tokstr = (char *) hcalloc(bsiz = 32); return cmd_or_math(CS_MATH) ? DINPAR : INPAR; } } else if (d == ')') return INOUTPAR; hungetc(d); lexstop = 0; if (!(incond == 1 || incmdpos)) break; return INPAR; case LX1_OUTPAR: return OUTPAR; case LX1_INANG: d = hgetc(); if (!incmdpos && d == '(') { hungetc(d); lexstop = 0; unpeekfd: if(peekfd != -1) { hungetc(c); c = '0' + peekfd; } break; } if (d == '>') { peek = INOUTANG; } else if (d == '<') { int e = hgetc(); if (e == '(') { hungetc(e); hungetc(d); peek = INANG; } else if (e == '<') peek = TRINANG; else if (e == '-') peek = DINANGDASH; else { hungetc(e); lexstop = 0; peek = DINANG; } } else if (d == '&') { peek = INANGAMP; } else { hungetc(d); if(isnumglob()) goto unpeekfd; peek = INANG; } tokfd = peekfd; return peek; case LX1_OUTANG: d = hgetc(); if (d == '(') { hungetc(d); goto unpeekfd; } else if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = OUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = OUTANGAMP; } } else if (d == '!' || d == '|') peek = OUTANGBANG; else if (d == '>') { d = hgetc(); if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = DOUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = DOUTANGAMP; } } else if (d == '!' || d == '|') peek = DOUTANGBANG; else if (d == '(') { hungetc(d); hungetc('>'); peek = OUTANG; } else { hungetc(d); lexstop = 0; peek = DOUTANG; if (isset(HISTALLOWCLOBBER)) hwaddc('|'); } } else { hungetc(d); lexstop = 0; peek = OUTANG; if (!incond && isset(HISTALLOWCLOBBER)) hwaddc('|'); } tokfd = peekfd; return peek; } /* we've started a string, now get the * * rest of it, performing tokenization */ return gettokstr(c, 0); }