Commit c2520d2f c2520d2ff5f9bdaf2fcecb673fc023ebf7d75f29 by Sergey Poznyakoff

Stricter typing of productions. The cntl

production allows for empty lists (e.g. %<{reply-to}%?{from}%>).
Enable debugging when MHFORMAT_DEBUG environment variable is
set.
(yylex): Skip whitespace after the function name.
(branch_fixup): The produced jump offset was wrong. Fixed.
(mh_code_builtin): Fixed passing of escape arguments.
1 parent 29849507
...@@ -61,12 +61,15 @@ static int want_function; /* Set when expecting function name */ ...@@ -61,12 +61,15 @@ static int want_function; /* Set when expecting function name */
61 %token BOGUS 61 %token BOGUS
62 %type <type> cond_expr component funcall item argument escape literal 62 %type <type> cond_expr component funcall item argument escape literal
63 %type <elif_list> elif_part elif_list fi 63 %type <elif_list> elif_part elif_list fi
64 %type <pc> cond end else elif else_part 64 %type <pc> cond end else elif else_part zlist list pitem
65 %type <builtin> function 65 %type <builtin> function
66 66
67 %% 67 %%
68 68
69 input : list 69 input : list
70 {
71 /* nothing: to shut bison up */
72 }
70 ; 73 ;
71 74
72 list : pitem 75 list : pitem
...@@ -94,6 +97,7 @@ pitem : item ...@@ -94,6 +97,7 @@ pitem : item
94 yyerror ("UNEXPECTED item TYPE"); 97 yyerror ("UNEXPECTED item TYPE");
95 abort (); 98 abort ();
96 } 99 }
100 $$ = pc;
97 } 101 }
98 ; 102 ;
99 103
...@@ -212,7 +216,7 @@ argument : /* empty */ ...@@ -212,7 +216,7 @@ argument : /* empty */
212 ; 216 ;
213 217
214 /* 1 2 3 4 5 6 7 */ 218 /* 1 2 3 4 5 6 7 */
215 cntl : if cond list end elif_part else_part fi 219 cntl : if cond zlist end elif_part else_part fi
216 { 220 {
217 size_t start_pc = 0, end_pc = 0; 221 size_t start_pc = 0, end_pc = 0;
218 222
...@@ -244,6 +248,13 @@ cntl : if cond list end elif_part else_part fi ...@@ -244,6 +248,13 @@ cntl : if cond list end elif_part else_part fi
244 } 248 }
245 ; 249 ;
246 250
251 zlist : /* empty */
252 {
253 $$ = pc;
254 }
255 | list
256 ;
257
247 if : IF 258 if : IF
248 { 259 {
249 in_escape++; 260 in_escape++;
...@@ -305,13 +316,13 @@ elif_part : /* empty */ ...@@ -305,13 +316,13 @@ elif_part : /* empty */
305 } 316 }
306 ; 317 ;
307 318
308 elif_list : elif cond list 319 elif_list : elif cond zlist
309 { 320 {
310 $$.cond = $1; 321 $$.cond = $1;
311 MHI_NUM(format.prog[$2]) = pc - $2 + 2; 322 MHI_NUM(format.prog[$2]) = pc - $2 + 2;
312 $$.end = 0; 323 $$.end = 0;
313 } 324 }
314 | elif_list end elif cond list 325 | elif_list end elif cond zlist
315 { 326 {
316 MHI_NUM(format.prog[$4]) = pc - $4 + 2; 327 MHI_NUM(format.prog[$4]) = pc - $4 + 2;
317 $$.cond = $1.cond; 328 $$.cond = $1.cond;
...@@ -356,6 +367,8 @@ static int backslash(int c); ...@@ -356,6 +367,8 @@ static int backslash(int c);
356 int 367 int
357 yylex () 368 yylex ()
358 { 369 {
370 if (yydebug)
371 fprintf (stderr, "[lex at %10.10s]\n", curp);
359 if (*curp == '%') 372 if (*curp == '%')
360 { 373 {
361 curp++; 374 curp++;
...@@ -458,6 +471,8 @@ yylex () ...@@ -458,6 +471,8 @@ yylex ()
458 { 471 {
459 curp -= rest; 472 curp -= rest;
460 yylval.builtin = bp; 473 yylval.builtin = bp;
474 while (*curp && isspace(*curp))
475 curp++;
461 return FUNCTION; 476 return FUNCTION;
462 } 477 }
463 } 478 }
...@@ -469,7 +484,10 @@ int ...@@ -469,7 +484,10 @@ int
469 mh_format_parse (char *format_str, mh_format_t *fmt) 484 mh_format_parse (char *format_str, mh_format_t *fmt)
470 { 485 {
471 int rc; 486 int rc;
487 char *p = getenv ("MHFORMAT_DEBUG");
472 488
489 if (p)
490 yydebug = 1;
473 start = curp = format_str; 491 start = curp = format_str;
474 obstack_init (&stack); 492 obstack_init (&stack);
475 format.progsize = 0; 493 format.progsize = 0;
...@@ -512,7 +530,7 @@ branch_fixup (size_t epc, size_t tgt) ...@@ -512,7 +530,7 @@ branch_fixup (size_t epc, size_t tgt)
512 if (!prev) 530 if (!prev)
513 return; 531 return;
514 branch_fixup (prev, tgt); 532 branch_fixup (prev, tgt);
515 MHI_NUM(format.prog[prev]) = tgt - prev - 1; 533 MHI_NUM(format.prog[prev]) = tgt - prev;
516 } 534 }
517 535
518 536
...@@ -587,9 +605,14 @@ mh_code_builtin (mh_builtin_t *bp, int argtype) ...@@ -587,9 +605,14 @@ mh_code_builtin (mh_builtin_t *bp, int argtype)
587 case mhtype_num: 605 case mhtype_num:
588 mh_code_op (mhop_num_to_arg); 606 mh_code_op (mhop_num_to_arg);
589 break; 607 break;
608
590 case mhtype_str: 609 case mhtype_str:
591 mh_code_op (mhop_str_to_arg); 610 /* mhtype_none means that the argument was an escape,
611 which has left its string value (if any) in the
612 arg_str register. Therefore, there's no need to
613 code mhop_str_to_arg */
592 break; 614 break;
615
593 default: 616 default:
594 yyerror ("UNKNOWN ARGTYPE"); 617 yyerror ("UNKNOWN ARGTYPE");
595 abort (); 618 abort ();
...@@ -608,15 +631,18 @@ mh_code_builtin (mh_builtin_t *bp, int argtype) ...@@ -608,15 +631,18 @@ mh_code_builtin (mh_builtin_t *bp, int argtype)
608 case mhtype_none: 631 case mhtype_none:
609 mh_error ("extra arguments to %s", bp->name); 632 mh_error ("extra arguments to %s", bp->name);
610 return 0; 633 return 0;
634
611 case mhtype_num: 635 case mhtype_num:
612 mh_code_op (mhop_str_to_num); 636 mh_code_op (mhop_str_to_num);
613 break; 637 break;
638
614 case mhtype_str: 639 case mhtype_str:
615 mh_code_op (mhop_num_to_str); 640 mh_code_op (mhop_num_to_str);
616 break; 641 break;
617 } 642 }
618 } 643 }
619 } 644 }
645
620 mh_code_op (mhop_call); 646 mh_code_op (mhop_call);
621 MHI_BUILTIN(instr) = bp->fun; 647 MHI_BUILTIN(instr) = bp->fun;
622 mh_code (&instr); 648 mh_code (&instr);
......