/[anubis]/anubis/src/rcfile.y
ViewVC logotype

Diff of /anubis/src/rcfile.y

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6 by gray, Fri Feb 7 23:00:34 2003 UTC revision 1.7 by gray, Wed Feb 26 16:57:41 2003 UTC
# Line 53  static RC_STMT *rc_stmt_create(enum rc_s Line 53  static RC_STMT *rc_stmt_create(enum rc_s
53  static void rc_stmt_destroy(RC_STMT *stmt);  static void rc_stmt_destroy(RC_STMT *stmt);
54  static void rc_stmt_list_destroy(RC_STMT *stmt);  static void rc_stmt_list_destroy(RC_STMT *stmt);
55  static void rc_stmt_print(RC_STMT *stmt, int level);  static void rc_stmt_print(RC_STMT *stmt, int level);
56  static void reg_option_init();  static int reg_option_add(int *flag, char *opt);
 static int reg_option_add(char *opt);  
57    
58  static RC_SECTION *rc_section;  static RC_SECTION *rc_section;
 static int reg_opt;  
 static int perlre;  
59    
60  static int debug_level;  static int debug_level;
61    
# Line 77  static int debug_level; Line 74  static int debug_level;
74  };  };
75    
76  %token EOL T_BEGIN T_END AND OR EQ NE  %token EOL T_BEGIN T_END AND OR EQ NE
77  %token T_HEADER T_COMMAND IF FI ELSE RULE DONE  %token T_HEADER T_COMMAND T_BODY IF FI ELSE RULE DONE
78  %token <string> IDENT STRING REGEX D_BEGIN  %token <string> IDENT STRING REGEX D_BEGIN
79    
80  %left OR  %left OR
81  %left AND  %left AND
82    %left NOT
83    
84  %type <string> begin keyword  %type <string> begin keyword string option
85  %type <section> section seclist  %type <section> section seclist
86  %type <stmtlist> stmtlist  %type <stmtlist> stmtlist
87  %type <stmt> stmt asgn_stmt cond_stmt rule_stmt  %type <stmt> stmt asgn_stmt cond_stmt rule_stmt
88  %type <cond> cond  %type <num> part optlist
89  %type <num> cond_lhs  %type <node> rule_start cond expr
 %type <node> cond_rhs compat_rx_list rx_list regex rule_start  
 %type <regex> compat_rx  
90    
91  %%  %%
92    
# Line 184  keyword  : IDENT Line 180  keyword  : IDENT
180  cond_stmt: if cond stmtlist fi  cond_stmt: if cond stmtlist fi
181             {             {
182                     $$ = rc_stmt_create(rc_stmt_cond);                     $$ = rc_stmt_create(rc_stmt_cond);
183                     $$->v.cond = $2;                     $$->v.cond.node = $2;
184                     $$->v.cond.iftrue = $3.head;                     $$->v.cond.iftrue = $3.head;
185                     $$->v.cond.iffalse = NULL;                     $$->v.cond.iffalse = NULL;
186             }             }
187           | if cond stmtlist else stmtlist fi           | if cond stmtlist else stmtlist fi
188             {             {
189                     $$ = rc_stmt_create(rc_stmt_cond);                     $$ = rc_stmt_create(rc_stmt_cond);
190                     $$->v.cond = $2;                     $$->v.cond.node = $2;
191                     $$->v.cond.iftrue = $3.head;                     $$->v.cond.iftrue = $3.head;
192                     $$->v.cond.iffalse = $5.head;                     $$->v.cond.iffalse = $5.head;
193             }             }
194           ;           ;
195    
196  cond     : cond_lhs { reg_option_init(); } optlist cond_rhs  cond     : expr
197             | '(' cond ')'
198             {             {
199                     $$.method = $1;                     $$ = $2;
                    $$.node = $4;  
200             }             }
201           ;           | cond AND cond
   
 cond_lhs : T_HEADER  
202             {             {
203                     $$ = HEADER;                     $$ = rc_node_create(rc_node_bool);
204                       $$->v.bool.op = bool_and;
205                       $$->v.bool.left = $1;
206                       $$->v.bool.right = $3;
207             }             }
208           | T_COMMAND           | cond OR cond
209             {             {
210                     $$ = COMMAND;                     $$ = rc_node_create(rc_node_bool);
211                       $$->v.bool.op = bool_or;
212                       $$->v.bool.left = $1;
213                       $$->v.bool.right = $3;
214             }             }
215           ;           | NOT cond
   
 optlist  : /* empty */  
          | option  
          | optlist option  
          ;  
   
 option   : ':' IDENT  
216             {             {
217                     int rc = reg_option_add($2);                     $$ = rc_node_create(rc_node_bool);
218                     xfree($2);                     $$->v.bool.op = bool_not;
219                     if (rc)                     $$->v.bool.left = $2;
220                             YYERROR;                     $$->v.bool.right = NULL;
221             }             }
222           ;           ;
223    
224  cond_rhs : compat_rx_list  expr     : part '[' string ']' optlist string
          | rx_list  
          ;  
   
 compat_rx_list: compat_rx  
225             {             {
226                     $$ = rc_node_create(rc_node_re);                     $$ = rc_node_create(rc_node_expr);
227                     $$->v.re = $1;                     $$->v.expr.part = $1;
228                       $$->v.expr.key = $3;
229                       $$->v.expr.re = anubis_regex_compile($6, $5);
230             }             }
231           | compat_rx_list compat_rx           | part optlist string
232             {             {
233                     RC_NODE *node;                     $$ = rc_node_create(rc_node_expr);
234                       $$->v.expr.part = $1;
235                     node = rc_node_create(rc_node_bool);                     $$->v.expr.key = NULL;
236                     node->v.bool.op = bool_not;                     $$->v.expr.re = anubis_regex_compile($3, $2);
                    node->v.bool.left = rc_node_create(rc_node_re);  
                    node->v.bool.left->v.re = $2;  
                             
                    $$ = rc_node_create(rc_node_bool);  
                    $$->v.bool.op = bool_and;  
                    $$->v.bool.left = $1;  
                    $$->v.bool.right = node;  
237             }             }
238           ;           | T_BODY optlist string
   
 compat_rx: REGEX  
239             {             {
240                     $$ = anubis_regex_compile($1, reg_opt);                     $$ = rc_node_create(rc_node_expr);
241                     if (!$$)                     $$->v.expr.part = BODY;
242                             YYERROR;                     $$->v.expr.key = NULL;
243                       $$->v.expr.re = anubis_regex_compile($3, $2);
244             }             }
245           ;           ;
246    
247  rx_list  : regex  part     : T_HEADER
          | rx_list and regex  
248             {             {
249                     $$ = rc_node_create(rc_node_bool);                     $$ = HEADER;
                    $$->v.bool.op = bool_and;  
                    $$->v.bool.left = $1;  
                    $$->v.bool.right = $3;  
250             }             }
251           | rx_list or regex           | T_COMMAND
252             {             {
253                     $$ = rc_node_create(rc_node_bool);                     $$ = COMMAND;
                    $$->v.bool.op = bool_or;  
                    $$->v.bool.left = $1;  
                    $$->v.bool.right = $3;  
254             }             }
255           ;           ;
256    
257  regex    : '(' rx_list ')'  optlist  : /* empty */
258             {             {
259                     $$ = $2;                     $$ = 0;
260             }             }
261           | EQ STRING           | option
262             {             {
263                     RC_REGEX *re = anubis_regex_compile($2, reg_opt);                     int rc;
264                                         $$ = 0;
265                     if (!re)                     rc = reg_option_add(&$$, $1);
266                       xfree($1);
267                       if (rc)
268                             YYERROR;                             YYERROR;
                    $$ = rc_node_create(rc_node_re);  
                    $$->v.re = re;  
269             }             }
270           | NE STRING           | optlist option
271             {             {
272                     RC_REGEX *re = anubis_regex_compile($2, reg_opt);                     int rc = reg_option_add(&$1, $2);
273                                         xfree($2);
274                     if (!re)                     if (rc)
275                             YYERROR;                             YYERROR;
276                       $$ = $1;
                    $$ = rc_node_create(rc_node_bool);  
                    $$->v.bool.op = bool_not;  
                    $$->v.bool.left = rc_node_create(rc_node_re);  
                    $$->v.bool.left->v.re = re;  
                    $$->v.bool.right = NULL;  
277             }             }
278           ;           ;
279    
280  and      : /* empty */  option   : ':' IDENT
281           | AND             {
282           ;                     $$ = $2;
283               }
 or       : OR  
284           ;           ;
285    
286  if       : IF  if       : IF
# Line 330  rule_stmt: rule_start EOL stmtlist DONE Line 300  rule_stmt: rule_start EOL stmtlist DONE
300             }             }
301           ;           ;
302    
303  rule_start: RULE optlist cond_rhs  rule_start: RULE optlist string
304             {             {
305                     $$ = $3;                     $$ = rc_node_create(rc_node_expr);
306                       $$->v.expr.part = HEADER;
307                       $$->v.expr.key = strdup(X_ANUBIS_RULE_HEADER);
308                       $$->v.expr.re = anubis_regex_compile($3, $2);
309             }             }
310           ;           ;
311    
312    string   : STRING
313             | IDENT
314             ;
315    
316  %%  %%
317    
318  int  int
# Line 473  rc_node_destroy(RC_NODE *node) Line 450  rc_node_destroy(RC_NODE *node)
450                  rc_bool_destroy(&node->v.bool);                  rc_bool_destroy(&node->v.bool);
451                  break;                  break;
452                                    
453          case rc_node_re:          case rc_node_expr:
454                  anubis_regex_free(node->v.re);                  free(node->v.expr.key);
455                    anubis_regex_free(node->v.expr.re);
456          }          }
457          xfree(node);          xfree(node);
458  }  }
459    
460    static char *
461    part_string(int part)
462    {
463            switch (part) {
464            case NIL:
465                    return "NIL";
466            case COMMAND:
467                    return "COMMAND";
468            case HEADER:
469                    return "HEADER";
470            case BODY:
471                    return "BODY";
472            default:
473                    return "UNKNOWN";
474            }
475    }
476    
477  void  void
478  rc_node_print(RC_NODE *node)  rc_node_print(RC_NODE *node)
479  {  {
480          switch (node->type) {          switch (node->type) {
481          case rc_node_re:          case rc_node_expr:
482                  printf("%s", anubis_regex_source(node->v.re));                  printf("%s", part_string(node->v.expr.part));
483                    if (node->v.expr.key && node->v.expr.key[0] != '\n')
484                            printf("[%s]",node->v.expr.key);
485                    printf(" %s", anubis_regex_source(node->v.expr.re));
486                  break;                  break;
487                                    
488          case rc_node_bool:          case rc_node_bool:
# Line 621  rc_stmt_print(RC_STMT *stmt, int level) Line 619  rc_stmt_print(RC_STMT *stmt, int level)
619          }          }
620  }  }
621    
   
 void  
 reg_option_init()  
 {  
         reg_opt = 0;  
 }  
   
622  int  int
623  reg_option_add(char *opt)  reg_option_add(int *flag, char *opt)
624  {  {
625          if (strcasecmp(opt, "basic") == 0)          if (strcasecmp(opt, "basic") == 0)
626                  reg_opt |= R_BASIC;                  *flag |= R_BASIC;
627          else if (strcasecmp(opt, "scase") == 0)          else if (strcasecmp(opt, "scase") == 0)
628                  reg_opt |= R_SCASE;                  *flag |= R_SCASE;
629  #ifdef HAVE_PCRE  #ifdef HAVE_PCRE
630          else if (strcasecmp(opt, "perlre") == 0)          else if (strcasecmp(opt, "perlre") == 0)
631                  reg_opt |= R_PERLRE;                  *flag |= R_PERLRE;
632  #endif  #endif
633          else {          else {
634                  yyerror(_("Unknown regexp option"));                  yyerror(_("Unknown regexp option"));
# Line 691  struct eval_env { Line 682  struct eval_env {
682          int method;          int method;
683          int cmp_method;          int cmp_method;
684          struct rc_secdef_child *child;          struct rc_secdef_child *child;
685            MESSAGE *msg;
686          void *data;          void *data;
         char *line;  
687          int refcnt;          int refcnt;
688          char **refstr;          char **refstr;
689  };  };
# Line 717  asgn_eval(struct eval_env *env, RC_ASGN Line 708  asgn_eval(struct eval_env *env, RC_ASGN
708                  str = substitute(asgn->rhs, env->refstr);                  str = substitute(asgn->rhs, env->refstr);
709          else          else
710                  str = asgn->rhs;                  str = asgn->rhs;
711          p->parser(env->method, key, str, env->data, p->data, env->line);          p->parser(env->method, key, str, p->data, env->data, env->msg);
712    }
713    
714    
715    int
716    re_eval_list(struct eval_env *env, char *key, RC_REGEX *re, struct list *list)
717    {
718            ASSOC *p;
719            int rc = 0;
720            
721            for (p = list_first(list); rc == 0 && p; p = list_next(list)) {
722                    if (!p->key || strcasecmp(p->key, key) == 0)
723                            rc = anubis_regex_match(re, p->value,
724                                                    &env->refcnt, &env->refstr);
725            }
726            return rc;
727    }
728    
729    int
730    re_eval_text(struct eval_env *env, RC_REGEX *re, char *text)
731    {
732            /*FIXME*/
733            return anubis_regex_match(re, text, &env->refcnt, &env->refstr);
734    }
735    
736    int
737    expr_eval(struct eval_env *env, RC_EXPR *expr)
738    {
739            int rc;
740            
741            if (env->refstr && anubis_regex_refcnt(expr->re)) {
742                    xfree_pptr(env->refstr);
743                    env->refstr = NULL;
744                    env->refcnt = 0;
745            }
746    
747            switch (expr->part) {
748            case COMMAND:
749                    rc = re_eval_list(env, expr->key, expr->re,
750                                      env->msg->commands);
751                    break;
752                    
753            case HEADER:
754                    rc = re_eval_list(env, expr->key, expr->re, env->msg->header);
755                    break;
756                    
757            case BODY:
758                    rc = re_eval_text(env, expr->re, env->msg->body);
759                    break;
760    
761            default:
762                    abort();
763            }
764            return rc;
765  }  }
766    
767  int  int
# Line 730  node_eval(struct eval_env *env, RC_NODE Line 774  node_eval(struct eval_env *env, RC_NODE
774          case rc_node_bool:          case rc_node_bool:
775                  rc = bool_eval(env, &node->v.bool);                  rc = bool_eval(env, &node->v.bool);
776                  break;                  break;
777          case rc_node_re:          case rc_node_expr:
778                  if (env->refstr && anubis_regex_refcnt(node->v.re)) {                  rc = expr_eval(env, &node->v.expr);
                         xfree_pptr(env->refstr);  
                         env->refstr = NULL;  
                         env->refcnt = 0;  
                 }  
                 rc = anubis_regex_match(node->v.re, env->line,  
                                         &env->refcnt, &env->refstr);  
779                  break;                  break;
780                                    
781          default:          default:
# Line 771  bool_eval(struct eval_env *env, RC_BOOL Line 809  bool_eval(struct eval_env *env, RC_BOOL
809  void  void
810  cond_eval(struct eval_env *env, RC_COND *cond)  cond_eval(struct eval_env *env, RC_COND *cond)
811  {  {
812          if (cond->method != env->cmp_method)          if (node_eval(env, cond->node))
                 stmt_list_eval(env, cond->iffalse);  
         else if (node_eval(env, cond->node))  
813                  stmt_list_eval(env, cond->iftrue);                  stmt_list_eval(env, cond->iftrue);
814          else          else
815                  stmt_list_eval(env, cond->iffalse);                  stmt_list_eval(env, cond->iffalse);
# Line 782  cond_eval(struct eval_env *env, RC_COND Line 818  cond_eval(struct eval_env *env, RC_COND
818  void  void
819  rule_eval(struct eval_env *env, RC_RULE *rule)  rule_eval(struct eval_env *env, RC_RULE *rule)
820  {  {
821          if (env->cmp_method == HEADER && node_eval(env, rule->node))          if (node_eval(env, rule->node))
822                  stmt_list_eval(env, rule->stmt);                  stmt_list_eval(env, rule->stmt);
823  }  }
824    
# Line 806  stmt_list_eval(struct eval_env *env, RC_ Line 842  stmt_list_eval(struct eval_env *env, RC_
842    
843  void  void
844  rc_run_section(int method, RC_SECTION *sec, struct rc_secdef *secdef,  rc_run_section(int method, RC_SECTION *sec, struct rc_secdef *secdef,
845                 int cmp_method, char *line, void *data)                 void *data, MESSAGE *msg)
846  {  {
847          if (!sec)          if (!sec)
848                  return;                  return;
# Line 814  rc_run_section(int method, RC_SECTION *s Line 850  rc_run_section(int method, RC_SECTION *s
850                  if (strcmp(sec->name, secdef->name) == 0) {                  if (strcmp(sec->name, secdef->name) == 0) {
851                          struct eval_env env;                          struct eval_env env;
852                          env.method = method;                          env.method = method;
                         env.cmp_method = cmp_method;  
853                          env.child = secdef->child;                          env.child = secdef->child;
                         env.line = line;  
854                          env.refcnt = 0;                          env.refcnt = 0;
855                          env.refstr = NULL;                          env.refstr = NULL;
856                            env.msg = msg;
857                          env.data = data;                          env.data = data;
858                                                    
859                          stmt_list_eval(&env, sec->stmt);                          stmt_list_eval(&env, sec->stmt);
# Line 835  void Line 870  void
870  rc_run_section_list(int method, RC_SECTION *sec, struct rc_secdef *secdef)  rc_run_section_list(int method, RC_SECTION *sec, struct rc_secdef *secdef)
871  {  {
872          for (; sec; sec = sec->next)          for (; sec; sec = sec->next)
873                  rc_run_section(method, sec, secdef, NIL, NULL, NULL);                  rc_run_section(method, sec, secdef, NULL, NULL);
874  }  }
875    
876    

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26