diff --git a/check.t b/check.t index 998233a..9f62975 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.461 2011/06/05 16:49:54 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.462 2011/06/05 19:58:16 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -25,7 +25,7 @@ # http://www.research.att.com/~gsf/public/ifs.sh expected-stdout: - @(#)MIRBSD KSH R40 2011/06/04 + @(#)MIRBSD KSH R40 2011/06/05 description: Check version of shell. stdin: diff --git a/main.c b/main.c index aff30b2..e1ccd55 100644 --- a/main.c +++ b/main.c @@ -33,7 +33,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.192 2011/06/04 16:42:30 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.193 2011/06/05 19:58:18 tg Exp $"); extern char **environ; @@ -206,8 +206,9 @@ main(int argc, const char *argv[]) ccp = empty_argv[0]; /* define built-in commands and see if we were called as one */ - ktinit(&builtins, APERM, - /* must be 80% of 2^n (currently 44 builtins) */ 64); + ktinit(APERM, &builtins, + /* currently 50 builtins -> 80% of 64 (2^6) */ + 6); for (i = 0; mkshbuiltins[i].name != NULL; i++) if (!strcmp(ccp, builtin(mkshbuiltins[i].name, mkshbuiltins[i].func))) @@ -235,10 +236,10 @@ main(int argc, const char *argv[]) coproc_init(); /* set up variable and command dictionaries */ - ktinit(&taliases, APERM, 0); - ktinit(&aliases, APERM, 0); + ktinit(APERM, &taliases, 0); + ktinit(APERM, &aliases, 0); #ifndef MKSH_NOPWNAM - ktinit(&homedirs, APERM, 0); + ktinit(APERM, &homedirs, 0); #endif /* define shell keywords */ @@ -1442,53 +1443,48 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist) * but with a slightly tweaked implementation written from scratch. */ -#define INIT_TBLS 8 /* initial table size (power of 2) */ +#define INIT_TBLSHIFT 3 /* initial table shift (2^3 = 8) */ #define PERTURB_SHIFT 5 /* see Python 2.5.4 Objects/dictobject.c */ -static void texpand(struct table *, size_t); +static void tgrow(struct table *); static int tnamecmp(const void *, const void *); -static struct tbl *ktscan(struct table *, const char *, uint32_t, - struct tbl ***); static void -texpand(struct table *tp, size_t nsize) +tgrow(struct table *tp) { - size_t i, j, osize = tp->size, perturb; + size_t i, j, osize, mask, perturb; struct tbl *tblp, **pp; struct tbl **ntblp, **otblp = tp->tbls; - i = 1; - i <<= 30; - if (nsize > i) + if (tp->tshift > 29) internal_errorf("hash table size limit reached"); - ntblp = alloc2(nsize, sizeof(struct tbl *), tp->areap); - memset(ntblp, 0, nsize * sizeof(struct tbl *)); - tp->size = nsize; - if (nsize == i) { - /* cannot be grown any more, use a fixed value */ - tp->nfree = i - 65536; - } else /* (nsize < 2^30) */ { - /* table can get 80% full */ - tp->nfree = (nsize * 4) / 5; - } + /* calculate old size, new shift and new size */ + osize = 1 << (tp->tshift++); + i = osize << 1; + + ntblp = alloc2(i, sizeof(struct tbl *), tp->areap); + /* multiplication cannot overflow: alloc2 checked that */ + memset(ntblp, 0, i * sizeof(struct tbl *)); + + /* table can get 80% full except when reaching its limit */ + tp->nfree = (tp->tshift == 30) ? 0x3FFF0000UL : ((i * 4) / 5); tp->tbls = ntblp; if (otblp == NULL) return; - /* from here on nsize := mask */ - nsize--; + mask = i - 1; for (i = 0; i < osize; i++) if ((tblp = otblp[i]) != NULL) { if ((tblp->flag & DEFINED)) { /* search for free hash table slot */ - j = (perturb = tblp->ua.hval) & nsize; + j = (perturb = tblp->ua.hval) & mask; goto find_first_empty_slot; find_next_empty_slot: j = (j << 2) + j + perturb + 1; perturb >>= PERTURB_SHIFT; find_first_empty_slot: - pp = &ntblp[j & nsize]; + pp = &ntblp[j & mask]; if (*pp != NULL) goto find_next_empty_slot; /* found an empty hash table slot */ @@ -1502,23 +1498,23 @@ texpand(struct table *tp, size_t nsize) } void -ktinit(struct table *tp, Area *ap, size_t tsize) +ktinit(Area *ap, struct table *tp, uint8_t initshift) { tp->areap = ap; tp->tbls = NULL; - tp->size = tp->nfree = 0; - if (tsize) - texpand(tp, tsize); + tp->tshift = ((initshift > INIT_TBLSHIFT) ? + initshift : INIT_TBLSHIFT) - 1; + tgrow(tp); } /* table, name (key) to search for, hash(name), rv pointer to tbl ptr */ -static struct tbl * +struct tbl * ktscan(struct table *tp, const char *name, uint32_t h, struct tbl ***ppp) { size_t j, perturb, mask; struct tbl **pp, *p; - mask = tp->size - 1; + mask = (1 << (tp->tshift)) - 1; /* search for hash table slot matching name */ j = (perturb = h) & mask; goto find_first_slot; @@ -1536,13 +1532,6 @@ ktscan(struct table *tp, const char *name, uint32_t h, struct tbl ***ppp) return (p); } -/* table, name (key) to search for, hash(n) */ -struct tbl * -ktsearch(struct table *tp, const char *n, uint32_t h) -{ - return (tp->size ? ktscan(tp, n, h, NULL) : NULL); -} - /* table, name (key) to enter, hash(n) */ struct tbl * ktenter(struct table *tp, const char *n, uint32_t h) @@ -1550,15 +1539,13 @@ ktenter(struct table *tp, const char *n, uint32_t h) struct tbl **pp, *p; size_t len; - if (tp->size == 0) - texpand(tp, INIT_TBLS); Search: if ((p = ktscan(tp, n, h, &pp))) return (p); if (tp->nfree == 0) { /* too full */ - texpand(tp, 2 * tp->size); + tgrow(tp); goto Search; } @@ -1583,7 +1570,7 @@ ktenter(struct table *tp, const char *n, uint32_t h) void ktwalk(struct tstate *ts, struct table *tp) { - ts->left = tp->size; + ts->left = 1 << (tp->tshift); ts->next = tp->tbls; } @@ -1613,16 +1600,19 @@ ktsort(struct table *tp) size_t i; struct tbl **p, **sp, **dp; - /* tp->size + 1 will not overflow */ - p = alloc2(tp->size + 1, sizeof(struct tbl *), ATEMP); + /* + * since the table is never entirely full, no need to reserve + * additional space for the trailing NULL appended below + */ + i = 1 << (tp->tshift); + p = alloc2(i, sizeof(struct tbl *), ATEMP); sp = tp->tbls; /* source */ dp = p; /* dest */ - i = (size_t)tp->size; while (i--) if ((*dp = *sp++) != NULL && (((*dp)->flag & DEFINED) || ((*dp)->flag & ARRAY))) dp++; - qsort(p, (i = dp - p), sizeof(void *), tnamecmp); + qsort(p, (i = dp - p), sizeof(struct tbl *), tnamecmp); p[i] = NULL; return (p); } diff --git a/sh.h b/sh.h index 7467840..fd87086 100644 --- a/sh.h +++ b/sh.h @@ -151,9 +151,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.473 2011/06/04 16:42:31 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.474 2011/06/05 19:58:19 tg Exp $"); #endif -#define MKSH_VERSION "R40 2011/06/04" +#define MKSH_VERSION "R40 2011/06/05" #ifndef MKSH_INCLUDES_ONLY @@ -935,8 +935,8 @@ extern struct shf shf_iob[]; struct table { Area *areap; /* area to allocate entries */ struct tbl **tbls; /* hashed table items */ - uint32_t size; /* table size (always 2^n) */ uint32_t nfree; /* free table entries */ + uint8_t tshift; /* table size (2^tshift) */ }; struct tbl { /* table item */ @@ -1682,8 +1682,10 @@ void coproc_write_close(int); int coproc_getfd(int, const char **); void coproc_cleanup(int); struct temp *maketemp(Area *, Temp_type, struct temp **); -void ktinit(struct table *, Area *, size_t); -struct tbl *ktsearch(struct table *, const char *, uint32_t); +void ktinit(Area *, struct table *, uint8_t); +struct tbl *ktscan(struct table *, const char *, uint32_t, struct tbl ***); +/* table, name (key) to search for, hash(n) */ +#define ktsearch(tp, s, h) ktscan((tp), (s), (h), NULL) struct tbl *ktenter(struct table *, const char *, uint32_t); #define ktdelete(p) do { p->flag = 0; } while (/* CONSTCOND */ 0) void ktwalk(struct tstate *, struct table *); @@ -1783,8 +1785,8 @@ struct tbl *typeset(const char *, Tflag, Tflag, int, int) MKSH_A_NONNULL((__nonnull__ (1))); void unset(struct tbl *, int); const char *skip_varname(const char *, int); -const char *skip_wdvarname(const char *, int); -int is_wdvarname(const char *, int); +const char *skip_wdvarname(const char *, bool); +int is_wdvarname(const char *, bool); int is_wdvarassign(const char *); struct tbl *arraysearch(struct tbl *, uint32_t); char **makenv(void); diff --git a/syn.c b/syn.c index 06796f2..8ace2ce 100644 --- a/syn.c +++ b/syn.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.66 2011/06/04 16:11:20 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.67 2011/06/05 19:58:20 tg Exp $"); extern short subshell_nesting_level; @@ -794,9 +794,9 @@ initkeywords(void) struct tokeninfo const *tt; struct tbl *p; - ktinit(&keywords, APERM, - /* must be 80% of 2^n (currently 28 keywords) */ - 64); + ktinit(APERM, &keywords, + /* currently 28 keywords -> 80% of 64 (2^6) */ + 6); for (tt = tokentab; tt->name; tt++) { if (tt->reserved) { p = ktenter(&keywords, tt->name, hash(tt->name)); diff --git a/var.c b/var.c index 8b79c6d..46aaf8d 100644 --- a/var.c +++ b/var.c @@ -26,9 +26,9 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.122 2011/05/29 02:18:57 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.123 2011/06/05 19:58:20 tg Exp $"); -/* +/*- * Variables * * WARNING: unreadable code, needs a rewrite @@ -37,6 +37,7 @@ __RCSID("$MirOS: src/bin/mksh/var.c,v 1.122 2011/05/29 02:18:57 tg Exp $"); * otherwise, (val.s + type) contains string value. * if (flag&EXPORT), val.s contains "name=value" for E-Z exporting. */ + static struct tbl vtemp; static struct table specials; static uint32_t lcg_state = 5381; @@ -66,7 +67,8 @@ newblock(void) l = alloc(sizeof(struct block), ATEMP); l->flags = 0; - ainit(&l->area); /* todo: could use e->area (l->area => l->areap) */ + /* TODO: could use e->area (l->area => l->areap) */ + ainit(&l->area); if (!e->loc) { l->argc = 0; l->argv = empty; @@ -75,8 +77,8 @@ newblock(void) l->argv = e->loc->argv; } l->exit = l->error = NULL; - ktinit(&l->vars, &l->area, 0); - ktinit(&l->funs, &l->area, 0); + ktinit(&l->area, &l->vars, 0); + ktinit(&l->area, &l->funs, 0); l->next = e->loc; e->loc = l; } @@ -87,12 +89,15 @@ newblock(void) void popblock(void) { + ssize_t i; struct block *l = e->loc; struct tbl *vp, **vpp = l->vars.tbls, *vq; - int i; - e->loc = l->next; /* pop block */ - for (i = l->vars.size; --i >= 0; ) + /* pop block */ + e->loc = l->next; + + i = 1 << (l->vars.tshift); + while (--i >= 0) if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL)) { if ((vq = global(vp->name))->flag & ISSET) setspec(vq); @@ -115,6 +120,7 @@ enum var_specs { V_MAX }; +/* this is biased with -1 relative to VARSPEC_ENUMS */ static const char * const initvar_names[] = { #define VARSPEC_ITEMS #include "var_spec.h" @@ -126,8 +132,9 @@ initvar(void) int i = 0; struct tbl *tp; - ktinit(&specials, APERM, - /* must be 80% of 2^n (currently 12 specials) */ 16); + ktinit(APERM, &specials, + /* currently 12 specials -> 80% of 16 (2^4) */ + 4); while (i < V_MAX - 1) { tp = ktenter(&specials, initvar_names[i], hash(initvar_names[i])); @@ -136,8 +143,9 @@ initvar(void) } } -/* Used to calculate an array index for global()/local(). Sets *arrayp to - * true if this is an array, sets *valp to the array index, returns +/* + * Used to calculate an array index for global()/local(). Sets *arrayp + * to true if this is an array, sets *valp to the array index, returns * the basename of the array. */ static const char * @@ -179,7 +187,7 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp) char *sub, *tmp; mksh_ari_t rval; - /* Calculate the value of the subscript */ + /* calculate the value of the subscript */ *arrayp = true; strndupx(tmp, p + 1, len - 2, ATEMP); sub = substitute(tmp, 0); @@ -234,7 +242,7 @@ global(const char *n) vp->val.i = kshpid; break; case '!': - /* If no job, expand to nothing */ + /* if no job, expand to nothing */ if ((vp->val.i = j_async()) == 0) vp->flag &= ~(ISSET|INTEGER); break; @@ -284,7 +292,7 @@ local(const char *n, bool copy) bool array; uint32_t h, val; - /* Check to see if this is an array */ + /* check to see if this is an array */ n = array_index_calc(n, &array, &val); h = hash(n); if (!ksh_isalphx(*n)) { @@ -327,18 +335,23 @@ str_val(struct tbl *vp) if ((vp->flag&SPECIAL)) getspec(vp); if (!(vp->flag&ISSET)) - s = null; /* special to dollar() */ - else if (!(vp->flag&INTEGER)) /* string source */ + /* special to dollar() */ + s = null; + else if (!(vp->flag&INTEGER)) + /* string source */ s = vp->val.s + vp->type; - else { /* integer source */ - /* worst case number length is when base=2 */ - /* 1 (minus) + 2 (base, up to 36) + 1 ('#') + number of bits - * in the mksh_uari_t + 1 (NUL) */ + else { + /* integer source */ + mksh_uari_t n; + int base; + /** + * worst case number length is when base == 2: + * 1 (minus) + 2 (base, up to 36) + 1 ('#') + + * number of bits in the mksh_uari_t + 1 (NUL) + */ char strbuf[1 + 2 + 1 + 8 * sizeof(mksh_uari_t) + 1]; const char *digits = (vp->flag & UCASEV_AL) ? digits_uc : digits_lc; - mksh_uari_t n; - int base; s = strbuf + sizeof(strbuf); if (vp->flag & INT_U) @@ -375,7 +388,8 @@ str_val(struct tbl *vp) if (!(vp->flag & INT_U) && vp->val.i < 0) *--s = '-'; } - if (vp->flag & (RJUST|LJUST)) /* case already dealt with */ + if (vp->flag & (RJUST|LJUST)) + /* case already dealt with */ s = formatstr(vp, s); else strdupx(s, s, ATEMP); @@ -411,7 +425,8 @@ setstr(struct tbl *vq, const char *s, int error_ok) errorfxz(2); return (0); } - if (!(vq->flag&INTEGER)) { /* string dest */ + if (!(vq->flag&INTEGER)) { + /* string dest */ if ((vq->flag&ALLOC)) { /* debugging */ if (s >= vq->val.s && @@ -431,7 +446,8 @@ setstr(struct tbl *vq, const char *s, int error_ok) strdupx(vq->val.s, s, vq->areap); vq->flag |= ALLOC; } - } else { /* integer dest */ + } else { + /* integer dest */ if (!v_evaluate(vq, s, error_ok, true)) return (0); } @@ -539,7 +555,8 @@ getint(struct tbl *vp, mksh_ari_t *nump, bool arith) return (base); } -/* convert variable vq to integer variable, setting its value from vp +/* + * convert variable vq to integer variable, setting its value from vp * (vq and vp may be the same) */ struct tbl * @@ -575,7 +592,8 @@ formatstr(struct tbl *vp, const char *s) olen = utf_mbswidth(s); if (vp->flag & (RJUST|LJUST)) { - if (!vp->u2.field) /* default field width */ + if (!vp->u2.field) + /* default field width */ vp->u2.field = olen; nlen = vp->u2.field; } else @@ -660,16 +678,17 @@ exportprep(struct tbl *vp, const char *val) memcpy(vp->val.s = xp, vp->name, namelen); xp += namelen; *xp++ = '='; - vp->type = xp - vp->val.s; /* offset to value */ + /* offset to value */ + vp->type = xp - vp->val.s; memcpy(xp, val, vallen); if (op != NULL) afree(op, vp->areap); } /* - * lookup variable (according to (set&LOCAL)), - * set its attributes (INTEGER, RDONLY, EXPORT, TRACE, LJUST, RJUST, ZEROFIL, - * LCASEV, UCASEV_AL), and optionally set its value if an assignment. + * lookup variable (according to (set&LOCAL)), set its attributes + * (INTEGER, RDONLY, EXPORT, TRACE, LJUST, RJUST, ZEROFIL, LCASEV, + * UCASEV_AL), and optionally set its value if an assignment. */ struct tbl * typeset(const char *var, Tflag set, Tflag clr, int field, int base) @@ -694,11 +713,12 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base) len = array_ref_len(val); if (len == 0) return (NULL); - /* IMPORT is only used when the shell starts up and is + /* + * IMPORT is only used when the shell starts up and is * setting up its environment. Allow only simple array - * references at this time since parameter/command substitution - * is preformed on the [expression] which would be a major - * security hole. + * references at this time since parameter/command + * substitution is preformed on the [expression] which + * would be a major security hole. */ if (set & IMPORT) { int i; @@ -715,7 +735,7 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base) vappend = true; } } else { - /* Importing from original environment: must have an = */ + /* importing from original environment: must have an = */ if (set & IMPORT) return (NULL); strdupx(tvar, var, ATEMP); @@ -727,7 +747,7 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base) tvar[len-3] = '\0'; } - /* Prevent typeset from creating a local PATH/ENV/SHELL */ + /* prevent typeset from creating a local PATH/ENV/SHELL */ if (Flag(FRESTRICTED) && (strcmp(tvar, "PATH") == 0 || strcmp(tvar, "ENV") == 0 || strcmp(tvar, "SHELL") == 0)) errorf("%s: %s", tvar, "restricted"); @@ -740,7 +760,7 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base) if (vp->flag & ARRAY) { struct tbl *a, *tmp; - /* Free up entire array */ + /* free up entire array */ for (a = vp->u.array; a; ) { tmp = a; a = a->u.array; @@ -773,8 +793,9 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base) if (set | clr) { bool ok = true; - /* XXX if x[0] isn't set, there will be problems: need to have - * one copy of attributes for arrays... + /* + * XXX if x[0] isn't set, there will be problems: need + * to have one copy of attributes for arrays... */ for (t = vpbase; t; t = t->u.array) { bool fake_assign; @@ -847,7 +868,7 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base) if (vp->flag&INTEGER) { /* do not zero base before assignment */ setstr(vp, val, KSH_UNWIND_ERROR | 0x4); - /* Done after assignment to override default */ + /* done after assignment to override default */ if (base > 0) vp->type = base; } else @@ -879,7 +900,7 @@ unset(struct tbl *vp, int flags) if ((vp->flag & ARRAY) && (flags & 1)) { struct tbl *a, *tmp; - /* Free up entire array */ + /* free up entire array */ for (a = vp->u.array; a; ) { tmp = a; a = a->u.array; @@ -893,15 +914,17 @@ unset(struct tbl *vp, int flags) vp->flag &= ~(ALLOC|ISSET); return; } - /* If foo[0] is being unset, the remainder of the array is kept... */ + /* if foo[0] is being unset, the remainder of the array is kept... */ vp->flag &= SPECIAL | ((flags & 1) ? 0 : ARRAY|DEFINED); if (vp->flag & SPECIAL) - unsetspec(vp); /* responsible for 'unspecial'ing var */ + /* responsible for 'unspecial'ing var */ + unsetspec(vp); } -/* return a pointer to the first char past a legal variable name (returns the - * argument if there is no legal name, returns a pointer to the terminating - * NUL if whole string is legal). +/* + * Return a pointer to the first char past a legal variable name + * (returns the argument if there is no legal name, returns a pointer to + * the terminating NUL if whole string is legal). */ const char * skip_varname(const char *s, int aok) @@ -920,7 +943,8 @@ skip_varname(const char *s, int aok) /* Return a pointer to the first character past any legal variable name */ const char * skip_wdvarname(const char *s, - int aok) /* skip array de-reference? */ + /* skip array de-reference? */ + bool aok) { if (s[0] == CHAR && ksh_isalphx(s[1])) { do { @@ -951,7 +975,7 @@ skip_wdvarname(const char *s, /* Check if coded string s is a variable name */ int -is_wdvarname(const char *s, int aok) +is_wdvarname(const char *s, bool aok) { const char *p = skip_wdvarname(s, aok); @@ -974,14 +998,16 @@ is_wdvarassign(const char *s) char ** makenv(void) { + ssize_t i; struct block *l; XPtrV denv; struct tbl *vp, **vpp; - int i; XPinit(denv, 64); - for (l = e->loc; l != NULL; l = l->next) - for (vpp = l->vars.tbls, i = l->vars.size; --i >= 0; ) + for (l = e->loc; l != NULL; l = l->next) { + vpp = l->vars.tbls; + i = 1 << (l->vars.tshift); + while (--i >= 0) if ((vp = *vpp++) != NULL && (vp->flag&(ISSET|EXPORT)) == (ISSET|EXPORT)) { struct block *l2; @@ -1004,6 +1030,7 @@ makenv(void) } XPput(denv, vp->val.s); } + } XPput(denv, NULL); return ((char **)XPclose(denv)); } @@ -1119,8 +1146,9 @@ setspec(struct tbl *vp) afree(tmpdir, APERM); tmpdir = NULL; } - /* Use tmpdir iff it is an absolute path, is writable and - * searchable and is a directory... + /* + * Use tmpdir iff it is an absolute path, is writable + * and searchable and is a directory... */ { struct stat statb; @@ -1223,7 +1251,8 @@ unsetspec(struct tbl *vp) case V_LINENO: case V_RANDOM: case V_SECONDS: - case V_TMOUT: /* AT&T ksh leaves previous value in place */ + case V_TMOUT: + /* AT&T ksh leaves previous value in place */ unspecial(vp->name); break; @@ -1248,7 +1277,7 @@ arraysearch(struct tbl *vp, uint32_t val) size_t len; vp->flag = (vp->flag | (ARRAY|DEFINED)) & ~ASSOC; - /* The table entry is always [0] */ + /* the table entry is always [0] */ if (val == 0) return (vp); prev = vp; @@ -1275,16 +1304,18 @@ arraysearch(struct tbl *vp, uint32_t val) news->u2.field = vp->u2.field; news->ua.index = val; - if (curr != news) { /* not reusing old array entry */ + if (curr != news) { + /* not reusing old array entry */ prev->u.array = news; news->u.array = curr; } return (news); } -/* Return the length of an array reference (eg, [1+2]) - cp is assumed - * to point to the open bracket. Returns 0 if there is no matching closing - * bracket. +/* + * Return the length of an array reference (eg, [1+2]) - cp is assumed + * to point to the open bracket. Returns 0 if there is no matching + * closing bracket. */ int array_ref_len(const char *cp) @@ -1352,7 +1383,7 @@ set_array(const char *var, bool reset, const char **vals) /* trash existing values and attributes */ unset(vp, 1); /* - * todo: would be nice for assignment to completely succeed or + * TODO: would be nice for assignment to completely succeed or * completely fail. Only really effects integer arrays: * evaluation of some of vals[] may fail... */ diff --git a/var_spec.h b/var_spec.h index 4035cc9..b3bef4b 100644 --- a/var_spec.h +++ b/var_spec.h @@ -1,5 +1,5 @@ #if defined(VARSPEC_DEFNS) -__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.1 2009/09/26 03:40:03 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.2 2011/06/05 19:58:21 tg Exp $"); #define FN(name) /* nothing */ #elif defined(VARSPEC_ENUMS) #define FN(name) V_##name, @@ -13,6 +13,8 @@ __RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.1 2009/09/26 03:40:03 tg Exp $"); #define F0 FN #endif +/* NOTE: F0 are skipped for the ITEMS array, only FN generate names */ + /* 0 is always V_NONE */ F0(NONE)