📄 variable.c
字号:
else if (eq(varname, "prompt") && (type == VT_STRING)) cp_promptstring = copy(v->va_string); else if (eq(varname, "ignoreeof")) cp_ignoreeof = true; else if (eq(varname, "cpdebug")) { cp_debug = true;#ifndef CPDEBUG fprintf(cp_err, "Warning: program not compiled with cshpar debug messages\n");#endif } switch (i = cp_usrset(v, true)) { case US_OK: /* Normal case. */ if (!alreadythere) { v->va_next = variables; variables = v; } break; case US_DONTRECORD: /* Do nothing... */ if (alreadythere) { fprintf(cp_err, "cp_vset: Internal Error: %s already there, but 'dont record'\n", v->va_name); } break; case US_READONLY: /* Badness... */ fprintf(cp_err, "Error: %s is a read-only variable.\n", v->va_name); if (alreadythere) fprintf(cp_err, "cp_vset: Internal Error: it was already there too!!\n"); break; default: fprintf(cp_err, "cp_vset: Internal Error: bad US val %d\n", i); break; } return;}voidcp_remvar(varname) char *varname;{ struct variable *v, *lv = NULL; bool found = true; int i; for (v = variables; v; v = v->va_next) { if (eq(v->va_name, varname)) break; lv = v; } if (!v) { /* Gotta make up a var struct for cp_usrset()... */ v = alloc(variable); v->va_name = varname; found = false; } /* Note that 'unset history' doesn't do anything here... Causes * trouble... */ if (eq(varname, "noglob")) cp_noglob = false; else if (eq(varname, "nonomatch")) cp_nonomatch = false; else if (eq(varname, "noclobber")) cp_noclobber = false; else if (eq(varname, "prompt")) cp_promptstring = ""; else if (eq(varname, "cpdebug")) cp_debug = false; else if (eq(varname, "ignoreeof")) cp_ignoreeof = false; switch (i = cp_usrset(v, false)) { case US_OK: /* Normal case. */ if (found) { if (lv) lv->va_next = v->va_next; else variables = v->va_next; } break; case US_DONTRECORD: /* Do nothing... */ if (found) fprintf(cp_err, "cp_remvar: Internal Error: var %d in list but shouldn't be\n", varname); break; case US_READONLY: /* Badness... */ fprintf(cp_err, "Error: %s is a read-only variable.\n", v->va_name); if (found) fprintf(cp_err, "cp_remvar: Internal Error: var %d in list but shouldn't be\n", varname); break; default: fprintf(cp_err, "cp_remvar: Internal Error: bad US val %d\n", i); break; } tfree(v); return;}/* The set command. Syntax is * set [opt ...] [opt = val ...]. Val may be a string, an int, a float, * or a list of the form (elt1 elt2 ...). */voidcom_set(wl) wordlist *wl;{ struct variable *vars; char *s; if (wl == NULL) { cp_vprint(); return; } vars = cp_setparse(wl); /* This is sort of a hassle... */ while (vars) { switch (vars->va_type) { case VT_BOOL: s = (char *) &vars->va_bool; break; case VT_NUM: s = (char *) &vars->va_num; break; case VT_REAL: s = (char *) &vars->va_real; break; case VT_STRING: s = vars->va_string; break; case VT_LIST: s = (char *) vars->va_vlist; break; } cp_vset(vars->va_name, vars->va_type, s); vars = vars->va_next; } return;}struct variable *cp_setparse(wl) wordlist *wl;{ char *name, *val, *s, *ss; double *td; struct variable *listv = NULL, *vv, *lv = NULL; struct variable *vars = NULL; int balance; while (wl) { name = cp_unquote(wl->wl_word); wl = wl->wl_next; if (((wl == NULL) || (*wl->wl_word != '=')) && index(name, '=') == NULL) { vv = alloc(variable); vv->va_name = copy(name); vv->va_type = VT_BOOL; vv->va_bool = true; vv->va_next = vars; vars = vv; continue; } if (wl && eq(wl->wl_word, "=")) { wl = wl->wl_next; if (wl == NULL) { fprintf(cp_err, "Error: bad set form.\n"); return (NULL); } val = wl->wl_word; wl = wl->wl_next; } else if (wl && (*wl->wl_word == '=')) { val = wl->wl_word + 1; wl = wl->wl_next; } else if (s = index(name, '=')) { val = s + 1; *s = '\0'; if (*val == '\0') { if (!wl) { fprintf(cp_err, "Error: %s equals what?.\n", name); return (NULL); } else { val = wl->wl_word; wl = wl->wl_next; } } } else { fprintf(cp_err, "Error: bad set form.\n"); return (NULL); } val = cp_unquote(val); if (eq(val, "(")) { /* ) */ /* The beginning of a list... We have to walk down * the list until we find a close paren... If there * are nested ()'s, treat them as tokens... */ balance = 1; while (wl) { if (eq(wl->wl_word, "(")) { /* ) ( */ balance++; } else if (eq(wl->wl_word, ")")) { if (!--balance) break; } vv = alloc(variable); ss = cp_unquote(wl->wl_word); td = ft_numparse(&ss, false); if (td) { vv->va_type = VT_REAL; vv->va_real = *td; } else { vv->va_type = VT_STRING; vv->va_string = copy(ss); } if (listv) { lv->va_next = vv; lv = vv; } else listv = lv = vv; wl = wl->wl_next; } if (balance && !wl) { fprintf(cp_err, "Error: bad set form.\n"); return (NULL); } vv = alloc(variable); vv->va_name = copy(name); vv->va_type = VT_LIST; vv->va_vlist = listv; vv->va_next = vars; vars = vv; wl = wl->wl_next; continue; } ss = cp_unquote(val); td = ft_numparse(&ss, false); vv = alloc(variable); vv->va_name = copy(name); vv->va_next = vars; vars = vv; if (td) { /*** We should try to get VT_NUM's... */ vv->va_type = VT_REAL; vv->va_real = *td; } else { vv->va_type = VT_STRING; vv->va_string = copy(val); } } return (vars);}voidcom_unset(wl) wordlist *wl;{ register char *name; struct variable *var, *nv; if (eq(wl->wl_word, "*")) { for (var = variables; var; var = nv) { nv = var->va_next; cp_remvar(var->va_name); } wl = wl->wl_next; } while (wl != NULL) { name = wl->wl_word; cp_remvar(name); wl = wl->wl_next; } return;}/* Shift a list variable, by default argv, one to the left (or more if a * second argument is given. */voidcom_shift(wl) wordlist *wl;{ struct variable *v, *vv; char *n = "argv"; int num = 1; if (wl) { n = wl->wl_word; wl = wl->wl_next; } if (wl) num = scannum(wl->wl_word); for (v = variables; v; v = v->va_next) if (eq(v->va_name, n)) break; if (!v) { fprintf(cp_err, "Error: %s: no such variable\n", n); return; } if (v->va_type != VT_LIST) { fprintf(cp_err, "Error: %s not of type list\n", n); return; } for (vv = v->va_vlist; vv && (num > 0); num--) vv = vv->va_next; if (num) { fprintf(cp_err, "Error: variable %s not long enough\n", n); return; } v->va_vlist = vv; return;}/* Determine the value of a variable. Fail if the variable is unset, * and if the type doesn't match, try and make it work... */boolcp_getvar(name, type, retval) int type; char *name, *retval;{ struct variable *v; for (v = variables; v; v = v->va_next) if (eq(name, v->va_name)) break; if (v == NULL) { if (type == VT_BOOL) * (bool *) retval = false; return (false); } if (v->va_type == type) { switch (type) { case VT_BOOL: * (bool *) retval = true; break; case VT_NUM: { int *i; i = (int *) retval; *i = v->va_num; break; } case VT_REAL: { double *d; d = (double *) retval; *d = v->va_real; break; } case VT_STRING: { /* Gotta be careful to have room. */ char *s; s = cp_unquote(v->va_string); cp_wstrip(s); (void) strcpy(retval, s); break; } case VT_LIST: { /* Funny case... */ struct variable **tv; tv = (struct variable **) retval; *tv = v->va_vlist; break; } default: fprintf(cp_err, "cp_getvar: Internal Error: bad var type %d.\n", type); break; } return (true); } else { /* Try to coerce it.. */ if ((type == VT_NUM) && (v->va_type == VT_REAL)) { int *i; i = (int *) retval; *i = (int) v->va_real; return (true); } else if ((type == VT_REAL) && (v->va_type == VT_NUM)) { double *d; d = (double *) retval; *d = (double) v->va_num; return (true); } else if ((type == VT_STRING) && (v->va_type == VT_NUM)) { (void) sprintf(retval, "%d", v->va_num); return (true); } else if ((type == VT_STRING) && (v->va_type == VT_REAL)) { (void) sprintf(retval, "%f", v->va_real); return (true); } return (false); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -