📄 c_ksh.c
字号:
if (!tp && !pflag) { tp = tsearch(&aliases, id, hash(id)); if (tp && !(tp->flag & ISSET)) tp = NULL; } if (!tp) tp = findcom(id, fcflags); if (vflag || (tp->type != CALIAS && tp->type != CEXEC && tp->type != CTALIAS)) shprintf("%s", id); switch (tp->type) { case CKEYWD: if (vflag) shprintf(" is a reserved word"); break; case CALIAS: if (vflag) shprintf(" is an %salias for ", (tp->flag & EXPORT) ? "exported " : null); if (!iam_whence && !vflag) shprintf("alias %s=", id); print_value_quoted(tp->val.s); break; case CFUNC: if (vflag) { shprintf(" is a"); if (tp->flag & EXPORT) shprintf("n exported"); if (tp->flag & TRACE) shprintf(" traced"); if (!(tp->flag & ISSET)) { shprintf(" undefined"); if (tp->u.fpath) shprintf(" (autoload from %s)", tp->u.fpath); } shprintf(" function"); } break; case CSHELL: if (vflag) shprintf(" is a%s shell builtin", (tp->flag & SPEC_BI) ? " special" : null); break; case CTALIAS: case CEXEC: if (tp->flag & ISSET) { if (vflag) { shprintf(" is "); if (tp->type == CTALIAS) shprintf( "a tracked %salias for ", (tp->flag & EXPORT) ? "exported " : null); } shprintf("%s", tp->val.s); } else { if (vflag) shprintf(" not found"); ret = 1; } break; default: shprintf("%s is *GOK*", id); break; } if (vflag || !ret) shprintf(newline); } return ret;}/* Deal with command -vV - command -p dealt with in comexec() */intc_command(wp) char **wp;{ /* Let c_whence do the work. Note that c_command() must be * a distinct function from c_whence() (tested in comexec()). */ return c_whence(wp);}/* typeset, export, and readonly */intc_typeset(wp) char **wp;{ struct block *l = e->loc; struct tbl *vp, **p; Tflag fset = 0, fclr = 0; int thing = 0, func = 0, local = 0; const char *options = "L#R#UZ#fi#lprtux"; /* see comment below */ char *fieldstr, *basestr; int field, base; int optc; Tflag flag; int pflag = 0; switch (**wp) { case 'e': /* export */ fset |= EXPORT; options = "p"; break; case 'r': /* readonly */ fset |= RDONLY; options = "p"; break; case 's': /* set */ /* called with 'typeset -' */ break; case 't': /* typeset */ local = 1; break; } fieldstr = basestr = (char *) 0; builtin_opt.flags |= GF_PLUSOPT; /* at&t ksh seems to have 0-9 as options, which are multiplied * to get a number that is used with -L, -R, -Z or -i (eg, -1R2 * sets right justify in a field of 12). This allows options * to be grouped in an order (eg, -Lu12), but disallows -i8 -L3 and * does not allow the number to be specified as a separate argument * Here, the number must follow the RLZi option, but is optional * (see the # kludge in ksh_getopt()). */ while ((optc = ksh_getopt(wp, &builtin_opt, options)) != EOF) { flag = 0; switch (optc) { case 'L': flag = LJUST; fieldstr = builtin_opt.optarg; break; case 'R': flag = RJUST; fieldstr = builtin_opt.optarg; break; case 'U': /* at&t ksh uses u, but this conflicts with * upper/lower case. If this option is changed, * need to change the -U below as well */ flag = INT_U; break; case 'Z': flag = ZEROFIL; fieldstr = builtin_opt.optarg; break; case 'f': func = 1; break; case 'i': flag = INTEGER; basestr = builtin_opt.optarg; break; case 'l': flag = LCASEV; break; case 'p': /* posix export/readonly -p flag. * typset -p is the same as typeset (in pdksh); * here for compatability with ksh93. */ pflag = 1; break; case 'r': flag = RDONLY; break; case 't': flag = TRACE; break; case 'u': flag = UCASEV_AL; /* upper case / autoload */ break; case 'x': flag = EXPORT; break; case '?': return 1; } if (builtin_opt.info & GI_PLUS) { fclr |= flag; fset &= ~flag; thing = '+'; } else { fset |= flag; fclr &= ~flag; thing = '-'; } } field = 0; if (fieldstr && !bi_getn(fieldstr, &field)) return 1; base = 0; if (basestr && !bi_getn(basestr, &base)) return 1; if (!(builtin_opt.info & GI_MINUSMINUS) && wp[builtin_opt.optind] && (wp[builtin_opt.optind][0] == '-' || wp[builtin_opt.optind][0] == '+') && wp[builtin_opt.optind][1] == '\0') { thing = wp[builtin_opt.optind][0]; builtin_opt.optind++; } if (func && ((fset|fclr) & ~(TRACE|UCASEV_AL|EXPORT))) { bi_errorf("only -t, -u and -x options may be used with -f"); return 1; } if (wp[builtin_opt.optind]) { /* Take care of exclusions. * At this point, flags in fset are cleared in fclr and vise * versa. This property should be preserved. */ if (fset & LCASEV) /* LCASEV has priority over UCASEV_AL */ fset &= ~UCASEV_AL; if (fset & LJUST) /* LJUST has priority over RJUST */ fset &= ~RJUST; if ((fset & (ZEROFIL|LJUST)) == ZEROFIL) { /* -Z implies -ZR */ fset |= RJUST; fclr &= ~RJUST; } /* Setting these attributes clears the others, unless they * are also set in this command */ if (fset & (LJUST|RJUST|ZEROFIL|UCASEV_AL|LCASEV|INTEGER |INT_U|INT_L)) fclr |= ~fset & (LJUST|RJUST|ZEROFIL|UCASEV_AL|LCASEV|INTEGER |INT_U|INT_L); } /* set variables and attributes */ if (wp[builtin_opt.optind]) { int i; int rval = 0; struct tbl *f; if (local && !func) fset |= LOCAL; for (i = builtin_opt.optind; wp[i]; i++) { if (func) { f = findfunc(wp[i], hash(wp[i]), (fset&UCASEV_AL) ? TRUE : FALSE); if (!f) { /* at&t ksh does ++rval: bogus */ rval = 1; continue; } if (fset | fclr) { f->flag |= fset; f->flag &= ~fclr; } else fptreef(shl_stdout, 0, f->flag & FKSH ? "function %s %T\n" : "%s() %T\n" , wp[i], f->val.t); } else if (!typeset(wp[i], fset, fclr, field, base)) { bi_errorf("%s: not identifier", wp[i]); return 1; } } return rval; } /* list variables and attributes */ flag = fset | fclr; /* no difference at this point.. */ if (func) { for (l = e->loc; l; l = l->next) { for (p = tsort(&l->funs); (vp = *p++); ) { if (flag && (vp->flag & flag) == 0) continue; if (thing == '-') fptreef(shl_stdout, 0, vp->flag & FKSH ? "function %s %T\n" : "%s() %T\n", vp->name, vp->val.t); else shprintf("%s\n", vp->name); } } } else { for (l = e->loc; l; l = l->next) { for (p = tsort(&l->vars); (vp = *p++); ) { struct tbl *tvp; int any_set = 0; /* * See if the parameter is set (for arrays, if any * element is set). */ for (tvp = vp; tvp; tvp = tvp->u.array) if (tvp->flag & ISSET) { any_set = 1; break; } /* * Check attributes - note that all array elements * have (should have?) the same attributes, so checking * the first is sufficient. * * Report an unset param only if the user has * explicitly given it some attribute (like export); * otherwise, after "echo $FOO", we would report FOO... */ if (!any_set && !(vp->flag & USERATTRIB)) continue; if (flag && (vp->flag & flag) == 0) continue; for (; vp; vp = vp->u.array) { /* Ignore array elements that aren't set unless there * are no set elements, in which case the first is * reported on */ if ((vp->flag&ARRAY) && any_set && !(vp->flag & ISSET)) continue; /* no arguments */ if (thing == 0 && flag == 0) { /* at&t ksh prints things like export, integer, * leftadj, zerofill, etc., but POSIX says must * be suitable for re-entry... */ shprintf("typeset "); if ((vp->flag&INTEGER)) shprintf("-i "); if ((vp->flag&EXPORT)) shprintf("-x "); if ((vp->flag&RDONLY)) shprintf("-r "); if ((vp->flag&TRACE)) shprintf("-t "); if ((vp->flag&LJUST)) shprintf("-L%d ", vp->u2.field); if ((vp->flag&RJUST)) shprintf("-R%d ", vp->u2.field); if ((vp->flag&ZEROFIL)) shprintf("-Z "); if ((vp->flag&LCASEV)) shprintf("-l "); if ((vp->flag&UCASEV_AL)) shprintf("-u "); if ((vp->flag&INT_U)) shprintf("-U "); shprintf("%s\n", vp->name); if (vp->flag&ARRAY) break; } else { if (pflag) shprintf("%s ", (flag & EXPORT) ? "export" : "readonly"); if ((vp->flag&ARRAY) && any_set) shprintf("%s[%d]", vp->name, vp->index); else shprintf("%s", vp->name); if (thing == '-' && (vp->flag&ISSET)) { char *s = str_val(vp); shprintf("="); /* at&t ksh can't have justified integers.. */ if ((vp->flag & (INTEGER|LJUST|RJUST)) == INTEGER) shprintf("%s", s); else print_value_quoted(s); } shprintf(newline); } /* Only report first `element' of an array with * no set elements. */ if (!any_set) break; } } } } return 0;} intc_alias(wp) char **wp;{ struct table *t = &aliases; int rv = 0, rflag = 0, tflag, Uflag = 0, pflag = 0; int prefix = 0; Tflag xflag = 0; int optc; builtin_opt.flags |= GF_PLUSOPT; while ((optc = ksh_getopt(wp, &builtin_opt, "dprtUx")) != EOF) { prefix = builtin_opt.info & GI_PLUS ? '+' : '-'; switch (optc) { case 'd': t = &homedirs; break; case 'p': pflag = 1; break; case 'r': rflag = 1; break; case 't': t = &taliases; break; case 'U': /* kludge for tracked alias initialization * (don't do a path search, just make an entry) */ Uflag = 1; break; case 'x': xflag = EXPORT; break; case '?': return 1; } } wp += builtin_opt.optind; if (!(builtin_opt.info & GI_MINUSMINUS) && *wp && (wp[0][0] == '-' || wp[0][0] == '+') && wp[0][1] == '\0') { prefix = wp[0][0]; wp++; } tflag = t == &taliases; /* "hash -r" means reset all the tracked aliases.. */ if (rflag) { static const char *const args[] = { "unalias", "-ta", (const char *) 0 }; if (!tflag || *wp) { shprintf( "alias: -r flag can only be used with -t and without arguments\n"); return 1; } ksh_getopt_reset(&builtin_opt, GF_ERROR); return c_unalias((char **) args); } if (*wp == NULL) { struct tbl *ap, **p; for (p = tsort(t); (ap = *p++) != NULL; ) if ((ap->flag & (ISSET|xflag)) == (ISSET|xflag)) { if (pflag) shf_puts("alias ", shl_stdout); shf_puts(ap->name, shl_stdout); if (prefix != '+') { shf_putc('=', shl_stdout); print_value_quoted(ap->val.s); } shprintf(newline); } } for (; *wp != NULL; wp++) { char *alias = *wp; char *val = strchr(alias, '='); char *newval; struct tbl *ap; int h; if (val) alias = str_nsave(alias, val++ - alias, ATEMP); h = hash(alias); if (val == NULL && !tflag && !xflag) { ap = tsearch(t, alias, h); if (ap != NULL && (ap->flag&ISSET)) { if (pflag) shf_puts("alias ", shl_stdout); shf_puts(ap->name, shl_stdout); if (prefix != '+') { shf_putc('=', shl_stdout); print_value_quoted(ap->val.s); } shprintf(newline); } else { shprintf("%s alias not found\n", alias); rv = 1; } continue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -