greim@sbsvax.UUCP (Michael Greim) (09/12/89)
Here's a bug report for perl3 and a fix for the bug. This is only ment as an unofficial "quick fix". I sent this report to Larry Wall too, who will probably include a bug fix of his own in one of his next suit of patches. A Bug in perl3. Priority : medium Symptoms: perl failed the test in base.term. The test $x = "\n"; if ($x lt ' ') {print "ok 1\n";} else {print "not ok 1\n";} said "not ok 1". With the debug flag turned on, one sees that the result of the comparison "$s lt ' '" yields false. Diagnosis: In several places bcmp is used. At least in one place, viz. the evaluation of the result of the O_SLT operator, the code relies on bcmp to return a value - less 0 if str1 < str2 - 0 if str1 == str2 - greater 0 if str1 > str2 To cite the 4BSD manual page: bcmp(b1, b2, length) char *b1, *b2; int length; ``bcmp compares sbyte string b1 against byte string b2, returning zero if they are identical, nonzero otherwise. Both strings are assumed to be length bytes long.'' The code for O_SLT operator in eval.c: case O_SLT: tmps = str_get(st[1]); value = (double) (str_cmp(st[1],st[2]) < 0); goto donumset; In routine str_cmp in str.c: if (str1->str_cur < str2->str_cur) { --> if (retval = bcmp(str1->str_ptr, str2->str_ptr, str1->str_cur)) return retval; else return 1; } --> else if (retval = bcmp(str1->str_ptr, str2->str_ptr, str2->str_cur)) return retval; else if (str1->str_cur == str2->str_cur) return 0; else return -1; The return of bcmp is returned as the result of str_cmp and tested if it is less than 0. Unfortunately according to the man page it is not guaranteed that the result of bcmp will be less than 0 . Therapy: The best would be to examine the code for occurances of bcmp and rewrite it as necessary. A quick fix is to include a "handmade" bcmp. Here it is: ------ cut here ---------- bcmp (s1, s2, n) register unsigned char * s1; register unsigned char * s2; register int n; /* * If bcmp returns always a number > 0 if s1 is not identical to s2 one * has to include this bcmp. * * Here is one which returns a number < 0 if s1 < s2 and a number > 0 if * s1 > s2. * ("unsigned char" to get subtraction correct) */ { while (n--) { if (*s1 != *s2) return ((int)(*s1 - *s2)); s1++; s2++; } return (0); } ------ cut here ---------- Absorb, apply and enjoy, -mg -- Michael Greim Email : greim@sbsvax.informatik.uni-saarland.dbp.de or : ...!uunet!unido!sbsvax!greim [.signature removed by the board of censors for electronic mail's main executive computer because it contained a four letter word ("word")]