X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Fmacros.c;h=b8a8e1744aac0c54f939173aa8564dc5e1f717f9;hb=bfcd4b9868112226705571dadad68aa160f6896e;hp=ce4cc9bc81b17e3d393e46c0a88578e8d98014f3;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vppinfra/macros.c b/src/vppinfra/macros.c index ce4cc9bc81b..b8a8e1744aa 100644 --- a/src/vppinfra/macros.c +++ b/src/vppinfra/macros.c @@ -1,9 +1,9 @@ /* - macros.c - a simple macro expander - - Copyright (c) 2010, 2014 Cisco and/or its affiliates. - - * Licensed under the Apache License, Version 2.0 (the "License"); + * macros.c - a simple macro expander + * + * Copyright (c) 2010-2020 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * @@ -28,10 +28,10 @@ macro_isalnum (i8 c) } static i8 * -builtin_eval (macro_main_t * mm, i8 * varname, i32 complain) +builtin_eval (clib_macro_main_t * mm, i8 * varname, i32 complain) { uword *p; - i8 *(*fp) (macro_main_t *, i32); + i8 *(*fp) (clib_macro_main_t *, i32); p = hash_get_mem (mm->the_builtin_eval_hash, varname); if (p == 0) @@ -40,8 +40,8 @@ builtin_eval (macro_main_t * mm, i8 * varname, i32 complain) return (*fp) (mm, complain); } -int -clib_macro_unset (macro_main_t * mm, char *name) +__clib_export int +clib_macro_unset (clib_macro_main_t * mm, char *name) { hash_pair_t *p; u8 *key, *value; @@ -60,8 +60,8 @@ clib_macro_unset (macro_main_t * mm, char *name) return 0; } -int -clib_macro_set_value (macro_main_t * mm, char *name, char *value) +__clib_export int +clib_macro_set_value (clib_macro_main_t * mm, char *name, char *value) { u8 *key_copy, *value_copy; int rv; @@ -76,7 +76,7 @@ clib_macro_set_value (macro_main_t * mm, char *name, char *value) } i8 * -clib_macro_get_value (macro_main_t * mm, char *name) +clib_macro_get_value (clib_macro_main_t * mm, char *name) { uword *p; @@ -91,13 +91,21 @@ clib_macro_get_value (macro_main_t * mm, char *name) * eval: takes a string, returns a vector. * looks up $foobar in the variable table. */ -i8 * -clib_macro_eval (macro_main_t * mm, i8 * s, i32 complain) +__clib_export i8 * +clib_macro_eval (clib_macro_main_t * mm, i8 * s, i32 complain, u16 level, + u16 max_level) { i8 *rv = 0; i8 *varname, *varvalue; i8 *ts; + if (level >= max_level) + { + if (complain) + clib_warning ("circular definition, level %d", level); + return (i8 *) format (0, " CIRCULAR "); + } + while (*s) { switch (*s) @@ -144,7 +152,7 @@ clib_macro_eval (macro_main_t * mm, i8 * s, i32 complain) /* Look in value table */ if (!varvalue) { - char *tmp = clib_macro_get_value (mm, varname); + i8 *tmp = clib_macro_get_value (mm, (char *) varname); if (tmp) varvalue = (i8 *) format (0, "%s%c", tmp, 0); } @@ -152,7 +160,7 @@ clib_macro_eval (macro_main_t * mm, i8 * s, i32 complain) /* Look in environment. */ if (!varvalue) { - char *tmp = getenv (varname); + char *tmp = getenv ((char *) varname); if (tmp) varvalue = (i8 *) format (0, "%s%c", tmp, 0); } @@ -161,7 +169,8 @@ clib_macro_eval (macro_main_t * mm, i8 * s, i32 complain) if (varvalue) { /* recursively evaluate */ - ts = clib_macro_eval (mm, varvalue, complain); + ts = clib_macro_eval (mm, varvalue, complain, level + 1, + max_level); vec_free (varvalue); /* add results to answer */ vec_append (rv, ts); @@ -188,27 +197,27 @@ clib_macro_eval (macro_main_t * mm, i8 * s, i32 complain) * eval: takes a string, returns a vector. * looks up $foobar in the variable table. */ -i8 * -clib_macro_eval_dollar (macro_main_t * mm, i8 * s, i32 complain) +__clib_export i8 * +clib_macro_eval_dollar (clib_macro_main_t *mm, i8 *s, i32 complain) { i8 *s2; i8 *rv; s2 = (i8 *) format (0, "$(%s)%c", s, 0); - rv = clib_macro_eval (mm, s2, complain); + rv = clib_macro_eval (mm, s2, complain, 0 /* level */ , 8 /* max_level */ ); vec_free (s2); return (rv); } -void -clib_macro_add_builtin (macro_main_t * mm, char *name, void *eval_fn) +__clib_export void +clib_macro_add_builtin (clib_macro_main_t * mm, char *name, void *eval_fn) { hash_set_mem (mm->the_builtin_eval_hash, name, (uword) eval_fn); } #ifdef CLIB_UNIX static i8 * -eval_hostname (macro_main_t * mm, i32 complain) +eval_hostname (clib_macro_main_t * mm, i32 complain) { char tmp[128]; if (gethostname (tmp, sizeof (tmp))) @@ -217,8 +226,8 @@ eval_hostname (macro_main_t * mm, i32 complain) } #endif -void -clib_macro_init (macro_main_t * mm) +__clib_export void +clib_macro_init (clib_macro_main_t * mm) { if (mm->the_builtin_eval_hash != 0) { @@ -234,8 +243,8 @@ clib_macro_init (macro_main_t * mm) #endif } -void -clib_macro_free (macro_main_t * mm) +__clib_export void +clib_macro_free (clib_macro_main_t * mm) { hash_pair_t *p; u8 **strings_to_free = 0; @@ -257,6 +266,62 @@ clib_macro_free (macro_main_t * mm) hash_free (mm->the_value_table_hash); } +typedef struct +{ + u8 *name; + u8 *value; +} name_sort_t; + +static int +name_compare (void *a1, void *a2) +{ + name_sort_t *ns1 = a1; + name_sort_t *ns2 = a2; + + return strcmp ((char *) ns1->name, (char *) ns2->name); +} + + +__clib_export u8 * +format_clib_macro_main (u8 * s, va_list * args) +{ + clib_macro_main_t *mm = va_arg (*args, clib_macro_main_t *); + int evaluate = va_arg (*args, int); + hash_pair_t *p; + name_sort_t *nses = 0, *ns; + int i; + + /* *INDENT-OFF* */ + hash_foreach_pair (p, mm->the_value_table_hash, + ({ + vec_add2 (nses, ns, 1); + ns->name = (u8 *)(p->key); + ns->value = (u8 *)(p->value[0]); + })); + /* *INDENT-ON* */ + + if (vec_len (nses) == 0) + return s; + + vec_sort_with_function (nses, name_compare); + + for (i = 0; i < vec_len (nses); i++) + { + s = format (s, "%-20s", nses[i].name); + if (evaluate == 0) + s = format (s, "%s\n", nses[i].value); + else + { + u8 *rv = (u8 *) clib_macro_eval_dollar (mm, (i8 *) nses[i].name, + 0 /* no complain */ ); + s = format (s, "%s\n", rv); + vec_free (rv); + } + } + return s; +} + + /* * fd.io coding-style-patch-verification: ON *