From 85866e782c0e8d49b2fbc5f8fdf77065f1efae14 Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Mon, 9 Nov 2020 10:30:06 -0500 Subject: vlib: support macros in initial config file Type: improvement Signed-off-by: Dave Barach Change-Id: If8a19eb6688755311a3430437331ddf13c7e28c8 --- src/vlib/unix/cli.c | 74 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 15 deletions(-) (limited to 'src/vlib/unix') diff --git a/src/vlib/unix/cli.c b/src/vlib/unix/cli.c index c7732ae431f..07ce414f616 100644 --- a/src/vlib/unix/cli.c +++ b/src/vlib/unix/cli.c @@ -3359,10 +3359,14 @@ unix_cli_exec (vlib_main_t * vm, int fd; unformat_input_t sub_input; clib_error_t *error; - + unix_cli_main_t *cm = &unix_cli_main; + unix_cli_file_t *cf; + u8 *file_data = 0; file_name = 0; fd = -1; error = 0; + struct stat s; + if (!unformat (input, "%s", &file_name)) { @@ -3379,23 +3383,63 @@ unix_cli_exec (vlib_main_t * vm, } /* Make sure its a regular file. */ - { - struct stat s; + if (fstat (fd, &s) < 0) + { + error = clib_error_return_unix (0, "failed to stat `%s'", file_name); + goto done; + } - if (fstat (fd, &s) < 0) - { - error = clib_error_return_unix (0, "failed to stat `%s'", file_name); - goto done; - } + if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode))) + { + error = clib_error_return (0, "not a regular file `%s'", file_name); + goto done; + } - if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode))) - { - error = clib_error_return (0, "not a regular file `%s'", file_name); - goto done; - } - } + /* Read the file */ + vec_validate (file_data, s.st_size); + + if (read (fd, file_data, s.st_size) != s.st_size) + { + error = clib_error_return_unix (0, "Failed to read %d bytes from '%s'", + s.st_size, file_name); + vec_free (file_data); + goto done; + } + + /* The macro expander expects a c string... */ + vec_add1 (file_data, 0); + + unformat_init_vector (&sub_input, file_data); + + /* Run the file contents through the macro processor */ + if (vec_len (sub_input.buffer) > 1) + { + u8 *expanded; + clib_macro_main_t *mm = 0; + + /* Initial config process? Use the global macro table. */ + if (pool_is_free_index + (cm->cli_file_pool, cm->current_input_file_index)) + mm = &cm->macro_main; + else + { + /* Otherwise, use the per-cli-process macro table */ + cf = pool_elt_at_index (cm->cli_file_pool, + cm->current_input_file_index); + mm = &cf->macro_main; + } - unformat_init_clib_file (&sub_input, fd); + expanded = (u8 *) clib_macro_eval (mm, + (i8 *) sub_input.buffer, + 1 /* complain */ , + 0 /* level */ , + 8 /* max_level */ ); + /* Macro processor NULL terminates the return */ + _vec_len (expanded) -= 1; + vec_reset_length (sub_input.buffer); + vec_append (sub_input.buffer, expanded); + vec_free (expanded); + } vlib_cli_input (vm, &sub_input, 0, 0); unformat_free (&sub_input); -- cgit 1.2.3-korg