PATCH: 3.2.0b5 config parser fixes

Gilles Detillieux <[email protected]>
Newsgroups gmane.comp.web.htdig.devel
Message-ID <[email protected]>
Hi, folks.  I was going to take another crack at the performance
optimizations in HtRegexList, but before that, I got down to tackling
some of the config parser bugs that had been nagging at us for quite
some time.  Please have a look at this patch, and test it as much as
possible, to see if it causes any problems.  The fixes in there are:

- improved error handling, gives file name and correct line number, even
  if using include files
- allows space before comment, because otherwise it would just complain
  about the "#" character and go on to parse the text after it as a
  definition
- allows config file with an unterminated line at end of file, by pushing
  an extra newline token to the parser at EOF
- parser correctly handles extra newline tokens, by moving this handling
  out of simple_expression, and into simple_expression_list and block, as
  simple_expression must return a new ConfigDefaults object and a newline
  token doesn't cut it (caused segfaults when dealing with fix above)

Apply using "patch -p0 < this-message-file".

--- htcommon/conf_lexer.lxx.orig	2003-12-14 07:40:12.000000000 -0600
+++ htcommon/conf_lexer.lxx	2004-04-22 15:47:48.000000000 -0500
@@ -41,6 +41,7 @@
 #define MAX_INCLUDE_DEPTH 10
 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
 String *name_stack[MAX_INCLUDE_DEPTH];
+int lineno_stack[MAX_INCLUDE_DEPTH];
 int include_stack_ptr = 0;
 %}
 
@@ -50,7 +51,7 @@ STRING			[\x21-\xff]+
 BR_STRING		[^ \n\t<>]+
 %%
 
-^#.*\n			/*   Ignore comments     */
+^[[:space:]]*#.*\n	/*   Ignore comments     */
 ^[[:space:]]*\n		/*   Ignore emty lines   */
 <*>[ \t]+		/*   Ignore spaces       */
 include[ \t]*:		BEGIN(incl);
@@ -157,6 +158,8 @@ include[ \t]*:		BEGIN(incl);
 			}
 			name_stack[include_stack_ptr-1] =
 					new String(ParsedFilename.get());
+			lineno_stack[include_stack_ptr-1] = yylineno;
+			yylineno = 1;
 		        yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) );
 
 		        BEGIN(INITIAL);
@@ -164,10 +167,18 @@ include[ \t]*:		BEGIN(incl);
 
 <<EOF>> 		{
 		        if ( include_stack_ptr <= 0 )
+			    {
+			    static int termnext = 0;
+			    // fix to allow unterminated final line
+			    if (++termnext <= 1)
+				return(T_NEWLINE);
+			    termnext = 0;	// in case we're called again
 		            yyterminate();
+			    }
 		        else
 		            {
 			    delete name_stack[include_stack_ptr-1];
+			    yylineno = lineno_stack[include_stack_ptr-1];
 		            yy_delete_buffer( YY_CURRENT_BUFFER );
 		            yy_switch_to_buffer(
 		                 include_stack[--include_stack_ptr] );
@@ -183,7 +194,13 @@ include[ \t]*:		BEGIN(incl);
 
 \n			
 <*>.|\n		{ 
-	fprintf(stderr,"Unknown char in line %d: %s",yylineno,yytext);
-	// exit(1); // Seems to harsh!
+	HtConfiguration* config= HtConfiguration::config();
+	String str;
+	if (include_stack_ptr > 0)
+	    str = *name_stack[include_stack_ptr-1];
+	else	// still at top level config
+	    str = config->getFileName();
+	fprintf(stderr,"Unknown char in file %s line %d: %s\n",str.get(),yylineno,yytext);
+	// exit(1); // Seems too harsh!
 	}
 %%
--- htcommon/conf_parser.yxx.orig	2003-11-22 07:40:17.000000000 -0600
+++ htcommon/conf_parser.yxx	2004-04-22 15:48:54.000000000 -0500
@@ -84,6 +84,7 @@ block:        simple_expression		{   
           //    ... : ...
           // </server>
 	}
+        | T_NEWLINE	{ /* Ignore empty lines */  }
 ;
 
 simple_expression:      T_KEYWORD T_DELIMITER T_STRING T_NEWLINE	{ 
@@ -116,7 +117,6 @@ simple_expression:      T_KEYWORD T_DELI
 				    $$->value=new char[1];
 				    *$$->value='\0';
 					}
-        | T_NEWLINE	{ /* Ignore empty lines */  }
 ;
 
 complex_expression:	T_LEFT_BR T_KEYWORD T_DELIMITER T_STRING T_RIGHT_BR T_NEWLINE simple_expression_list T_LEFT_BR T_SLASH T_KEYWORD T_RIGHT_BR T_NEWLINE {
@@ -170,6 +170,7 @@ simple_expression_list:   simple_express
 				delete $2;
 				//$$=$1; //I think $$==$1
 			}
+			| T_NEWLINE	{ /* Ignore empty lines */  }
                       ;
 
 list:	  T_STRING T_STRING			{ 
@@ -253,8 +254,17 @@ list:	  T_STRING T_STRING			{ 
 int
 yyerror (char *s)  /* Called by yyparse on error */
 {
-extern int yylineno;	// I don't know what about included files
-   fprintf (stderr, "%s\nIn line %d\n",s,yylineno);
+extern int yylineno;
+extern int include_stack_ptr;
+extern String *name_stack[];
+   HtConfiguration* config= HtConfiguration::config();
+   String str;
+   if (include_stack_ptr > 0)
+	str = *name_stack[include_stack_ptr-1];
+   else	// still at top level config
+	str = config->getFileName();
+   //fprintf (stderr, "%s\nIn line %d\n",s,yylineno);
+   fprintf(stderr,"Error in file %s line %d: %s\n",str.get(),yylineno,s);
    // exit(1);
    return -1;
 }


-- 
Gilles R. Detillieux              E-mail: <[email protected]>
Spinal Cord Research Centre       WWW:    http://www.scrc.umanitoba.ca/
Dept. Physiology, U. of Manitoba  Winnipeg, MB  R3E 3J7  (Canada)


-------------------------------------------------------
This SF.net email is sponsored by: The Robotic Monkeys at ThinkGeek
For a limited time only, get FREE Ground shipping on all orders of $35
or more. Hurry up and shop folks, this offer expires April 30th!
http://www.thinkgeek.com/freeshipping/?cpg=12297
_______________________________________________
ht://Dig Developer mailing list:
[email protected]
List information (subscribe/unsubscribe, etc.)
https://lists.sourceforge.net/lists/listinfo/htdig-dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.