Re: yacc: malloc+copy -> strndup()
On Fri, Nov 03, 2017 at 09:29:16AM +0100, Otto Moerbeek wrote: > On Fri, Nov 03, 2017 at 04:22:43PM +0800, Michael W. Bombardieri wrote: > > > On Fri, Nov 03, 2017 at 04:03:44PM +0800, Michael W. Bombardieri wrote: > > > Hello, > > > > > > In yacc the dup_line() function malloc()'ed a buffer and copied > > > a line into it. The copied line includes \n. > > > Allocate-and-copy can be done by strndup() in one hit. > > > I ran this on i386 with awk/awkgram.y and rcs/date.y and didn't > > > see any difference in y.tab.c compared to the system's yacc. > > > > > > - Michael > > > > Forgot to mention. The assert() is triggered if '\0' is encountered before > > '\n'. > > Even if that is ok, a better error message could be printed instead of > > assert(). > > Yes, we are very reluctant to use assert()... what if somebody compiles > with NDEBUG? When I put '\0' in an input file it seems to trigger syntax_error() earlier on, so I decided to follow this. syntax_error() at least prints the input line number. Index: reader.c === RCS file: /cvs/src/usr.bin/yacc/reader.c,v retrieving revision 1.34 diff -u -p -u -r1.34 reader.c --- reader.c25 May 2017 20:11:03 - 1.34 +++ reader.c3 Nov 2017 09:07:47 - @@ -171,21 +171,17 @@ get_line(void) char * dup_line(void) { - char *p, *s, *t; + char *p, *end; + size_t len; if (line == NULL) - return (0); - s = line; - while (*s != '\n') - ++s; - p = malloc(s - line + 1); + return (NULL); + if ((end = strchr(line, '\n')) == NULL) + syntax_error(lineno, line, line + strlen(line)); + len = end - line + 1; + p = strndup(line, len); if (p == NULL) no_space(); - - s = line; - t = p; - while ((*t++ = *s++) != '\n') - continue; return (p); }
Re: yacc: malloc+copy -> strndup()
On Fri, Nov 03, 2017 at 04:22:43PM +0800, Michael W. Bombardieri wrote: > On Fri, Nov 03, 2017 at 04:03:44PM +0800, Michael W. Bombardieri wrote: > > Hello, > > > > In yacc the dup_line() function malloc()'ed a buffer and copied > > a line into it. The copied line includes \n. > > Allocate-and-copy can be done by strndup() in one hit. > > I ran this on i386 with awk/awkgram.y and rcs/date.y and didn't > > see any difference in y.tab.c compared to the system's yacc. > > > > - Michael > > Forgot to mention. The assert() is triggered if '\0' is encountered before > '\n'. > Even if that is ok, a better error message could be printed instead of > assert(). Yes, we are very reluctant to use assert()... what if somebody compiles with NDEBUG? -Otto > > > > > > > Index: reader.c > > === > > RCS file: /cvs/src/usr.bin/yacc/reader.c,v > > retrieving revision 1.34 > > diff -u -p -u -r1.34 reader.c > > --- reader.c25 May 2017 20:11:03 - 1.34 > > +++ reader.c3 Nov 2017 07:48:08 - > > @@ -171,21 +171,17 @@ get_line(void) > > char * > > dup_line(void) > > { > > - char *p, *s, *t; > > + char *p, *end; > > + size_t len; > > > > if (line == NULL) > > - return (0); > > - s = line; > > - while (*s != '\n') > > - ++s; > > - p = malloc(s - line + 1); > > + return (NULL); > > + end = strchr(line, '\n'); > > + assert(end != NULL); > > + len = end - line + 1; > > + p = strndup(line, len); > > if (p == NULL) > > no_space(); > > - > > - s = line; > > - t = p; > > - while ((*t++ = *s++) != '\n') > > - continue; > > return (p); > > } > >
Re: yacc: malloc+copy -> strndup()
On Fri, Nov 03, 2017 at 04:03:44PM +0800, Michael W. Bombardieri wrote: > Hello, > > In yacc the dup_line() function malloc()'ed a buffer and copied > a line into it. The copied line includes \n. > Allocate-and-copy can be done by strndup() in one hit. > I ran this on i386 with awk/awkgram.y and rcs/date.y and didn't > see any difference in y.tab.c compared to the system's yacc. > > - Michael Forgot to mention. The assert() is triggered if '\0' is encountered before '\n'. Even if that is ok, a better error message could be printed instead of assert(). > > > Index: reader.c > === > RCS file: /cvs/src/usr.bin/yacc/reader.c,v > retrieving revision 1.34 > diff -u -p -u -r1.34 reader.c > --- reader.c 25 May 2017 20:11:03 - 1.34 > +++ reader.c 3 Nov 2017 07:48:08 - > @@ -171,21 +171,17 @@ get_line(void) > char * > dup_line(void) > { > - char *p, *s, *t; > + char *p, *end; > + size_t len; > > if (line == NULL) > - return (0); > - s = line; > - while (*s != '\n') > - ++s; > - p = malloc(s - line + 1); > + return (NULL); > + end = strchr(line, '\n'); > + assert(end != NULL); > + len = end - line + 1; > + p = strndup(line, len); > if (p == NULL) > no_space(); > - > - s = line; > - t = p; > - while ((*t++ = *s++) != '\n') > - continue; > return (p); > } >
yacc: malloc+copy -> strndup()
Hello, In yacc the dup_line() function malloc()'ed a buffer and copied a line into it. The copied line includes \n. Allocate-and-copy can be done by strndup() in one hit. I ran this on i386 with awk/awkgram.y and rcs/date.y and didn't see any difference in y.tab.c compared to the system's yacc. - Michael Index: reader.c === RCS file: /cvs/src/usr.bin/yacc/reader.c,v retrieving revision 1.34 diff -u -p -u -r1.34 reader.c --- reader.c25 May 2017 20:11:03 - 1.34 +++ reader.c3 Nov 2017 07:48:08 - @@ -171,21 +171,17 @@ get_line(void) char * dup_line(void) { - char *p, *s, *t; + char *p, *end; + size_t len; if (line == NULL) - return (0); - s = line; - while (*s != '\n') - ++s; - p = malloc(s - line + 1); + return (NULL); + end = strchr(line, '\n'); + assert(end != NULL); + len = end - line + 1; + p = strndup(line, len); if (p == NULL) no_space(); - - s = line; - t = p; - while ((*t++ = *s++) != '\n') - continue; return (p); }