summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/macros.h
blob: 1b2064add34e9ab56167955cfd7897537429e5a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 * macros.h - definitions for 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:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#ifndef included_macros_h
#define included_macros_h

#include <vppinfra/vec.h>
#include <vppinfra/hash.h>
#include <vppinfra/format.h>

#ifdef CLIB_UNIX
#include <stdlib.h>
#include <unistd.h>
#endif

typedef struct
{
  uword *the_builtin_eval_hash;
  uword *the_value_table_hash;
} clib_macro_main_t;

int clib_macro_unset (clib_macro_main_t * mm, char *name);
int clib_macro_set_value (clib_macro_main_t * mm, char *name, char *value);
void clib_macro_add_builtin (clib_macro_main_t * mm, char *name,
			     void *eval_fn);
i8 *clib_macro_get_value (clib_macro_main_t * mm, char *name);
i8 *clib_macro_eval (clib_macro_main_t * mm, i8 * s, i32 complain,
		     u16 level, u16 max_level);
i8 *clib_macro_eval_dollar (clib_macro_main_t * mm, i8 * s, i32 complain);
void clib_macro_init (clib_macro_main_t * mm);
void clib_macro_free (clib_macro_main_t * mm);

format_function_t format_clib_macro_main;

#endif /* included_macros_h */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
ER DEALINGS IN THE SOFTWARE. */ #include <vppinfra/format.h> #include <vppinfra/hash.h> #include <vppinfra/heap.h> /* Hash table plus vector of keys. */ typedef struct { /* Vector or heap used to store keys. Hash table stores keys as byte offsets into this vector. */ u8 *key_vector_or_heap; /* Byte offsets of free keys in vector (used to store free keys when n_key_bytes > 1). */ u32 *key_vector_free_indices; u8 **key_tmps; /* Possibly fixed size of key. 0 means keys are vectors of u8's. 1 means keys are null terminated c strings. */ #define MHASH_VEC_STRING_KEY 0 #define MHASH_C_STRING_KEY 1 u32 n_key_bytes; /* Seed value for Jenkins hash. */ u32 hash_seed; /* Hash table mapping key -> value. */ uword *hash; /* Format function for keys. */ format_function_t *format_key; } mhash_t; void mhash_init (mhash_t * h, uword n_value_bytes, uword n_key_bytes); always_inline void mhash_init_c_string (mhash_t * h, uword n_value_bytes) { mhash_init (h, n_value_bytes, MHASH_C_STRING_KEY); } always_inline void mhash_init_vec_string (mhash_t * h, uword n_value_bytes) { mhash_init (h, n_value_bytes, MHASH_VEC_STRING_KEY); } always_inline void * mhash_key_to_mem (mhash_t * h, uword key) { if (key == ~0) { u8 *key_tmp; int my_cpu = os_get_thread_index (); vec_validate (h->key_tmps, my_cpu); key_tmp = h->key_tmps[my_cpu]; return key_tmp; } return vec_elt_at_index (h->key_vector_or_heap, key); } hash_pair_t *mhash_get_pair (mhash_t * h, const void *key); uword mhash_set_mem (mhash_t * h, void *key, uword * new_value, uword * old_value); uword mhash_unset (mhash_t * h, void *key, uword * old_value); always_inline uword * mhash_get (mhash_t * h, const void *key) { hash_pair_t *p = mhash_get_pair (h, key); return p ? &p->value[0] : 0; } always_inline uword mhash_set (mhash_t * h, void *key, uword new_value, uword * old_value) { return mhash_set_mem (h, key, &new_value, old_value); } always_inline uword mhash_unset_key (mhash_t * h, uword key, uword * old_value) { void *k = mhash_key_to_mem (h, key); return mhash_unset (h, k, old_value); } always_inline uword mhash_value_bytes (mhash_t * m) { hash_t *h = hash_header (m->hash); return hash_value_bytes (h); } always_inline uword mhash_elts (mhash_t * m) { return hash_elts (m->hash); } always_inline uword mhash_key_vector_is_heap (mhash_t * h) { return h->n_key_bytes <= 1; } always_inline void mhash_free (mhash_t * h) { if (mhash_key_vector_is_heap (h)) heap_free (h->key_vector_or_heap); else vec_free (h->key_vector_or_heap); vec_free (h->key_vector_free_indices); hash_free (h->hash); } #define mhash_foreach(k,v,mh,body) \ do { \ hash_pair_t * _mhash_foreach_p; \ hash_foreach_pair (_mhash_foreach_p, (mh)->hash, ({ \ (k) = mhash_key_to_mem ((mh), _mhash_foreach_p->key); \ (v) = &_mhash_foreach_p->value[0]; \ body; \ })); \ } while (0) format_function_t format_mhash_key; #endif /* included_clib_mhash_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */