Commit a109ef6b authored by Jan Moskyto Matejka's avatar Jan Moskyto Matejka
Browse files

Merge branch 'int-new' into bash-completion

parents b12daceb 801fd81e
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ struct cmd_node {

static struct cmd_node cmd_root;

#define isspace_(X) isspace((unsigned char) (X))

void
cmd_build_tree(void)
{
@@ -61,7 +63,7 @@ cmd_build_tree(void)
      while (*c)
	{
	  char *d = c;
	  while (*c && !isspace(*c))
	  while (*c && !isspace_(*c))
	    c++;
	  for(new=old->son; new; new=new->sibling)
	    if (new->len == c-d && !memcmp(new->token, d, c-d))
@@ -79,7 +81,7 @@ cmd_build_tree(void)
	      new->prio = (new->len == 3 && (!memcmp(new->token, "roa", 3) || !memcmp(new->token, "rip", 3))) ? 0 : 1; /* Hack */
	    }
	  old = new;
	  while (isspace(*c))
	  while (isspace_(*c))
	    c++;
	}
      if (cmd->is_real_cmd)
@@ -170,13 +172,13 @@ cmd_help(const char *cmd, int len)
  n = &cmd_root;
  while (cmd < end)
    {
      if (isspace(*cmd))
      if (isspace_(*cmd))
	{
	  cmd++;
	  continue;
	}
      z = cmd;
      while (cmd < end && !isspace(*cmd))
      while (cmd < end && !isspace_(*cmd))
	cmd++;
      m = cmd_find_abbrev(n, z, cmd-z, &ambig);
      if (ambig)
@@ -283,20 +285,20 @@ cmd_complete(const char *cmd, int len, char *buf, int again)
  int ambig, cnt = 0, common;

  /* Find the last word we want to complete */
  for(fin=end; fin > start && !isspace(fin[-1]); fin--)
  for(fin=end; fin > start && !isspace_(fin[-1]); fin--)
    ;

  /* Find the context */
  n = &cmd_root;
  while (cmd < fin)
    {
      if (isspace(*cmd))
      if (isspace_(*cmd))
	{
	  cmd++;
	  continue;
	}
      z = cmd;
      while (cmd < fin && !isspace(*cmd))
      while (cmd < fin && !isspace_(*cmd))
	cmd++;
      m = cmd_find_abbrev(n, z, cmd-z, &ambig);
      if (ambig)
@@ -382,13 +384,13 @@ cmd_expand(char *cmd)
  n = &cmd_root;
  while (*c)
    {
      if (isspace(*c))
      if (isspace_(*c))
	{
	  c++;
	  continue;
	}
      b = c;
      while (*c && !isspace(*c))
      while (*c && !isspace_(*c))
	c++;
      m = cmd_find_abbrev(n, b, c-b, &ambig);
      if (!m)
+76 −101
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#include "conf/conf.h"
#include "conf/cf-parse.tab.h"
#include "lib/string.h"
#include "lib/hash.h"

struct keyword {
  byte *name;
@@ -57,21 +58,36 @@ struct keyword {

#include "conf/keywords.h"

#define KW_HASH_SIZE 64
static struct keyword *kw_hash[KW_HASH_SIZE];
static int kw_hash_inited;
/* Could be defined by Bison in cf-parse.tab.h, inteferes with SYM hash */
#ifdef SYM
#undef SYM
#endif

#define SYM_HASH_SIZE 128

struct sym_scope {
  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 uint cf_hash(byte *c);

#define KW_KEY(n)		n->name
#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)

static int cf_hash(byte *c);
static inline struct symbol * cf_get_sym(byte *c, uint h0);
HASH(struct keyword) kw_hash;


static struct sym_scope *conf_this_scope;

linpool *cfg_mem;

@@ -124,7 +140,8 @@ include ^{WHITE}*include{WHITE}*\".*\"{WHITE}*;
}

{DIGIT}+:{DIGIT}+ {
  unsigned long int l, len1 UNUSED, len2;
  uint len1 UNUSED, len2;
  u64 l;
  char *e;

  errno = 0;
@@ -155,7 +172,8 @@ include ^{WHITE}*include{WHITE}*\".*\"{WHITE}*;
}

[02]:{DIGIT}+:{DIGIT}+ {
  unsigned long int l, len1, len2;
  uint len1, len2;
  u64 l;
  char *e;

  if (yytext[0] == '0')
@@ -252,11 +270,9 @@ else: {
    yytext[yyleng-1] = 0;
    yytext++;
  }
  unsigned int h = cf_hash(yytext);
  struct keyword *k = kw_hash[h & (KW_HASH_SIZE-1)];
  while (k)
    {
      if (!strcmp(k->name, yytext))

  struct keyword *k = HASH_FIND(kw_hash, KW, yytext);
  if (k)
  {
    if (k->value > 0)
      return k->value;
@@ -266,9 +282,8 @@ else: {
      return ENUM;
    }
  }
      k=k->next;
    }
  cf_lval.s = cf_get_sym(yytext, h);

  cf_lval.s = cf_get_symbol(yytext);
  return SYM;
}

@@ -331,13 +346,13 @@ else: {

%%

static int
static uint
cf_hash(byte *c)
{
  unsigned int h = 13;
  uint h = 13 << 24;

  while (*c)
    h = (h * 37) + *c++;
    h = h + (h >> 2) + (h >> 5) + ((uint) *c++ << 24);
  return h;
}

@@ -502,56 +517,27 @@ check_eof(void)
}

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, **ht;
  int l;
  struct symbol *s;

  if (!new_config->sym_hash)
    new_config->sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *));
  ht = new_config->sym_hash;
  l = strlen(c);
  uint l = strlen(c);
  if (l > SYM_MAX_LEN)
    cf_error("Symbol too long");

  s = cfg_alloc(sizeof(struct symbol) + l);
  s->next = ht[h];
  ht[h] = s;
  s->scope = conf_this_scope;
  s->class = SYM_VOID;
  s->def = NULL;
  s->aux = 0;
  strcpy(s->name, c);
  return s;
}

static struct symbol *
cf_find_sym(struct config *cfg, byte *c, uint h0)
{
  uint h = h0 & (SYM_HASH_SIZE-1);
  struct symbol *s, **ht;
  if (!new_config->sym_hash.data)
    HASH_INIT(new_config->sym_hash, new_config->pool, SYM_ORDER);

  if (ht = cfg->sym_hash)
    {
      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;
    }
  HASH_INSERT2(new_config->sym_hash, SYM, new_config->pool, s);

  return NULL;
}

static inline struct symbol *
cf_get_sym(byte *c, uint h0)
{
  return cf_find_sym(new_config, c, h0) ?: cf_new_sym(c, h0);
  return s;
}

/**
@@ -568,7 +554,18 @@ cf_get_sym(byte *c, uint h0)
struct symbol *
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;
}

/**
@@ -583,7 +580,7 @@ cf_find_symbol(struct config *cfg, byte *c)
struct symbol *
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 *
@@ -596,7 +593,7 @@ cf_default_name(char *template, int *counter)
  for(;;)
    {
      bsprintf(buf, template, ++(*counter));
      s = cf_get_sym(buf, cf_hash(buf));
      s = cf_get_symbol(buf);
      if (s->class == SYM_VOID)
	return s;
      if (!perc)
@@ -627,7 +624,7 @@ cf_define_symbol(struct symbol *sym, int type, void *def)
    {
      if (sym->scope == conf_this_scope)
	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->def = def;
@@ -637,15 +634,11 @@ cf_define_symbol(struct symbol *sym, int type, void *def)
static void
cf_lex_init_kh(void)
{
  struct keyword *k;
  HASH_INIT(kw_hash, &root_pool, KW_ORDER);

  struct keyword *k;
  for (k=keyword_list; k->name; k++)
    {
      unsigned h = cf_hash(k->name) & (KW_HASH_SIZE-1);
      k->next = kw_hash[h];
      kw_hash[h] = k;
    }
  kw_hash_inited = 1;
    HASH_INSERT(kw_hash, KW, k);
}

/**
@@ -659,7 +652,7 @@ cf_lex_init_kh(void)
void
cf_lex_init(int is_cli, struct config *c)
{
  if (!kw_hash_inited)
  if (!kw_hash.data)
    cf_lex_init_kh();

  ifs_head = ifs = push_ifs(NULL);
@@ -718,24 +711,6 @@ cf_pop_scope(void)
  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;
    }
}

/**
 * cf_symbol_class_name - get name of a symbol class
 * @sym: symbol
+2 −2
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ int
cli_parse(struct config *c)
{
  int done = 0;
  c->sym_fallback = config->sym_hash;
  c->fallback = config;
  new_config = c;
  cfg_mem = c->mem;
  if (setjmp(conf_jmpbuf))
@@ -177,7 +177,7 @@ cli_parse(struct config *c)
  done = 1;

cleanup:
  c->sym_fallback = NULL;
  c->fallback = NULL;
  new_config = NULL;
  cfg_mem = NULL;
  return done;
+9 −3
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@

#include "sysdep/config.h"
#include "lib/ip.h"
#include "lib/hash.h"
#include "lib/resource.h"
#include "sysdep/unix/timer.h"

@@ -52,8 +53,8 @@ struct config {
  char *err_file_name;			/* File name containing error */
  char *file_name;			/* Name of main configuration file */
  int file_fd;				/* File descriptor of main configuration file */
  struct symbol **sym_hash;		/* Lexer: symbol hash table */
  struct symbol **sym_fallback;		/* Lexer: fallback symbol hash table */
  HASH(struct symbol) sym_hash;		/* Lexer: symbol hash table */
  struct config *fallback;		/* Link to regular config for CLI parsing */
  int obstacle_count;			/* Number of items blocking freeing of this config */
  int shutdown;				/* This is a pseudo-config for daemon shutdown */
  bird_clock_t load_time;		/* When we've got this configuration */
@@ -114,6 +115,12 @@ struct symbol {
  char name[1];
};

struct sym_scope {
  struct sym_scope *next;		/* Next on scope stack */
  struct symbol *name;			/* Name of this scope */
  int active;				/* Currently entered */
};

#define SYM_MAX_LEN 64

/* Remember to update cf_symbol_class_name() */
@@ -155,7 +162,6 @@ struct symbol *cf_default_name(char *template, int *counter);
struct symbol *cf_define_symbol(struct symbol *symbol, int type, void *def);
void cf_push_scope(struct symbol *);
void cf_pop_scope(void);
struct symbol *cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos);
char *cf_symbol_class_name(struct symbol *sym);

static inline int cf_symbol_is_constant(struct symbol *sym)
+21 −14
Original line number Diff line number Diff line
@@ -27,16 +27,16 @@ CF_HDR
CF_DEFINES

static void
check_u16(unsigned val)
check_u16(uint val)
{
  if (val > 0xFFFF)
    cf_error("Value %d out of range (0-65535)", val);
    cf_error("Value %u out of range (0-65535)", val);
}

CF_DECLS

%union {
  int i;
  uint i;
  u32 i32;
  u64 i64;
  ip_addr a;
@@ -175,7 +175,7 @@ ipa_scope:

pxlen4:
   '/' NUM {
     if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
     if ($2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %u", $2);
     $$ = $2;
   }
 | ':' IP4 {
@@ -187,17 +187,24 @@ pxlen4:
net_ip4_: IP4 pxlen4
{
  net_fill_ip4(&($$), $1, $2);
  if (!net_validate_ip4((net_addr_ip4 *) &($$)))
    cf_error("Invalid IPv4 prefix");

  net_addr_ip4 *n = (void *) &($$);
  if (!net_validate_ip4(n))
    cf_error("Invalid IPv4 prefix %I4/%d, maybe you wanted %I4/%d",
	     n->prefix, n->pxlen, ip4_and(n->prefix, ip4_mkmask(n->pxlen)), n->pxlen);
};

net_ip6_: IP6 '/' NUM
{
  if ($3 > IP6_MAX_PREFIX_LENGTH)
    cf_error("Invalid prefix length %u", $3);

  net_fill_ip6(&($$), $1, $3);
  if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH)
    cf_error("Invalid prefix length %d", $3);
  if (!net_validate_ip6((net_addr_ip6 *) &($$)))
    cf_error("Invalid IPv6 prefix");

  net_addr_ip6 *n = (void *) &($$);
  if (!net_validate_ip6(n))
    cf_error("Invalid IPv6 prefix %I6/%d, maybe you wanted %I6/%d",
	     n->prefix, n->pxlen, ip6_and(n->prefix, ip6_mkmask(n->pxlen)), n->pxlen);
};

net_vpn4_: VPN_RD net_ip4_
@@ -216,16 +223,16 @@ net_roa4_: net_ip4_ MAX NUM AS NUM
{
  $$ = cfg_alloc(sizeof(net_addr_roa4));
  net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5);
  if ($3 < (int) net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH)
    cf_error("Invalid max prefix length %d", $3);
  if ($3 < net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH)
    cf_error("Invalid max prefix length %u", $3);
};

net_roa6_: net_ip6_ MAX NUM AS NUM
{
  $$ = cfg_alloc(sizeof(net_addr_roa6));
  net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5);
  if ($3 < (int) net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH)
    cf_error("Invalid max prefix length %d", $3);
  if ($3 < net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH)
    cf_error("Invalid max prefix length %u", $3);
};

net_ip_: net_ip4_ | net_ip6_ ;
Loading