Re: yacc: malloc+copy -> strndup()

2017-11-03 Thread Michael W. Bombardieri
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()

2017-11-03 Thread Otto Moerbeek
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()

2017-11-03 Thread Michael W. Bombardieri
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()

2017-11-03 Thread Michael W. Bombardieri
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);
 }