[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Problem with assign() in src/lua/lua.c
- From: Terry Moore <tmm@...>
- Date: Mon, 03 Jun 2002 11:36:24 -0400
Hi all,
We are upgrading from Lua 3.2 to Lua 4.0, and I noticed the following
problem, for which I have a proposed solution.
The lua command driver (src/lua/lua.c) handles variable assignments as part
of option parsing. Unfortunately, it does this in way that clobbers the
option value (as observed by getargs()).
Here's the original code:
static void assign (char *arg) {
char *eq = strchr(arg, '=');
*eq = '\0'; /* spilt `arg' in two strings (name & value) */
lua_pushstring(L, eq+1);
lua_setglobal(L, arg);
}
The problem is at the split. It clobbers the argv[] value.
To see this, try:
lua FOO=baz -i
> print(getargs()[1])
FOO
I argue that this should print
FOO=baz
It is not difficult to fix this, at the cost of a little code. While I was
at it, I changed this to reject:
lua =baz
which I think is not really a meaningful thing to do, but which is
presently taken as an assignment to the global variable named "". Also,
since we have a local option -D (as in lua -D foo or lua -D foo=baz), I
changed the assign() subroutine to accept an argument with no '=' at all.
The resulting routine is, alas, somewhat longer.
static int assign (const char *arg) { /* comment 1 */
const char *eq;
size_t lenvar;
eq = strchr(arg, '='); /* comment 3 */
if (eq == NULL) { /* comment 2 */
/* no equal sign? define as "" */
eq = "";
lenvar = strlen(arg);
} else if (eq == arg) { /* comment 3 */
fprintf(stderr, "lua: can't define \"{nothing}={val}\"\n");
return (EXIT_FAILURE);
} else {
lenvar = eq - arg;
++eq;
}
/* ok, set the value without clobbering args */
lua_getglobals(L); /* reference the global table */
lua_pushlstring(L, arg, lenvar); /* push the key */
lua_pushstring(L, eq); /* push the value */
lua_settable(L, -3); /* set globals["x"]="value" */
lua_pop(L, 1); /* ditch the globals ref */
return EXIT_SUCCESS;
}
Comments:
1) changed type of arg to const char *.
2) local style is to only assign during a declaration if the variable's
value is immutable. [i.e., const char * const eq = ... would be ok]. But
since eq is changed (see comment 3), I broke up the declaration.
3) this catches the case where there's no '=' in the input.
4) this catches the case where there's no variable to the left of the '='.
--Terry
tmm@mcci.com tel: +1-607-277-1029 fax: +1-607-277-6844 www.mcci.com