[comp.bugs.4bsd] csh oddity, fix

greim@sbsvax.UUCP (Michael Greim) (01/19/88)

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.
By the way : Craig, you are wrong, alnum() is not a macro but a routine
of csh, to be found in sh.misc.c. It tests whether its parameter is
a letter, a number or an underscore. The macro is isalnum().

letter() tests for letter or underscore.

+ 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");
	...

Please note, that the check for the length of a variable differs too:
('mist' is German, meaning 'garbage' or 'manure' :^} )
a.) you can set variables with names longer than 20, like
	set abcdefghijklmnopqrstuvwxyz=mist
b.) you can not use a variable with 20 character name
	set abcdefghijklmnopqrst=mist2
	echo $abcdefghijklmnopqrst
    you can only use up to 18 characters this way
c.) you can use a variable with 19 characters if writing
	set a234567890123456789=mist03
	echo ${a234567890123456789}
This is of course because the tests for length differ in the divers
places.
I will send a fix for this when I have the time.

By the way: I don't think it should be an error if you do 'setenv 1a mist',
because there may be some weird programs that might desire such an
environment variable (suggested by Paul Keller). But if you do this
sh will refuse to start because 1a is an illegal variable name for it.

	-- Michael

+------------------------------------------------------------------------------+
| UUCP:  ...!uunet!unido!sbsvax!greim   | Michael T. Greim                     |
|        or greim@sbsvax.UUCP           | Universitaet des Saarlandes          |
| CSNET: greim%sbsvax.uucp@Germany.CSnet| FB 10 - Informatik (Dept. of CS)     |
| ARPA:  greim%sbsvax.uucp@uunet.UU.NET | Bau 36, Im Stadtwald 15              |
| Phone: +49 681 302 2434               | D-6600 Saarbruecken 11, West Germany |
+------------------------------------------------------------------------------+
| "And as the sun pulls away from the shore and our boat sinks slowly in the   |
| west ..." Spike Jones                                                        |
+------------------------------------------------------------------------------+