/[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.24 by gray, Fri Aug 8 20:48:27 2003 UTC revision 1.25 by gray, Thu Aug 14 12:34:26 2003 UTC
# Line 37  Line 37 
37  extern int yylex(void);  extern int yylex(void);
38  int yyerror(char *s);  int yyerror(char *s);
39    
40  static RC_SECTION *rc_section_create(char *, RC_STMT *);  static RC_SECTION *rc_section_create(char *, size_t, RC_STMT *);
41  static void rc_section_destroy(RC_SECTION **);  static void rc_section_destroy(RC_SECTION **);
42  static void rc_section_print(RC_SECTION *);  static void rc_section_print(RC_SECTION *);
43  static void rc_asgn_destroy(RC_ASGN *);  static void rc_asgn_destroy(RC_ASGN *);
# Line 78  static struct rc_secdef *rc_secdef; Line 78  static struct rc_secdef *rc_secdef;
78                  RC_REGEX *key;                  RC_REGEX *key;
79                  char *string;                  char *string;
80          } msgpart;          } msgpart;
81            RC_LOC loc;
82            struct {
83                    size_t line;
84                    char *name;
85            } begin_sec;
86          LIST *list;          LIST *list;
87  };  };
88    
# Line 91  static struct rc_secdef *rc_secdef; Line 96  static struct rc_secdef *rc_secdef;
96  %left AND  %left AND
97  %left NOT  %left NOT
98    
99  %type <string> begin keyword string modifier arg string_key  %type <string> keyword string modifier arg string_key
100  %type <section> section seclist  %type <section> section seclist
101  %type <stmtlist> stmtlist  %type <stmtlist> stmtlist
102  %type <stmt> stmt asgn_stmt cond_stmt rule_stmt inst_stmt modf_stmt  %type <stmt> stmt asgn_stmt cond_stmt rule_stmt inst_stmt modf_stmt
# Line 99  static struct rc_secdef *rc_secdef; Line 104  static struct rc_secdef *rc_secdef;
104  %type <node> rule_start cond expr  %type <node> rule_start cond expr
105  %type <msgpart> msgpart s_msgpart r_msgpart key opt_key  %type <msgpart> msgpart s_msgpart r_msgpart key opt_key
106  %type <list> arglist  %type <list> arglist
107  %type <regex> regex  %type <regex> regex
108    %type <begin_sec> begin
109    
110  %%  %%
111    
# Line 138  section  : /* empty */ EOL Line 144  section  : /* empty */ EOL
144             }             }
145           | begin stmtlist end           | begin stmtlist end
146             {             {
147                     $$ = rc_section_create($1, $2.head);                     $$ = rc_section_create($1.name, $1.line, $2.head);
148             }             }
149           | begin end           | begin end
150             {             {
# Line 148  section  : /* empty */ EOL Line 154  section  : /* empty */ EOL
154    
155  begin    : T_BEGIN { verbatim(); } string EOL  begin    : T_BEGIN { verbatim(); } string EOL
156             {             {
157                     $$ = $3;                     $$.line = cfg_line_num - 1;
158                       $$.name = $3;
159                     if (rc_section_lookup(rc_section, $3))                     if (rc_section_lookup(rc_section, $3))
160                             parse_error(_("Section %s already defined"), $3);                             parse_error(_("Section %s already defined"), $3);
161                     rc_secdef = anubis_find_section($3);                     rc_secdef = anubis_find_section($3);
162             }             }
163           | D_BEGIN EOL           | D_BEGIN EOL
164             {             {
165                       $$.line = cfg_line_num - 1;
166                       $$.name = $1;
167                     if (rc_section_lookup(rc_section, $1))                     if (rc_section_lookup(rc_section, $1))
168                             parse_error(_("Section %s already defined"), $1);                             parse_error(_("Section %s already defined"), $1);
169                     rc_secdef = anubis_find_section($1);                     rc_secdef = anubis_find_section($1);
# Line 566  rc_set_debug_level(char *arg) Line 575  rc_set_debug_level(char *arg)
575                  yydebug = debug_level;                  yydebug = debug_level;
576  }  }
577    
578    
579    /* Locations */
580    
581    /* To save space, each filename is allocated only once. Each filename
582       has a reference count associated with it. It is incremented
583       with each new allocation of the same string. It is decremented
584       with each attempt to free the string. Only when the reference count
585       drops to zero is the storage actually reclaimed */
586    
587    struct strobj {
588            char *value;          /* String value */
589            size_t refcnt;        /* Reference count */
590    };
591    
592    /* A list of string objects */
593    static LIST /* of struct strobj */ *string_list;
594    
595    static int
596    string_comparator(void *item, void *data)
597    {
598            struct strobj *s = item;
599            return strcmp (s->value, (char*) data);
600    }
601    
602    static int
603    value_comparator(void *item, void *data)
604    {
605            struct strobj *s = item;
606            return s->value != data;
607    }
608    
609    /* Looks up a string object with the given value. If not found, a
610       new object is created and added to the list. In any case the
611       reference count of the objet is incremented.
612       The return value is the string value associated with the object. */
613    char *
614    string_create(char *str)
615    {
616            struct strobj *s = list_locate(string_list, str, string_comparator);
617            if (!s) {
618                    s = xmalloc(sizeof(*s));
619                    s->value = strdup(str);
620                    s->refcnt = 0;
621                    list_prepend(string_list, s);
622            }
623            s->refcnt++;
624            return s->value;
625    }
626    
627    /* Destroys the object with the given string value */
628    void
629    string_destroy(char *str)
630    {
631            struct strobj *s = list_locate(string_list, str, value_comparator);
632            if (s) {
633                    if (--s->refcnt == 0) {
634                            free(s->value);
635                            list_remove(string_list, str, value_comparator);
636                    }
637            }
638    }
639    
640    /* Initializes LOC with the current location. If the second argument
641       is not zero, it overrides the current line number. */
642    void
643    rc_mark_loc(RC_LOC *loc, size_t line)
644    {
645            loc->file = string_create(cfg_file);
646            loc->line = line ? line : cfg_line_num;
647    }
648    
649    /* Reclaims the memory associated with the LOC */
650    void
651    rc_destroy_loc(RC_LOC *loc)
652    {
653            string_destroy(loc->file);
654    }
655    
656    
657  /* Section manipulation */  /* Section manipulation */
658    
659  RC_SECTION *  RC_SECTION *
660  rc_section_create(char *name, RC_STMT *stmt)  rc_section_create(char *name, size_t line, RC_STMT *stmt)
661  {  {
662          RC_SECTION *p = xmalloc(sizeof(*p));          RC_SECTION *p = xmalloc(sizeof(*p));
663            rc_mark_loc(&p->loc, line);
664          p->next = NULL;          p->next = NULL;
665          p->name = name;          p->name = name;
666          p->stmt = stmt;          p->stmt = stmt;
# Line 581  void Line 671  void
671  rc_section_destroy(RC_SECTION **s)  rc_section_destroy(RC_SECTION **s)
672  {  {
673          rc_stmt_list_destroy((*s)->stmt);          rc_stmt_list_destroy((*s)->stmt);
674            rc_destroy_loc(&(*s)->loc);
675          xfree((*s)->name);          xfree((*s)->name);
676          xfree(*s);          xfree(*s);
677  }  }
# Line 618  void Line 709  void
709  rc_section_link(RC_SECTION **ap, RC_SECTION *b)  rc_section_link(RC_SECTION **ap, RC_SECTION *b)
710  {  {
711          RC_SECTION *a, *prev;          RC_SECTION *a, *prev;
712            
713          /* Remove all sections with prio == override (the default) */          /* Remove all sections with prio == override (the default) */
714          a = *ap;          a = *ap;
715          prev = NULL;          prev = NULL;
# Line 706  rc_node_create(enum rc_node_type t) Line 797  rc_node_create(enum rc_node_type t)
797  {  {
798          RC_NODE *p = xmalloc(sizeof(*p));          RC_NODE *p = xmalloc(sizeof(*p));
799          memset(p, 0, sizeof(*p));          memset(p, 0, sizeof(*p));
800            rc_mark_loc(&p->loc, 0);
801          p->type = t;          p->type = t;
802          return p;          return p;
803  }  }
# Line 724  rc_node_destroy(RC_NODE *node) Line 816  rc_node_destroy(RC_NODE *node)
816                  free(node->v.expr.key);                  free(node->v.expr.key);
817                  anubis_regex_free(&node->v.expr.re);                  anubis_regex_free(&node->v.expr.re);
818          }          }
819            rc_destroy_loc(&node->loc);
820          xfree(node);          xfree(node);
821  }  }
822    
# Line 865  rc_stmt_create(enum rc_stmt_type type) Line 958  rc_stmt_create(enum rc_stmt_type type)
958  {  {
959          RC_STMT *p = xmalloc(sizeof(*p));          RC_STMT *p = xmalloc(sizeof(*p));
960          memset(p, 0, sizeof(*p));          memset(p, 0, sizeof(*p));
961            rc_mark_loc(&p->loc, 0);
962          p->type = type;          p->type = type;
963          return p;          return p;
964  }  }
# Line 888  rc_stmt_destroy(RC_STMT *stmt) Line 982  rc_stmt_destroy(RC_STMT *stmt)
982          case rc_stmt_inst:          case rc_stmt_inst:
983                  rc_inst_destroy(&stmt->v.inst);                  rc_inst_destroy(&stmt->v.inst);
984          }          }
985            rc_destroy_loc(&stmt->loc);
986          xfree(stmt);          xfree(stmt);
987  }  }
988    
# Line 1047  struct eval_env { Line 1142  struct eval_env {
1142          int refcnt;          int refcnt;
1143          char **refstr;          char **refstr;
1144          jmp_buf jmp;          jmp_buf jmp;
1145            RC_LOC loc;
1146  };  };
1147    
1148  static void asgn_eval(struct eval_env *env, RC_ASGN *asgn);  static void asgn_eval(struct eval_env *env, RC_ASGN *asgn);
# Line 1057  static void rule_eval(struct eval_env *e Line 1153  static void rule_eval(struct eval_env *e
1153  static void stmt_list_eval(struct eval_env *env, RC_STMT *stmt);  static void stmt_list_eval(struct eval_env *env, RC_STMT *stmt);
1154  static void inst_eval(struct eval_env *env, RC_INST *inst);  static void inst_eval(struct eval_env *env, RC_INST *inst);
1155    
1156    #define VALID_STR(s) ((s)?(s):"NULL")
1157    
1158  void  void
1159  inst_eval(struct eval_env *env, RC_INST *inst)  inst_eval(struct eval_env *env, RC_INST *inst)
1160  {  {
# Line 1074  inst_eval(struct eval_env *env, RC_INST Line 1172  inst_eval(struct eval_env *env, RC_INST
1172                    
1173          switch (inst->opcode) {          switch (inst->opcode) {
1174          case inst_stop:          case inst_stop:
1175                    trace(&env->loc, _("STOP"));
1176                  longjmp(env->jmp, 1);                  longjmp(env->jmp, 1);
1177                  break;                  break;
1178    
1179          case inst_call:          case inst_call:
1180                    trace(&env->loc, _("Calling %s"), inst->arg);
1181                  rcfile_call_section(env->method, inst->arg,                  rcfile_call_section(env->method, inst->arg,
1182                                      env->data, env->msg);                                      env->data, env->msg);
1183                  break;                  break;
1184                                    
1185          case inst_add:          case inst_add:
1186                  if (inst->part == BODY)                  trace(&env->loc, _("ADD %s [%s] %s"),
1187                          (inst->part == BODY) ? "BODY" : "HEADER",
1188                          VALID_STR(inst->key2), arg);
1189                    if (inst->part == BODY)
1190                          message_add_body(env->msg, inst->key2, arg);                          message_add_body(env->msg, inst->key2, arg);
1191                  else                  else
1192                          message_add_header(env->msg, inst->key2, arg);                          message_add_header(env->msg, inst->key2, arg);
1193                  break;                  break;
1194                                    
1195          case inst_modify:          case inst_modify:
1196                    trace(&env->loc, _("MODIFY %s [%s] [%s] %s"),
1197                          (inst->part == BODY) ? "BODY" : "HEADER",
1198                          anubis_regex_source(inst->key),
1199                          VALID_STR(inst->key2), arg);
1200                    
1201                  if (inst->part == BODY)                  if (inst->part == BODY)
1202                          message_modify_body(env->msg, inst->key, arg);                          message_modify_body(env->msg, inst->key, arg);
1203                  else                  else
# Line 1098  inst_eval(struct eval_env *env, RC_INST Line 1206  inst_eval(struct eval_env *env, RC_INST
1206                  break;                  break;
1207                                    
1208          case inst_remove:          case inst_remove:
1209                    trace(&env->loc, _("REMOVE HEADER [%s]"),
1210                          anubis_regex_source(inst->key));
1211                  message_remove_headers(env->msg, inst->key);                  message_remove_headers(env->msg, inst->key);
1212                  break;                  break;
1213                                    
# Line 1118  asgn_eval(struct eval_env *env, RC_ASGN Line 1228  asgn_eval(struct eval_env *env, RC_ASGN
1228          if (!p)          if (!p)
1229                  return;                  return;
1230    
1231            trace(&env->loc, _("executing %s"), asgn->lhs);
1232          if (env->refstr) {          if (env->refstr) {
1233                  char *s;                  char *s;
1234                  LIST *arg = list_create();                  LIST *arg = list_create();
# Line 1186  expr_eval(struct eval_env *env, RC_EXPR Line 1297  expr_eval(struct eval_env *env, RC_EXPR
1297          default:          default:
1298                  abort();                  abort();
1299          }          }
1300            if (rc)
1301                    trace(&env->loc, _("Matched condition %s[%s] \"%s\""),
1302                          part_string(expr->part),
1303                          VALID_STR(expr->key),
1304                          anubis_regex_source(expr->re));
1305          return rc;          return rc;
1306  }  }
1307    
# Line 1194  node_eval(struct eval_env *env, RC_NODE Line 1310  node_eval(struct eval_env *env, RC_NODE
1310  {  {
1311          int rc; /* It won't be used uninitialized despite what cc says.          int rc; /* It won't be used uninitialized despite what cc says.
1312                     Note default: branch below */                     Note default: branch below */
1313            
1314            env->loc = node->loc;
1315          switch (node->type) {          switch (node->type) {
1316          case rc_node_bool:          case rc_node_bool:
1317                  rc = bool_eval(env, &node->v.bool);                  rc = bool_eval(env, &node->v.bool);
1318                  break;                  break;
1319                    
1320          case rc_node_expr:          case rc_node_expr:
1321                  rc = expr_eval(env, &node->v.expr);                  rc = expr_eval(env, &node->v.expr);
1322                  break;                  break;
# Line 1206  node_eval(struct eval_env *env, RC_NODE Line 1324  node_eval(struct eval_env *env, RC_NODE
1324          default:          default:
1325                  abort();                  abort();
1326          }          }
1327    
1328          return rc;          return rc;
1329  }  }
1330    
# Line 1250  rule_eval(struct eval_env *env, RC_RULE Line 1369  rule_eval(struct eval_env *env, RC_RULE
1369  void  void
1370  stmt_list_eval(struct eval_env *env, RC_STMT *stmt)  stmt_list_eval(struct eval_env *env, RC_STMT *stmt)
1371  {  {
1372          for (; stmt; stmt = stmt->next)          for (; stmt; stmt = stmt->next) {
1373                    env->loc = stmt->loc;
1374    
1375                  switch (stmt->type) {                  switch (stmt->type) {
1376                  case rc_stmt_asgn:                  case rc_stmt_asgn:
1377                          asgn_eval(env, &stmt->v.asgn);                          asgn_eval(env, &stmt->v.asgn);
# Line 1267  stmt_list_eval(struct eval_env *env, RC_ Line 1388  stmt_list_eval(struct eval_env *env, RC_
1388                  case rc_stmt_inst:                  case rc_stmt_inst:
1389                          inst_eval(env, &stmt->v.inst);                          inst_eval(env, &stmt->v.inst);
1390                  }                  }
1391            }
1392  }  }
1393    
1394  void  void
# Line 1280  eval_section(int method, RC_SECTION *sec Line 1402  eval_section(int method, RC_SECTION *sec
1402          env.refstr = NULL;          env.refstr = NULL;
1403          env.msg = msg;          env.msg = msg;
1404          env.data = data;          env.data = data;
1405            env.loc = sec->loc;
1406            
1407            trace(&sec->loc, "section %s", sec->name);
1408                    
1409          if (setjmp(env.jmp) == 0)          if (setjmp(env.jmp) == 0)
1410                  stmt_list_eval(&env, sec->stmt);                  stmt_list_eval(&env, sec->stmt);
# Line 1345  is_prog_allowed() Line 1470  is_prog_allowed()
1470                  parse_error(_("program is not allowed in this section"));                  parse_error(_("program is not allowed in this section"));
1471          return p->allow_prog;          return p->allow_prog;
1472  }  }
1473    

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

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