Re: ospf6d/parse.y : fix line count

2018-06-03 Thread Remi Locherer
On Sat, Jun 02, 2018 at 10:33:07PM +0200, Denis Fondras wrote:
> Applying otto@'s diff to ospf6d.
> Fixes an off-by-one line count when using include statements.
> 
> Ok ?

I applied your diff and verified that the line number for errors
in included files is now correct.

ok remi@

> 
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v
> retrieving revision 1.31
> diff -u -p -r1.31 parse.y
> --- parse.y   26 Apr 2018 14:12:19 -  1.31
> +++ parse.y   2 Jun 2018 20:18:24 -
> @@ -50,6 +50,10 @@ static struct file {
>   TAILQ_ENTRY(file)entry;
>   FILE*stream;
>   char*name;
> + size_t   ungetpos;
> + size_t   ungetsize;
> + u_char  *ungetbuf;
> + int  eof_reached;
>   int  lineno;
>   int  errors;
>  } *file, *topfile;
> @@ -63,8 +67,9 @@ int  yyerror(const char *, ...)
>  __attribute__((__nonnull__ (1)));
>  int   kw_cmp(const void *, const void *);
>  int   lookup(char *);
> +int   igetc(void);
>  int   lgetc(int);
> -int   lungetc(int);
> +void  lungetc(int);
>  int   findeol(void);
>  
>  TAILQ_HEAD(symhead, sym)  symhead = TAILQ_HEAD_INITIALIZER(symhead);
> @@ -146,7 +151,8 @@ grammar   : /* empty */
>  include  : INCLUDE STRING{
>   struct file *nfile;
>  
> - if ((nfile = pushfile($2, 1)) == NULL) {
> + if ((nfile = pushfile($2,
> + !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) {
>   yyerror("failed to include file %s", $2);
>   free($2);
>   YYERROR;
> @@ -591,34 +597,39 @@ lookup(char *s)
>   return (STRING);
>  }
>  
> -#define MAXPUSHBACK  128
> +#define START_EXPAND 1
> +#define DONE_EXPAND  2
>  
> -u_char   *parsebuf;
> -int   parseindex;
> -u_charpushback_buffer[MAXPUSHBACK];
> -int   pushback_index = 0;
> +static int   expanding;
>  
>  int
> -lgetc(int quotec)
> +igetc(void)
>  {
> - int c, next;
> + int c;
>  
> - if (parsebuf) {
> - /* Read character from the parsebuffer instead of input. */
> - if (parseindex >= 0) {
> - c = parsebuf[parseindex++];
> - if (c != '\0')
> - return (c);
> - parsebuf = NULL;
> - } else
> - parseindex++;
> + while (1) {
> + if (file->ungetpos > 0)
> + c = file->ungetbuf[--file->ungetpos];
> + else
> + c = getc(file->stream);
> +
> + if (c == START_EXPAND)
> + expanding = 1;
> + else if (c == DONE_EXPAND)
> + expanding = 0;
> + else
> + break;
>   }
> + return (c);
> +}
>  
> - if (pushback_index)
> - return (pushback_buffer[--pushback_index]);
> +int
> +lgetc(int quotec)
> +{
> + int c, next;
>  
>   if (quotec) {
> - if ((c = getc(file->stream)) == EOF) {
> + if ((c = igetc()) == EOF) {
>   yyerror("reached end of file while parsing "
>   "quoted string");
>   if (file == topfile || popfile() == EOF)
> @@ -628,8 +639,8 @@ lgetc(int quotec)
>   return (c);
>   }
>  
> - while ((c = getc(file->stream)) == '\\') {
> - next = getc(file->stream);
> + while ((c = igetc()) == '\\') {
> + next = igetc();
>   if (next != '\n') {
>   c = next;
>   break;
> @@ -638,28 +649,39 @@ lgetc(int quotec)
>   file->lineno++;
>   }
>  
> - while (c == EOF) {
> - if (file == topfile || popfile() == EOF)
> - return (EOF);
> - c = getc(file->stream);
> + if (c == EOF) {
> + /*
> +  * Fake EOL when hit EOF for the first time. This gets line
> +  * count right if last line in included file is syntactically
> +  * invalid and has no newline.
> +  */
> + if (file->eof_reached == 0) {
> + file->eof_reached = 1;
> + return ('\n');
> + }
> + while (c == EOF) {
> + if (file == topfile || popfile() == EOF)
> + return (EOF);
> + c = igetc();
> + }
>   }
>   return (c);
>  }
>  
> -int
> +void
>  lungetc(int c)
>  {
>   if (c == EOF)
> - return (EOF);
> -   

ospf6d/parse.y : fix line count

2018-06-02 Thread Denis Fondras
Applying otto@'s diff to ospf6d.
Fixes an off-by-one line count when using include statements.

Ok ?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v
retrieving revision 1.31
diff -u -p -r1.31 parse.y
--- parse.y 26 Apr 2018 14:12:19 -  1.31
+++ parse.y 2 Jun 2018 20:18:24 -
@@ -50,6 +50,10 @@ static struct file {
TAILQ_ENTRY(file)entry;
FILE*stream;
char*name;
+   size_t   ungetpos;
+   size_t   ungetsize;
+   u_char  *ungetbuf;
+   int  eof_reached;
int  lineno;
int  errors;
 } *file, *topfile;
@@ -63,8 +67,9 @@ intyyerror(const char *, ...)
 __attribute__((__nonnull__ (1)));
 int kw_cmp(const void *, const void *);
 int lookup(char *);
+int igetc(void);
 int lgetc(int);
-int lungetc(int);
+voidlungetc(int);
 int findeol(void);
 
 TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead);
@@ -146,7 +151,8 @@ grammar : /* empty */
 include: INCLUDE STRING{
struct file *nfile;
 
-   if ((nfile = pushfile($2, 1)) == NULL) {
+   if ((nfile = pushfile($2,
+   !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -591,34 +597,39 @@ lookup(char *s)
return (STRING);
 }
 
-#define MAXPUSHBACK128
+#define START_EXPAND   1
+#define DONE_EXPAND2
 
-u_char *parsebuf;
-int parseindex;
-u_char  pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
+static int expanding;
 
 int
-lgetc(int quotec)
+igetc(void)
 {
-   int c, next;
+   int c;
 
-   if (parsebuf) {
-   /* Read character from the parsebuffer instead of input. */
-   if (parseindex >= 0) {
-   c = parsebuf[parseindex++];
-   if (c != '\0')
-   return (c);
-   parsebuf = NULL;
-   } else
-   parseindex++;
+   while (1) {
+   if (file->ungetpos > 0)
+   c = file->ungetbuf[--file->ungetpos];
+   else
+   c = getc(file->stream);
+
+   if (c == START_EXPAND)
+   expanding = 1;
+   else if (c == DONE_EXPAND)
+   expanding = 0;
+   else
+   break;
}
+   return (c);
+}
 
-   if (pushback_index)
-   return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+   int c, next;
 
if (quotec) {
-   if ((c = getc(file->stream)) == EOF) {
+   if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -628,8 +639,8 @@ lgetc(int quotec)
return (c);
}
 
-   while ((c = getc(file->stream)) == '\\') {
-   next = getc(file->stream);
+   while ((c = igetc()) == '\\') {
+   next = igetc();
if (next != '\n') {
c = next;
break;
@@ -638,28 +649,39 @@ lgetc(int quotec)
file->lineno++;
}
 
-   while (c == EOF) {
-   if (file == topfile || popfile() == EOF)
-   return (EOF);
-   c = getc(file->stream);
+   if (c == EOF) {
+   /*
+* Fake EOL when hit EOF for the first time. This gets line
+* count right if last line in included file is syntactically
+* invalid and has no newline.
+*/
+   if (file->eof_reached == 0) {
+   file->eof_reached = 1;
+   return ('\n');
+   }
+   while (c == EOF) {
+   if (file == topfile || popfile() == EOF)
+   return (EOF);
+   c = igetc();
+   }
}
return (c);
 }
 
-int
+void
 lungetc(int c)
 {
if (c == EOF)
-   return (EOF);
-   if (parsebuf) {
-   parseindex--;
-   if (parseindex >= 0)
-   return (c);
+   return;
+
+   if (file->ungetpos >= file->ungetsize) {
+   void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+