📄 set.c
字号:
/*- * Copyright (c) 1980, 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)set.c 8.1 (Berkeley) 5/31/93";#endif /* not lint */#include <sys/types.h>#include <stdlib.h>#ifndef SHORT_STRINGS#include <string.h>#endif /* SHORT_STRINGS */#if __STDC__# include <stdarg.h>#else# include <varargs.h>#endif#include "csh.h"#include "extern.h"static Char *getinx __P((Char *, int *));static void asx __P((Char *, int, Char *));static struct varent *getvx __P((Char *, int));static Char *xset __P((Char *, Char ***));static Char *operate __P((int, Char *, Char *));static void putn1 __P((int));static struct varent *madrof __P((Char *, struct varent *));static void unsetv1 __P((struct varent *));static void exportpath __P((Char **));static void balance __P((struct varent *, int, int));/* * C Shell */void/*ARGSUSED*/doset(v, t) Char **v; struct command *t;{ register Char *p; Char *vp, op; Char **vecp; bool hadsub; int subscr; 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 - vp) > MAXVARLEN) { stderror(ERR_NAME | ERR_VARTOOLONG); return; } if (*p == '[') { hadsub++; p = getinx(p, &subscr); } if ((op = *p) != '\0') { *p++ = 0; if (*p == 0 && *v && **v == '(') p = *v++; } else if (*v && eq(*v, STRequal)) { op = '=', v++; if (*v) p = *v++; } if (op && op != '=') stderror(ERR_NAME | ERR_SYNTAX); if (eq(p, STRLparen)) { register 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); set1(vp, vecp, &shvhed); *e = p; v = e + 1; } else if (hadsub) asx(vp, subscr, Strsave(p)); else set(vp, Strsave(p)); if (eq(vp, STRpath)) { exportpath(adrof(STRpath)->vec); dohash(NULL, NULL); } else if (eq(vp, STRhistchars)) { register Char *pn = value(STRhistchars); HIST = *pn++; HISTSUB = *pn; } else if (eq(vp, STRuser)) { Setenv(STRUSER, value(vp)); Setenv(STRLOGNAME, value(vp)); } else if (eq(vp, STRwordchars)) { word_chars = value(vp); } else if (eq(vp, STRterm)) Setenv(STRTERM, value(vp)); else if (eq(vp, STRhome)) { register Char *cp; cp = Strsave(value(vp)); /* get the old value back */ /* * convert to cononical pathname (possibly resolving symlinks) */ cp = dcanon(cp, cp); set(vp, Strsave(cp)); /* have to save the new val */ /* and now mirror home with HOME */ Setenv(STRHOME, cp); /* fix directory stack for new tilde home */ dtilde(); xfree((ptr_t) cp); }#ifdef FILEC else if (eq(vp, STRfilec)) filec = 1;#endif } while ((p = *v++) != NULL);}static Char *getinx(cp, ip) register Char *cp; register int *ip;{ *ip = 0; *cp++ = 0; while (*cp && Isdigit(*cp)) *ip = *ip * 10 + *cp++ - '0'; if (*cp++ != ']') stderror(ERR_NAME | ERR_SUBSCRIPT); return (cp);}static voidasx(vp, subscr, p) Char *vp; int subscr; Char *p;{ register struct varent *v = getvx(vp, subscr); xfree((ptr_t) v->vec[subscr - 1]); v->vec[subscr - 1] = globone(p, G_APPEND);}static struct varent *getvx(vp, subscr) Char *vp; int subscr;{ register struct varent *v = adrof(vp); if (v == 0) udvar(vp); if (subscr < 1 || subscr > blklen(v->vec)) stderror(ERR_NAME | ERR_RANGE); return (v);}void/*ARGSUSED*/dolet(v, t) Char **v; struct command *t;{ register Char *p; Char *vp, c, op; bool hadsub; int subscr; 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 - vp) > MAXVARLEN) stderror(ERR_NAME | ERR_VARTOOLONG); 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 (*p == '\0' && *v == NULL) stderror(ERR_NAME | ERR_ASSIGN); vp = Strsave(vp); 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); c = *p++; stderror(ERR_NAME | ERR_SYNTAX); } if (c != '=') stderror(ERR_NAME | ERR_UNKNOWNOP); p = xset(p, &v); } } if (op == '=') if (hadsub) asx(vp, subscr, p); else set(vp, p); else if (hadsub) { struct varent *gv = getvx(vp, subscr); asx(vp, subscr, operate(op, gv->vec[subscr - 1], p)); } else set(vp, operate(op, value(vp), p)); if (eq(vp, STRpath)) { exportpath(adrof(STRpath)->vec); dohash(NULL, NULL); } xfree((ptr_t) vp); if (c != '=') xfree((ptr_t) p); } while ((p = *v++) != NULL);}static Char *xset(cp, vp) Char *cp, ***vp;{ register Char *dp; if (*cp) { dp = Strsave(cp); --(*vp); xfree((ptr_t) ** vp); **vp = dp; } return (putn(expr(vp)));}static Char *operate(op, vp, p) int op; Char *vp, *p;{ Char opr[2]; Char *vec[5]; register Char **v = vec; Char **vecp = v; register int i; if (op != '=') { if (*vp) *v++ = vp; opr[0] = op; opr[1] = 0; *v++ = opr; if (op == '<' || op == '>') *v++ = opr; } *v++ = p; *v++ = 0; i = expr(&vecp); if (*vecp) stderror(ERR_NAME | ERR_EXPRESSION); return (putn(i));}static Char *putp;Char *putn(n) register int n;{ int num; static Char number[15]; putp = number; if (n < 0) { n = -n; *putp++ = '-'; } num = 2; /* confuse lint */ if (sizeof(int) == num && ((unsigned int) n) == 0x8000) { *putp++ = '3'; n = 2768;#ifdef pdp11 }#else } else { num = 4; /* confuse lint */ if (sizeof(int) == num && ((unsigned int) n) == 0x80000000) { *putp++ = '2'; n = 147483648; } }#endif putn1(n); *putp = 0; return (Strsave(number));}static voidputn1(n) register int n;{ if (n > 9) putn1(n / 10); *putp++ = n % 10 + '0';}intgetn(cp) register Char *cp;{ register int n; int sign; sign = 0; if (cp[0] == '+' && cp[1]) cp++; if (*cp == '-') { sign++; cp++; if (!Isdigit(*cp)) stderror(ERR_NAME | ERR_BADNUM); } n = 0; while (Isdigit(*cp)) n = n * 10 + *cp++ - '0'; if (*cp) stderror(ERR_NAME | ERR_BADNUM); return (sign ? -n : n);}Char *value1(var, head)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -