Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!ames!lll-winken!uunet!mcvax!kth!draken!tut!tukki!tarvaine From: tarvaine@tukki.jyu.fi (Tapani Tarvainen) Newsgroups: gnu.utils.bug Subject: Re: bug in Gnu e?grep / regex.c Summary: ptr - ptr != int Message-ID: <924@tukki.jyu.fi> Date: 18 Jun 89 10:36:07 GMT References: <920@tukki.jyu.fi> Reply-To: tarvaine@tukki.jyu.fi (Tapani Tarvainen) Distribution: gnu Organization: University of Jyvaskyla, Finland Lines: 56 Keywords: In article <920@tukki.jyu.fi> I wrote about problems in porting Gnu e?grep to MS-DOS. It turned out I hadn't found them all: It still failed with certain regexps. It didn't crash, just gave wrong results, making the bug much harder to track down. At this point it fortunately occurred me that using large data model wasn't really necessary after all - the "Memory exhausted" problem with small model was only the result of the erroneous test described in my previous posting. And indeed, after compiling with small model I got perfect results every time. So I could hunt the bug in large data model by tracing the versions side by side. The problem was in regex.c, which presumably has been written when compilers that violate its assumptions were but a dream in some ANSI-committee-member-to-be's mind. Actually, there were two related problems: One, the code assumes that the result of subtracting pointers is an int. According to pANS as well as TurboC, it is ptrdiff_t -- and in large data models the latter defines it as long. Two, occasionally 0 (zero) is passed as a pointer argument without cast, which I think is valid only when ints and pointers are of the same size and the representation of null pointer is (int)0. (If NULL had been used, it would've worked with Turbo C as it defines NULL as 0L in large data models, but that is something of a kludge, and might fail with some other compiler.) Both had the effect of passing 4-byte values to functions expecting 2-byte ones, with predictable results. To fix these I changed most ints in regex.c and a few in grep.c into ptrdiff_t and added casts where necessary (and probably some that strictly aren't), including ptrdiff_t type constants. To maintain compatibility with pre-ANSI compilers I added #ifndef __STDC__ typedef int ptrdiff_t; #endif It is perhaps worth noting that with ANSI-style prototypes these problems would not have occurred in the first place. I _think_ there are no more bugs left, but I'll experiment a little yet to make sure. By the way, what is the recommended place for sending ports of Gnu stuff like this - I mean if there are no bugs (for which this group is for), only things like different #include's or makefile? Where should I send the diffs for this & TC makefile once I'm satisfied with the thing? -- Tapani Tarvainen BitNet: tarvainen@finjyu Internet: tarvainen@jylk.jyu.fi -- OR -- tarvaine@tukki.jyu.fi