1998-11-27 19:35:10 +00:00
|
|
|
/*
|
|
|
|
* BIRD Internet Routing Daemon -- Configuration File Handling
|
|
|
|
*
|
2000-01-16 16:44:50 +00:00
|
|
|
* (c) 1998--2000 Martin Mares <mj@ucw.cz>
|
1998-11-27 19:35:10 +00:00
|
|
|
*
|
|
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _BIRD_CONF_H_
|
|
|
|
#define _BIRD_CONF_H_
|
|
|
|
|
2016-11-09 15:36:34 +00:00
|
|
|
#include "sysdep/config.h"
|
|
|
|
#include "lib/ip.h"
|
2017-05-25 21:30:39 +00:00
|
|
|
#include "lib/hash.h"
|
1998-11-27 19:35:10 +00:00
|
|
|
#include "lib/resource.h"
|
2017-11-28 16:43:20 +00:00
|
|
|
#include "lib/timer.h"
|
1998-11-27 19:35:10 +00:00
|
|
|
|
1999-02-05 21:37:34 +00:00
|
|
|
/* Configuration structure */
|
|
|
|
struct config {
|
|
|
|
pool *pool; /* Pool the configuration is stored in */
|
|
|
|
linpool *mem; /* Linear pool containing configuration data */
|
|
|
|
list protos; /* Configured protocol instances (struct proto_config) */
|
1999-05-17 20:06:19 +00:00
|
|
|
list tables; /* Configured routing tables (struct rtable_config) */
|
2022-09-14 23:38:18 +00:00
|
|
|
list mpls_domains; /* Configured MPLS domains (struct mpls_domain_config) */
|
2016-11-08 16:46:29 +00:00
|
|
|
list logfiles; /* Configured log files (sysdep) */
|
2016-11-30 09:21:43 +00:00
|
|
|
list tests; /* Configured unit tests (f_bt_test_suite) */
|
2019-02-26 15:44:24 +00:00
|
|
|
list symbols; /* Configured symbols in config order */
|
2012-03-18 16:32:30 +00:00
|
|
|
|
2023-08-21 16:44:10 +00:00
|
|
|
struct rfile *mrtdump_file; /* Configured MRTDump file */
|
2020-04-08 20:25:15 +00:00
|
|
|
const char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
|
2022-09-01 12:21:56 +00:00
|
|
|
struct symbol *def_tables[NET_MAX]; /* Default routing tables for each network */
|
2012-12-27 11:56:23 +00:00
|
|
|
struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */
|
2010-01-03 11:17:52 +00:00
|
|
|
|
1999-02-05 21:37:34 +00:00
|
|
|
u32 router_id; /* Our Router ID */
|
2020-12-07 21:19:40 +00:00
|
|
|
u32 proto_default_debug; /* Default protocol debug mask */
|
|
|
|
u32 proto_default_mrtdump; /* Default protocol mrtdump mask */
|
|
|
|
u32 channel_default_debug; /* Default channel debug mask */
|
2021-08-25 20:20:48 +00:00
|
|
|
u16 filter_vstk, filter_estk; /* Filter stack depth */
|
2010-02-02 23:19:24 +00:00
|
|
|
struct timeformat tf_route; /* Time format for 'show route' */
|
|
|
|
struct timeformat tf_proto; /* Time format for 'show protocol' */
|
|
|
|
struct timeformat tf_log; /* Time format for the logfile */
|
|
|
|
struct timeformat tf_base; /* Time format for other purposes */
|
2017-06-21 12:43:49 +00:00
|
|
|
u32 gr_wait; /* Graceful restart wait timeout (sec) */
|
2021-02-10 15:53:57 +00:00
|
|
|
const char *hostname; /* Hostname */
|
2010-02-02 23:19:24 +00:00
|
|
|
|
2000-05-29 22:10:18 +00:00
|
|
|
int cli_debug; /* Tracing of CLI connections and commands */
|
2015-03-02 08:41:14 +00:00
|
|
|
int latency_debug; /* I/O loop tracks duration of each event */
|
2021-09-27 11:04:16 +00:00
|
|
|
int table_debug; /* Track route propagation through tables */
|
2015-03-02 08:41:14 +00:00
|
|
|
u32 latency_limit; /* Events with longer duration are logged (us) */
|
|
|
|
u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */
|
|
|
|
u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */
|
1999-02-05 21:37:34 +00:00
|
|
|
char *err_msg; /* Parser error message */
|
|
|
|
int err_lino; /* Line containing error */
|
2018-09-11 14:55:41 +00:00
|
|
|
int err_chno; /* Character where the parser stopped */
|
2011-09-11 19:21:47 +00:00
|
|
|
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 */
|
2023-01-19 09:49:47 +00:00
|
|
|
int thread_count; /* How many worker threads to prefork */
|
2022-05-02 18:29:03 +00:00
|
|
|
|
2019-04-08 15:05:07 +00:00
|
|
|
struct sym_scope *root_scope; /* Scope for root symbols */
|
2023-06-13 08:51:03 +00:00
|
|
|
struct sym_scope *current_scope; /* Current scope where we are actually in while parsing */
|
2023-10-29 14:42:46 +00:00
|
|
|
int allow_attributes; /* Allow attributes in the current state of configuration parsing */
|
2023-08-21 13:37:09 +00:00
|
|
|
_Atomic int obstacle_count; /* Number of items blocking freeing of this config */
|
|
|
|
event done_event; /* Called when obstacle_count reaches zero */
|
2000-01-16 17:40:26 +00:00
|
|
|
int shutdown; /* This is a pseudo-config for daemon shutdown */
|
2019-06-18 14:27:21 +00:00
|
|
|
int gr_down; /* This is a pseudo-config for graceful restart */
|
2017-06-06 14:47:30 +00:00
|
|
|
btime load_time; /* When we've got this configuration */
|
1999-02-05 21:37:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Please don't use these variables in protocols. Use proto_config->global instead. */
|
2000-01-16 16:44:50 +00:00
|
|
|
extern struct config *config; /* Currently active configuration */
|
2023-10-29 14:42:46 +00:00
|
|
|
extern _Thread_local struct config *new_config; /* Configuration being parsed */
|
2000-01-16 17:40:26 +00:00
|
|
|
|
2016-11-09 15:36:34 +00:00
|
|
|
struct config *config_alloc(const char *name);
|
1999-02-05 21:37:34 +00:00
|
|
|
int config_parse(struct config *);
|
Parse CLI commands. We use the same parser as for configuration files (because
we want to allow filter and similar complex constructs to be used in commands
and we should avoid code duplication), only with CLI_MARKER token prepended
before the whole input.
Defined macro CF_CLI(cmd, args, help) for defining CLI commands in .Y files.
The first argument specifies the command itself, the remaining two arguments
are copied to the help file (er, will be copied after the help file starts
to exist). This macro automatically creates a skeleton rule for the command,
you only need to append arguments as in:
CF_CLI(STEAL MONEY, <$>, [[Steal <$> US dollars or equivalent in any other currency]]): NUM {
cli_msg(0, "%d$ stolen", $3);
} ;
Also don't forget to reset lexer state between inputs.
1999-10-31 17:47:47 +00:00
|
|
|
int cli_parse(struct config *);
|
1999-02-05 21:37:34 +00:00
|
|
|
void config_free(struct config *);
|
2022-11-09 20:09:16 +00:00
|
|
|
void config_free_old(void);
|
2017-06-21 12:43:49 +00:00
|
|
|
int config_commit(struct config *, int type, uint timeout);
|
2012-12-26 11:40:48 +00:00
|
|
|
int config_confirm(void);
|
|
|
|
int config_undo(void);
|
2019-06-12 14:13:21 +00:00
|
|
|
int config_status(void);
|
|
|
|
btime config_timer_status(void);
|
2012-12-26 11:40:48 +00:00
|
|
|
void config_init(void);
|
2016-03-09 15:48:28 +00:00
|
|
|
void cf_error(const char *msg, ...) NORET;
|
2023-06-16 20:11:03 +00:00
|
|
|
#define cf_warn(msg, args...) log(L_WARN "%s:%d:%d: " msg, ifs->file_name, ifs->lino, ifs->chno - ifs->toklen + 1, ##args)
|
2000-01-16 16:44:50 +00:00
|
|
|
void config_add_obstacle(struct config *);
|
|
|
|
void config_del_obstacle(struct config *);
|
2019-06-18 14:27:21 +00:00
|
|
|
void order_shutdown(int gr);
|
2000-01-16 16:44:50 +00:00
|
|
|
|
2012-12-26 11:40:48 +00:00
|
|
|
#define RECONFIG_NONE 0
|
|
|
|
#define RECONFIG_HARD 1
|
|
|
|
#define RECONFIG_SOFT 2
|
|
|
|
#define RECONFIG_UNDO 3
|
|
|
|
|
|
|
|
#define CONF_DONE 0
|
|
|
|
#define CONF_PROGRESS 1
|
|
|
|
#define CONF_QUEUED 2
|
|
|
|
#define CONF_UNQUEUED 3
|
|
|
|
#define CONF_CONFIRM 4
|
|
|
|
#define CONF_SHUTDOWN -1
|
|
|
|
#define CONF_NOTHING -2
|
|
|
|
|
1999-02-05 21:37:34 +00:00
|
|
|
|
1998-11-29 21:59:37 +00:00
|
|
|
/* Pools */
|
2022-11-01 07:56:26 +00:00
|
|
|
extern pool *config_pool;
|
1998-12-06 11:59:18 +00:00
|
|
|
extern linpool *cfg_mem;
|
1998-11-27 19:35:10 +00:00
|
|
|
|
1998-12-06 11:59:18 +00:00
|
|
|
#define cfg_alloc(size) lp_alloc(cfg_mem, size)
|
|
|
|
#define cfg_allocu(size) lp_allocu(cfg_mem, size)
|
|
|
|
#define cfg_allocz(size) lp_allocz(cfg_mem, size)
|
2016-11-08 16:46:29 +00:00
|
|
|
char *cfg_strdup(const char *c);
|
2011-11-06 23:31:23 +00:00
|
|
|
void cfg_copy_list(list *dest, list *src, unsigned node_size);
|
1998-11-29 21:59:37 +00:00
|
|
|
|
1998-11-27 19:35:10 +00:00
|
|
|
/* Lexer */
|
|
|
|
|
2015-05-19 06:53:34 +00:00
|
|
|
extern int (*cf_read_hook)(byte *buf, uint max, int fd);
|
1998-11-27 19:35:10 +00:00
|
|
|
|
2023-09-14 15:24:09 +00:00
|
|
|
struct keyword {
|
|
|
|
byte *name;
|
|
|
|
int value;
|
|
|
|
};
|
|
|
|
|
1998-11-27 19:35:10 +00:00
|
|
|
struct symbol {
|
2019-02-26 15:44:24 +00:00
|
|
|
node n; /* In list of symbols in config */
|
1998-11-27 19:35:10 +00:00
|
|
|
struct symbol *next;
|
1999-11-04 13:51:52 +00:00
|
|
|
struct sym_scope *scope;
|
2019-02-15 12:53:17 +00:00
|
|
|
int class; /* SYM_* */
|
|
|
|
uint flags; /* SYM_FLAG_* */
|
|
|
|
|
|
|
|
union {
|
|
|
|
struct proto_config *proto; /* For SYM_PROTO and SYM_TEMPLATE */
|
|
|
|
const struct f_line *function; /* For SYM_FUNCTION */
|
|
|
|
const struct filter *filter; /* For SYM_FILTER */
|
|
|
|
struct rtable_config *table; /* For SYM_TABLE */
|
2022-03-19 15:23:42 +00:00
|
|
|
struct ea_class *attribute; /* For SYM_ATTRIBUTE */
|
2022-09-14 23:38:18 +00:00
|
|
|
struct mpls_domain_config *mpls_domain; /* For SYM_MPLS_DOMAIN */
|
|
|
|
struct mpls_range_config *mpls_range; /* For SYM_MPLS_RANGE */
|
2019-05-21 16:33:37 +00:00
|
|
|
struct f_val *val; /* For SYM_CONSTANT */
|
|
|
|
uint offset; /* For SYM_VARIABLE */
|
2023-06-09 10:49:19 +00:00
|
|
|
const struct keyword *keyword; /* For SYM_KEYWORD */
|
Filter: Methods rework
Methods can now be called as x.m(y), as long as x can have its type
inferred in config time. If used as a command, it modifies the object,
if used as a value, it keeps the original object intact.
Also functions add(x,y), delete(x,y), filter(x,y) and prepend(x,y) now
spit a warning and are considered deprecated.
It's also possible to call a method on a constant, see filter/test.conf
for examples like bgp_path = +empty+.prepend(1).
Inside instruction definitions (filter/f-inst.c), a METHOD_CONSTRUCTOR()
call is added, which registers the instruction as a method for the type
of its first argument. Each type has its own method symbol table and
filter parser switches between them based on the inferred type of the
object calling the method.
Also FI_CLIST_(ADD|DELETE|FILTER) instructions have been split to allow
for this method dispatch. With type inference, it's now possible.
2023-06-16 15:35:37 +00:00
|
|
|
const struct f_method *method; /* For SYM_METHOD */
|
2019-02-15 12:53:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
char name[0];
|
1998-11-27 19:35:10 +00:00
|
|
|
};
|
|
|
|
|
2017-05-25 21:30:39 +00:00
|
|
|
struct sym_scope {
|
|
|
|
struct sym_scope *next; /* Next on scope stack */
|
|
|
|
struct symbol *name; /* Name of this scope */
|
2022-05-02 18:29:03 +00:00
|
|
|
|
|
|
|
HASH(struct symbol) hash; /* Local symbol hash */
|
|
|
|
|
2019-06-25 14:18:06 +00:00
|
|
|
uint slots; /* Variable slots */
|
2022-03-06 15:37:30 +00:00
|
|
|
byte soft_scopes; /* Number of soft scopes above */
|
2023-06-13 09:09:41 +00:00
|
|
|
byte block:1; /* No independent stack frame */
|
|
|
|
byte readonly:1; /* Do not add new symbols */
|
2017-05-25 21:30:39 +00:00
|
|
|
};
|
|
|
|
|
2023-10-25 12:41:11 +00:00
|
|
|
void cf_enter_filters(void);
|
|
|
|
void cf_exit_filters(void);
|
2022-05-02 18:29:03 +00:00
|
|
|
|
Filter: Methods rework
Methods can now be called as x.m(y), as long as x can have its type
inferred in config time. If used as a command, it modifies the object,
if used as a value, it keeps the original object intact.
Also functions add(x,y), delete(x,y), filter(x,y) and prepend(x,y) now
spit a warning and are considered deprecated.
It's also possible to call a method on a constant, see filter/test.conf
for examples like bgp_path = +empty+.prepend(1).
Inside instruction definitions (filter/f-inst.c), a METHOD_CONSTRUCTOR()
call is added, which registers the instruction as a method for the type
of its first argument. Each type has its own method symbol table and
filter parser switches between them based on the inferred type of the
object calling the method.
Also FI_CLIST_(ADD|DELETE|FILTER) instructions have been split to allow
for this method dispatch. With type inference, it's now possible.
2023-06-16 15:35:37 +00:00
|
|
|
extern pool *global_root_scope_pool;
|
|
|
|
extern linpool *global_root_scope_linpool;
|
2022-05-02 18:29:03 +00:00
|
|
|
|
2021-04-14 19:39:43 +00:00
|
|
|
|
2015-02-21 11:42:31 +00:00
|
|
|
#define SYM_MAX_LEN 64
|
|
|
|
|
2000-06-03 16:56:00 +00:00
|
|
|
/* Remember to update cf_symbol_class_name() */
|
1998-11-27 19:35:10 +00:00
|
|
|
#define SYM_VOID 0
|
1998-11-27 21:07:02 +00:00
|
|
|
#define SYM_PROTO 1
|
2013-07-25 20:33:57 +00:00
|
|
|
#define SYM_TEMPLATE 2
|
1999-11-15 11:34:51 +00:00
|
|
|
#define SYM_FUNCTION 3
|
|
|
|
#define SYM_FILTER 4
|
|
|
|
#define SYM_TABLE 5
|
2018-11-21 19:37:11 +00:00
|
|
|
#define SYM_ATTRIBUTE 6
|
2023-06-09 10:49:19 +00:00
|
|
|
#define SYM_KEYWORD 7
|
Filter: Methods rework
Methods can now be called as x.m(y), as long as x can have its type
inferred in config time. If used as a command, it modifies the object,
if used as a value, it keeps the original object intact.
Also functions add(x,y), delete(x,y), filter(x,y) and prepend(x,y) now
spit a warning and are considered deprecated.
It's also possible to call a method on a constant, see filter/test.conf
for examples like bgp_path = +empty+.prepend(1).
Inside instruction definitions (filter/f-inst.c), a METHOD_CONSTRUCTOR()
call is added, which registers the instruction as a method for the type
of its first argument. Each type has its own method symbol table and
filter parser switches between them based on the inferred type of the
object calling the method.
Also FI_CLIST_(ADD|DELETE|FILTER) instructions have been split to allow
for this method dispatch. With type inference, it's now possible.
2023-06-16 15:35:37 +00:00
|
|
|
#define SYM_METHOD 8
|
2022-09-14 23:38:18 +00:00
|
|
|
#define SYM_MPLS_DOMAIN 9
|
|
|
|
#define SYM_MPLS_RANGE 10
|
1998-11-27 19:35:10 +00:00
|
|
|
|
1999-11-15 11:34:51 +00:00
|
|
|
#define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */
|
2018-11-21 19:37:11 +00:00
|
|
|
#define SYM_VARIABLE_RANGE SYM_VARIABLE ... (SYM_VARIABLE | 0xff)
|
2013-07-25 20:33:57 +00:00
|
|
|
#define SYM_CONSTANT 0x200 /* 0x200-0x2ff are variable types */
|
2018-11-21 19:37:11 +00:00
|
|
|
#define SYM_CONSTANT_RANGE SYM_CONSTANT ... (SYM_CONSTANT | 0xff)
|
2013-07-25 20:33:57 +00:00
|
|
|
|
2019-02-15 12:53:17 +00:00
|
|
|
#define SYM_TYPE(s) ((s)->val->type)
|
|
|
|
#define SYM_VAL(s) ((s)->val->val)
|
|
|
|
|
|
|
|
/* Symbol flags */
|
|
|
|
#define SYM_FLAG_SAME 0x1 /* For SYM_FUNCTION and SYM_FILTER */
|
1999-03-29 20:21:28 +00:00
|
|
|
|
2011-09-11 19:21:47 +00:00
|
|
|
struct include_file_stack {
|
2012-07-18 17:29:33 +00:00
|
|
|
void *buffer; /* Internal lexer state */
|
|
|
|
char *file_name; /* File name */
|
|
|
|
int fd; /* File descriptor */
|
|
|
|
int lino; /* Current line num */
|
2018-09-11 14:55:41 +00:00
|
|
|
int chno; /* Current char num (on current line) */
|
|
|
|
int toklen; /* Current token length */
|
2012-07-18 17:29:33 +00:00
|
|
|
int depth; /* Include depth, 0 = cannot include */
|
|
|
|
|
|
|
|
struct include_file_stack *prev; /* Previous record in stack */
|
|
|
|
struct include_file_stack *up; /* Parent (who included this file) */
|
2011-09-11 19:21:47 +00:00
|
|
|
};
|
|
|
|
|
2011-10-09 23:01:58 +00:00
|
|
|
extern struct include_file_stack *ifs;
|
2011-09-11 19:21:47 +00:00
|
|
|
|
1998-11-27 19:35:10 +00:00
|
|
|
int cf_lex(void);
|
2011-09-11 19:21:47 +00:00
|
|
|
void cf_lex_init(int is_cli, struct config *c);
|
2014-03-25 13:58:00 +00:00
|
|
|
void cf_lex_unwind(void);
|
|
|
|
|
2022-05-02 18:29:03 +00:00
|
|
|
struct symbol *cf_find_symbol_scope(const struct sym_scope *scope, const byte *c);
|
|
|
|
static inline struct symbol *cf_find_symbol_cfg(const struct config *cfg, const byte *c)
|
|
|
|
{ return cf_find_symbol_scope(cfg->root_scope, c); }
|
|
|
|
|
|
|
|
#define cf_find_symbol(where, what) _Generic(*(where), \
|
|
|
|
struct config: cf_find_symbol_cfg, \
|
|
|
|
struct sym_scope: cf_find_symbol_scope \
|
|
|
|
)((where), (what))
|
2015-11-08 23:42:02 +00:00
|
|
|
|
2023-06-13 08:51:03 +00:00
|
|
|
struct symbol *cf_get_symbol(struct config *conf, const byte *c);
|
|
|
|
struct symbol *cf_default_name(struct config *conf, char *template, int *counter);
|
|
|
|
struct symbol *cf_localize_symbol(struct config *conf, struct symbol *sym);
|
2019-02-15 12:53:17 +00:00
|
|
|
|
2023-06-13 08:51:03 +00:00
|
|
|
static inline int cf_symbol_is_local(struct config *conf, struct symbol *sym)
|
|
|
|
{ return (sym->scope == conf->current_scope) && !conf->current_scope->soft_scopes; }
|
2022-03-06 15:37:30 +00:00
|
|
|
|
Filter: Methods rework
Methods can now be called as x.m(y), as long as x can have its type
inferred in config time. If used as a command, it modifies the object,
if used as a value, it keeps the original object intact.
Also functions add(x,y), delete(x,y), filter(x,y) and prepend(x,y) now
spit a warning and are considered deprecated.
It's also possible to call a method on a constant, see filter/test.conf
for examples like bgp_path = +empty+.prepend(1).
Inside instruction definitions (filter/f-inst.c), a METHOD_CONSTRUCTOR()
call is added, which registers the instruction as a method for the type
of its first argument. Each type has its own method symbol table and
filter parser switches between them based on the inferred type of the
object calling the method.
Also FI_CLIST_(ADD|DELETE|FILTER) instructions have been split to allow
for this method dispatch. With type inference, it's now possible.
2023-06-16 15:35:37 +00:00
|
|
|
/* internal */
|
|
|
|
struct symbol *cf_new_symbol(struct sym_scope *scope, pool *p, struct linpool *lp, const byte *c);
|
2023-10-28 21:42:21 +00:00
|
|
|
struct symbol *cf_root_symbol(const byte *, struct sym_scope *);
|
Filter: Methods rework
Methods can now be called as x.m(y), as long as x can have its type
inferred in config time. If used as a command, it modifies the object,
if used as a value, it keeps the original object intact.
Also functions add(x,y), delete(x,y), filter(x,y) and prepend(x,y) now
spit a warning and are considered deprecated.
It's also possible to call a method on a constant, see filter/test.conf
for examples like bgp_path = +empty+.prepend(1).
Inside instruction definitions (filter/f-inst.c), a METHOD_CONSTRUCTOR()
call is added, which registers the instruction as a method for the type
of its first argument. Each type has its own method symbol table and
filter parser switches between them based on the inferred type of the
object calling the method.
Also FI_CLIST_(ADD|DELETE|FILTER) instructions have been split to allow
for this method dispatch. With type inference, it's now possible.
2023-06-16 15:35:37 +00:00
|
|
|
|
2019-02-15 12:53:17 +00:00
|
|
|
/**
|
|
|
|
* cf_define_symbol - define meaning of a symbol
|
|
|
|
* @sym: symbol to be defined
|
|
|
|
* @type: symbol class to assign
|
|
|
|
* @def: class dependent data
|
|
|
|
*
|
|
|
|
* Defines new meaning of a symbol. If the symbol is an undefined
|
|
|
|
* one (%SYM_VOID), it's just re-defined to the new type. If it's defined
|
|
|
|
* in different scope, a new symbol in current scope is created and the
|
|
|
|
* meaning is assigned to it. If it's already defined in the current scope,
|
|
|
|
* an error is reported via cf_error().
|
|
|
|
*
|
|
|
|
* Result: Pointer to the newly defined symbol. If we are in the top-level
|
|
|
|
* scope, it's the same @sym as passed to the function.
|
|
|
|
*/
|
2023-06-13 08:51:03 +00:00
|
|
|
#define cf_define_symbol(conf_, osym_, type_, var_, def_) ({ \
|
|
|
|
struct symbol *sym_ = cf_localize_symbol(conf_, osym_); \
|
2020-02-04 09:34:46 +00:00
|
|
|
sym_->class = type_; \
|
|
|
|
sym_->var_ = def_; \
|
|
|
|
sym_; })
|
2019-02-15 12:53:17 +00:00
|
|
|
|
2023-06-13 08:51:03 +00:00
|
|
|
void cf_push_scope(struct config *, struct symbol *);
|
|
|
|
void cf_pop_scope(struct config *);
|
|
|
|
void cf_push_soft_scope(struct config *);
|
|
|
|
void cf_pop_soft_scope(struct config *);
|
2022-03-06 15:37:30 +00:00
|
|
|
|
2023-06-13 08:51:03 +00:00
|
|
|
static inline void cf_push_block_scope(struct config *conf)
|
|
|
|
{ cf_push_scope(conf, NULL); conf->current_scope->block = 1; }
|
2022-10-18 01:58:19 +00:00
|
|
|
|
2023-06-13 08:51:03 +00:00
|
|
|
static inline void cf_pop_block_scope(struct config *conf)
|
|
|
|
{ ASSERT(conf->current_scope->block); cf_pop_scope(conf); }
|
2022-10-18 01:58:19 +00:00
|
|
|
|
2000-01-19 12:30:19 +00:00
|
|
|
char *cf_symbol_class_name(struct symbol *sym);
|
1998-11-27 19:35:10 +00:00
|
|
|
|
|
|
|
/* Parser */
|
|
|
|
|
2016-11-09 15:36:34 +00:00
|
|
|
extern char *cf_text;
|
1998-11-27 19:35:10 +00:00
|
|
|
int cf_parse(void);
|
|
|
|
|
1999-12-06 13:44:45 +00:00
|
|
|
/* Sysdep hooks */
|
|
|
|
|
|
|
|
void sysdep_preconfig(struct config *);
|
2000-01-16 16:44:50 +00:00
|
|
|
int sysdep_commit(struct config *, struct config *);
|
2000-01-16 17:40:26 +00:00
|
|
|
void sysdep_shutdown_done(void);
|
1999-12-06 13:44:45 +00:00
|
|
|
|
1998-11-27 19:35:10 +00:00
|
|
|
#endif
|