bbadger@x102c.harris-atd.com (Badger BA 64810) (04/05/89)
Variable expansion in csh isn't done properly. The problem is shown by this example: % set verbose set verbose set verbose % set x1=(a b c) set x1= ( a b c ) % echo ${x1[2]} echo 1${x[2]} Variable syntax. % Here's a more complete transcript, showing that a variable name with no digits in it works correctly: % set echo % set verbose set verbose % set xx=(a b c) set xx= ( a b c ) set xx= ( a b c ) % set x1=(d e f) set x1= ( d e f ) set x1= ( d e f ) % alias x 'echo ${x\!:1[2]}' alias x 'echo ${x!:1[2]}' alias x echo ${x!:1[2]} % alias x_ 'echo $x\!:1[2]' alias x_ 'echo $x!:1[2]' alias x_ echo $x!:1[2] % echo ${xx[2]} echo ${xx[2]} echo b b % x x x x echo b b % echo $xx[2] echo $xx[2] echo b b % x_ x x_ x echo b b % echo $x1[2] echo $x1[2] echo e e % x_ 1 x_ 1 echo e e % echo ${x1[2]} echo 1${x[2]} Variable syntax. % !! echo 1${x[2]} x: Undefined variable. % x 1 x 1 Variable syntax. % !! x 1 Variable syntax. % The work-around seems to be to not use {}'s. Bernard A. Badger Jr. 407/984-6385 |``Use the Source, Luke!'' Secure Computer Products |``Get a LIFE!'' -- J.H. Conway Harris GISD, Melbourne, FL 32902 |Buddy, can you paradigm? Internet: bbadger%x102c@trantor.harris-atd.com|'s/./&&/g' Tom sed expansively.
chris@mimsy.UUCP (Chris Torek) (04/06/89)
Date: Wed, 13 Jan 88 20:36:53 EST From: Chris Torek <chris@gyre.umd.edu> To: 4bsd-bugs@ucbvax.Berkeley.EDU Subject: csh mislexes $var1iables Index: bin/csh/sh.lex.c 4.3BSD Fix Reference: 4.3BSD/bin/114 Description: The C shell's `lexical analyser' (if you can call it that) thinks that variables are either all digits or all numbers. As far as it is concerned, $a1bc is the variable $a followed by the string `1bc'. Everyone is happy: the lexer sees a properly-formed variable ($a) plus a string, and later, the variable evaluator looks up $a1bc. If, however, one writes instead ${a1bc}, the lexer is not happy. It sees a variable (${a) that is not proper: the closing brace `}' is missing. It complains about variable syntax (an ambiguous error, but here the real meaning is not the intended one!), and the evaluator never gets a chance. Repeat-by: % set a1=ok % echo ${a1} Variable syntax. % man csh (read section on shell variable syntax) Fix: It seems to work. The code is all twisty and devious, so maybe it will break something. I doubt it. Chris *** sh.lex.c.old Wed Jan 13 20:22:06 1988 --- sh.lex.c Wed Jan 13 20:22:10 1988 *************** *** 373,377 **** } } else if (letter(c)) ! while (letter(c = getC(DOEXCL))) { if (np < &name[sizeof name / 2]) *np++ = c; --- 373,377 ---- } } else if (letter(c)) ! while (letter(c = getC(DOEXCL)) || digit(c)) { if (np < &name[sizeof name / 2]) *np++ = c; -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
greim@sbsvax.UUCP (Michael Greim) (04/10/89)
In article <1893@trantor.harris-atd.com>, bbadger@x102c.harris-atd.com (Badger BA 64810) writes: > Variable expansion in csh isn't done properly. [...] You can fix this bug if you have source. I have published a fix on 12. January 1988. I was relatively new to the net, so I did not obey some conventions. This fix is part of a set of fixes. One of the projects I have waiting on my schedule is to bundle all the fixes, create diffs for the tahoe csh (which has the same bugs, mostly) and publish all this in the appropriate news group. I always wondered who applied my fixes. = From greim@sbsvax.UUCP Tue Jan 12 19:24:28 1988 = Path: sbsvax!greim = From: greim@sbsvax.UUCP (Michael Greim) = Newsgroups: comp.unix.wizards = Subject: Re: csh oddity = Summary: fix = Keywords: csh variables substitution = Message-ID: <373@sbsvax.UUCP> = Date: 12 Jan 88 18:24:28 GMT = References: <826@murphy.UUCP> = Organization: Universitaet des Saarlandes, D-6600 Saarbruecken, FRG = Lines: 87 = = This is in answer to an article by = Dave Cornutt, Gould Computer Systems, Ft. Lauderdale, FL = = He writes about a bug in csh. = Doing = set a1b=abc = set b=${a1b} = will provoke an error message "Variable syntax.", and in the = history the last command will be entered as "set b=1${ab}". = = This is really a bug, but it is relativly easy to find and to fix. = I know some which are very difficult to fix. = = Diagnosis: = Look in sh.lex.c, somewhere around line 390 in the routine getdol = there should be the following code (this here quoted from 4.3 BSD): = = case '*': = if (special) = goto vsyn; = goto ret; = = default: = if (digit(c)) { = /* = * let $?0 pass for now = if (special) = goto vsyn; = */ = while (digit(c = getC(DOEXCL))) { = if (np < &name[sizeof name / 2]) = *np++ = c; = } = } else if (letter(c)) = while (letter(c = getC(DOEXCL))) { = if (np < &name[sizeof name / 2]) = *np++ = c; = } = else = goto vsyn; = } = = This code causes the bug. After a $ is encountered the routine looks = if a number follows, it was '$1' or something like this, if not, = it wants to check whether the variable name is correct, but it = only tests if all characters a letters. Variable Names can contain = numberes too. = = Therapy: = change to = = case '*': = if (special) = goto vsyn; = goto ret; = = default: = if (digit(c)) { = /* = * let $?0 pass for now = if (special) = goto vsyn; = */ = while (digit(c = getC(DOEXCL))) { = if (np < &name[sizeof name / 2]) = *np++ = c; = } = } else if (alnum(c)) = while (alnum(c = getC(DOEXCL))) { = if (np < &name[sizeof name / 2]) = *np++ = c; = } = else = goto vsyn; = } = = [...] = From greim@sbsvax.UUCP Mon Jan 18 17:12:59 1988 = Path: sbsvax!greim = From: greim@sbsvax.UUCP (Michael Greim) = Newsgroups: comp.unix.wizards,comp.bugs.4bsd = Subject: Re: csh oddity, fix = Keywords: csh variables substitution fix = Message-ID: <374@sbsvax.UUCP> = Date: 18 Jan 88 16:12:59 GMT = Organization: Universitaet des Saarlandes, D-6600 Saarbruecken, FRG = Lines: 95 = = In article <826@murphy.UUCP> dcornutt@murphy.UUCP (Dave Cornutt) writes: = > I have discovered something peculiar about csh variable substitution. Is = > this a bug or am I doing something wrong? = = Sorry folks, = The fix I sent on 12. Jan. is not complete. It does not cover every = instance of the bug. = Like Chris Torek says in <10167@mimsy.UUCP> it is idiocy = for two routines to handle the same job. But it comes even better : = the test, whether a variable name is valid, is done differently in = several parts of csh. = = Try the following commands, and note the faulty behaviour = set xy1z=mist = 1.) echo ${xy1z} in sh.lex.c = 2.) set 1a in sh.set.c = 3.) foreach a1b ... in sh.func.c = = If I have overlooked a bug instance, tell me. (But apply the fixes first: = they will kill some bugs :-) = = I do not give any context diff's, because my sourcecode is cluttered = with ifdef's, so the output might be too confusing. And I am too lazy = to revert to the original code in SCCS :^o = = The first situation is covered by my fix from 12.Jan, which applied to = the piece of code Chris Torek (<10167@mimsy.UUCP>) and Craig Hansen = (<1326@mips.UUCP>) suspected. [...] = = + means new line = - means deleted line = ! means changed line = = Fix2: = in sh.set.c, routine doset, about line 30 = ... = do { = hadsub = 0; = + if (!letter (*p)) = + goto setsyn; = for (vp = p; alnum(*p); p++) = continue; = if (vp == p) = goto setsyn; = ... = = Fix3: = in sh.func.c, routine doforeach, about line 356 = ... = cp = strip(*v); = + if (! letter (*cp)) = + bferr("Variable syntax"); = ! while (*cp && alnum(*cp)) = cp++; = if (*cp || strlen(*v) >= 20) = bferr("Invalid variable"); = ... = [...] Absorb, apply and enjoy, -mg email : greim@sbsvax.informatik.uni-saarland.dbp.de (some mailers might not like this. Then use greim@sbsvax.uucp) or : ...!uunet!unido!sbsvax!greim # include <disclaimers/std.h> -- email : greim@sbsvax.informatik.uni-saarland.dbp.de (some mailers might not like this. Then use greim@sbsvax.uucp) or : ...!uunet!unido!sbsvax!greim # include <disclaimers/std.h>