Diff for /embedaddon/bird/conf/cf-lex.l between versions 1.1 and 1.1.1.2

version 1.1, 2017/08/22 12:33:54 version 1.1.1.2, 2021/03/17 19:50:23
Line 48 Line 48
 #include "conf/conf.h"  #include "conf/conf.h"
 #include "conf/cf-parse.tab.h"  #include "conf/cf-parse.tab.h"
 #include "lib/string.h"  #include "lib/string.h"
   #include "lib/hash.h"
   
 struct keyword {  struct keyword {
   byte *name;    byte *name;
Line 57  struct keyword { Line 58  struct keyword {
   
 #include "conf/keywords.h"  #include "conf/keywords.h"
   
#define KW_HASH_SIZE 64/* Could be defined by Bison in cf-parse.tab.h, inteferes with SYM hash */
static struct keyword *kw_hash[KW_HASH_SIZE];#ifdef SYM
static int kw_hash_inited;#undef SYM
 #endif
   
 #define SYM_HASH_SIZE 128  
   
struct sym_scope {static uint cf_hash(byte *c);
  struct sym_scope *next;               /* Next on scope stack */ 
  struct symbol *name;                  /* Name of this scope */ 
  int active;                           /* Currently entered */ 
}; 
static struct sym_scope *conf_this_scope; 
   
static int cf_hash(byte *c);#define KW_KEY(n)               n->name
static inline struct symbol * cf_get_sym(byte *c, uint h0);#define KW_NEXT(n)              n->next
 #define KW_EQ(a,b)              !strcmp(a,b)
 #define KW_FN(k)                cf_hash(k)
 #define KW_ORDER                8 /* Fixed */
   
   #define SYM_KEY(n)              n->name, n->scope->active
   #define SYM_NEXT(n)             n->next
   #define SYM_EQ(a,s1,b,s2)       !strcmp(a,b) && s1 == s2
   #define SYM_FN(k,s)             cf_hash(k)
   #define SYM_ORDER               6 /* Initial */
   
   #define SYM_REHASH              sym_rehash
   #define SYM_PARAMS              /8, *1, 2, 2, 6, 20
   
   
   HASH_DEFINE_REHASH_FN(SYM, struct symbol)
   
   HASH(struct keyword) kw_hash;
   
   
   static struct sym_scope *conf_this_scope;
   
 linpool *cfg_mem;  linpool *cfg_mem;
   
 int (*cf_read_hook)(byte *buf, unsigned int max, int fd);  int (*cf_read_hook)(byte *buf, unsigned int max, int fd);
Line 84  static struct include_file_stack *ifs_head; Line 100  static struct include_file_stack *ifs_head;
 #define YY_INPUT(buf,result,max) result = cf_read_hook(buf, max, ifs->fd);  #define YY_INPUT(buf,result,max) result = cf_read_hook(buf, max, ifs->fd);
 #define YY_NO_UNPUT  #define YY_NO_UNPUT
 #define YY_FATAL_ERROR(msg) cf_error(msg)  #define YY_FATAL_ERROR(msg) cf_error(msg)
   #define YY_USER_ACTION ifs->chno += yyleng; ifs->toklen = yyleng;
   
 static void cf_include(char *arg, int alen);  static void cf_include(char *arg, int alen);
 static int check_eof(void);  static int check_eof(void);
Line 179  else: { Line 196  else: {
     yytext[yyleng-1] = 0;      yytext[yyleng-1] = 0;
     yytext++;      yytext++;
   }    }
  unsigned int h = cf_hash(yytext);
  struct keyword *k = kw_hash[h & (KW_HASH_SIZE-1)];  struct keyword *k = HASH_FIND(kw_hash, KW, yytext);
  while (k)  if (k)
   {
     if (k->value > 0)
       return k->value;
     else
     {      {
      if (!strcmp(k->name, yytext))      cf_lval.i = -k->value;
        {      return ENUM;
          if (k->value > 0) 
            return k->value; 
          else 
            { 
              cf_lval.i = -k->value; 
              return ENUM; 
            } 
        } 
      k=k->next; 
     }      }
  cf_lval.s = cf_get_sym(yytext, h);  }
 
   cf_lval.s = cf_get_symbol(yytext);
   return SYM;    return SYM;
 }  }
   
Line 224  else: { Line 238  else: {
   
 {WHITE}+  {WHITE}+
   
\n      ifs->lino++;\n      ifs->lino++; ifs->chno = 0;
   
 #       BEGIN(COMMENT);  #       BEGIN(COMMENT);
   
Line 234  else: { Line 248  else: {
   
 <COMMENT>\n {  <COMMENT>\n {
   ifs->lino++;    ifs->lino++;
     ifs->chno = 0;
   BEGIN(INITIAL);    BEGIN(INITIAL);
 }  }
   
 <COMMENT>.  <COMMENT>.
   
 <CCOMM>\*\/     BEGIN(INITIAL);  <CCOMM>\*\/     BEGIN(INITIAL);
<CCOMM>\n       ifs->lino++;<CCOMM>\n       ifs->lino++; ifs->chno = 0;
 <CCOMM>\/\*     cf_error("Comment nesting not supported");  <CCOMM>\/\*     cf_error("Comment nesting not supported");
 <CCOMM><<EOF>>  cf_error("Unterminated comment");  <CCOMM><<EOF>>  cf_error("Unterminated comment");
 <CCOMM>.  <CCOMM>.
Line 257  else: { Line 272  else: {
   
 %%  %%
   
static intstatic uint
 cf_hash(byte *c)  cf_hash(byte *c)
 {  {
  unsigned int h = 13;  uint h = 13 << 24;
   
   while (*c)    while (*c)
    h = (h * 37) + *c++;    h = h + (h >> 2) + (h >> 5) + ((uint) *c++ << 24);
   return h;    return h;
 }  }
   
Line 428  check_eof(void) Line 443  check_eof(void)
 }  }
   
 static struct symbol *  static struct symbol *
cf_new_sym(byte *c, uint h0)cf_new_symbol(byte *c)
 {  {
  uint h = h0 & (SYM_HASH_SIZE-1);  struct symbol *s;
  struct symbol *s, **ht; 
  int l; 
   
  if (!new_config->sym_hash)  uint l = strlen(c);
    new_config->sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *)); 
  ht = new_config->sym_hash; 
  l = strlen(c); 
   if (l > SYM_MAX_LEN)    if (l > SYM_MAX_LEN)
     cf_error("Symbol too long");      cf_error("Symbol too long");
   
   s = cfg_alloc(sizeof(struct symbol) + l);    s = cfg_alloc(sizeof(struct symbol) + l);
   s->next = ht[h];  
   ht[h] = s;  
   s->scope = conf_this_scope;    s->scope = conf_this_scope;
   s->class = SYM_VOID;    s->class = SYM_VOID;
   s->def = NULL;    s->def = NULL;
   s->aux = 0;    s->aux = 0;
   strcpy(s->name, c);    strcpy(s->name, c);
   return s;  
 }  
   
static struct symbol *  if (!new_config->sym_hash.data)
cf_find_sym(struct config *cfg, byte *c, uint h0)    HASH_INIT(new_config->sym_hash, new_config->pool, SYM_ORDER);
{ 
  uint h = h0 & (SYM_HASH_SIZE-1); 
  struct symbol *s, **ht; 
   
  if (ht = cfg->sym_hash)  HASH_INSERT2(new_config->sym_hash, SYM, new_config->pool, s);
    { 
      for(s = ht[h]; s; s=s->next) 
        if (!strcmp(s->name, c) && s->scope->active) 
          return s; 
    } 
  if (ht = cfg->sym_fallback) 
    { 
      /* We know only top-level scope is active */ 
      for(s = ht[h]; s; s=s->next) 
        if (!strcmp(s->name, c) && s->scope->active) 
          return s; 
    } 
   
  return NULL;  return s;
 }  }
   
 static inline struct symbol *  
 cf_get_sym(byte *c, uint h0)  
 {  
   return cf_find_sym(new_config, c, h0) ?: cf_new_sym(c, h0);  
 }  
   
 /**  /**
  * cf_find_symbol - find a symbol by name   * cf_find_symbol - find a symbol by name
  * @cfg: specificed config   * @cfg: specificed config
Line 494  cf_get_sym(byte *c, uint h0) Line 480  cf_get_sym(byte *c, uint h0)
 struct symbol *  struct symbol *
 cf_find_symbol(struct config *cfg, byte *c)  cf_find_symbol(struct config *cfg, byte *c)
 {  {
  return cf_find_sym(cfg, c, cf_hash(c));  struct symbol *s;
 
   if (cfg->sym_hash.data &&
       (s = HASH_FIND(cfg->sym_hash, SYM, c, 1)))
     return s;
 
   if (cfg->fallback &&
       cfg->fallback->sym_hash.data &&
       (s = HASH_FIND(cfg->fallback->sym_hash, SYM, c, 1)))
     return s;
 
   return NULL;
 }  }
   
 /**  /**
Line 509  cf_find_symbol(struct config *cfg, byte *c) Line 506  cf_find_symbol(struct config *cfg, byte *c)
 struct symbol *  struct symbol *
 cf_get_symbol(byte *c)  cf_get_symbol(byte *c)
 {  {
  return cf_get_sym(c, cf_hash(c));  return cf_find_symbol(new_config, c) ?: cf_new_symbol(c);
 }  }
   
 struct symbol *  struct symbol *
Line 522  cf_default_name(char *template, int *counter) Line 519  cf_default_name(char *template, int *counter)
   for(;;)    for(;;)
     {      {
       bsprintf(buf, template, ++(*counter));        bsprintf(buf, template, ++(*counter));
      s = cf_get_sym(buf, cf_hash(buf));      s = cf_get_symbol(buf);
       if (s->class == SYM_VOID)        if (s->class == SYM_VOID)
         return s;          return s;
       if (!perc)        if (!perc)
Line 553  cf_define_symbol(struct symbol *sym, int type, void *d Line 550  cf_define_symbol(struct symbol *sym, int type, void *d
     {      {
       if (sym->scope == conf_this_scope)        if (sym->scope == conf_this_scope)
         cf_error("Symbol already defined");          cf_error("Symbol already defined");
      sym = cf_new_sym(sym->name, cf_hash(sym->name));      sym = cf_new_symbol(sym->name);
     }      }
   sym->class = type;    sym->class = type;
   sym->def = def;    sym->def = def;
Line 563  cf_define_symbol(struct symbol *sym, int type, void *d Line 560  cf_define_symbol(struct symbol *sym, int type, void *d
 static void  static void
 cf_lex_init_kh(void)  cf_lex_init_kh(void)
 {  {
  struct keyword *k;  HASH_INIT(kw_hash, &root_pool, KW_ORDER);
   
  for(k=keyword_list; k->name; k++)  struct keyword *k;
    {  for (k=keyword_list; k->name; k++)
      unsigned h = cf_hash(k->name) & (KW_HASH_SIZE-1);    HASH_INSERT(kw_hash, KW, k);
      k->next = kw_hash[h]; 
      kw_hash[h] = k; 
    } 
  kw_hash_inited = 1; 
 }  }
   
 /**  /**
Line 585  cf_lex_init_kh(void) Line 578  cf_lex_init_kh(void)
 void  void
 cf_lex_init(int is_cli, struct config *c)  cf_lex_init(int is_cli, struct config *c)
 {  {
  if (!kw_hash_inited)  if (!kw_hash.data)
     cf_lex_init_kh();      cf_lex_init_kh();
   
   ifs_head = ifs = push_ifs(NULL);    ifs_head = ifs = push_ifs(NULL);
Line 642  cf_pop_scope(void) Line 635  cf_pop_scope(void)
   conf_this_scope->active = 0;    conf_this_scope->active = 0;
   conf_this_scope = conf_this_scope->next;    conf_this_scope = conf_this_scope->next;
   ASSERT(conf_this_scope);    ASSERT(conf_this_scope);
 }  
   
 struct symbol *  
 cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos)  
 {  
   for(;;)  
     {  
       if (!sym)  
         {  
           if (*pos >= SYM_HASH_SIZE)  
             return NULL;  
           sym = cf->sym_hash[(*pos)++];  
         }  
       else  
         sym = sym->next;  
       if (sym && sym->scope->active)  
         return sym;  
     }  
 }  }
   
 /**  /**

Removed from v.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>