summaryrefslogtreecommitdiffstats
path: root/lib/name_map.h
blob: 60be6c050f99f3ef3da6d2a70c6929b26e8bee3c (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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* Map value to name -- header
 * Copyright (C) 2011 Chris Hall (GMCH), Highwayman
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef _ZEBRA_NAME_MAP_H
#define _ZEBRA_NAME_MAP_H

#include "misc.h"
#include "qfstring.h"

/*==============================================================================
 * Name table definitions
 *
 * A name table maps an integer value to a name, with an option default for
 * unknown values.
 *
 * Two forms of name table are supported:
 *
 *   * direct   -- where the names are in an array indexed directly by value
 *
 *   * indirect -- where the name has to be searched for
 *
 * Obviously, direct is more efficient, except where the value range is large,
 * or very sparse.
 */
QFB_T(60) name_str_t ;          /* Reasonable size "name"       */

/*------------------------------------------------------------------------------
 * Direct name table
 *
 * This comes in two parts, the "body", which is an array of pointers, and the
 * "map", which points at the body and also contains the default (if any) and
 * the number of entries in the body.
 *
 * The body may be constructed as any other array, for example:
 *
 *   const char* bgp_message_types_body[] =
 *   {
 *     [BGP_MT_OPEN]   = "OPEN",
 *     [BGP_MT_UPDATE] = "UPDATE",
 *     ...
 *   } ;
 *
 * NB: this means that any unspecified values will map to NULL.  Which implies
 *     that it is not possible to map to NULL, because that will map to the
 *     default !
 *
 * The map is most easily constructed using the direct_map macro, for example:
 *
 *   const map_direct_t bgp_message_types_map direct_map =
 *                         map_direct_s(bgp_message_types_body, "UNKNOWN(%d)") ;
 *
 * The map_direct function returns a name_str_t struct, with a .str entry,
 * so can be used:
 *
 *   fprintf("...BGP %s message...", ...,
 *                     map_direct(bgp_message_types_map, val).str, ...) ;
 *
 * If the val is not known, map_direct() will return the default which is
 * assumed to be a format string for sprintf(), with val as the only value
 * parameter.  If the map has no explicit default (NULL is given to the
 * direct_map() macro) then an empty string is returned !
 *
 * To allow for value ranges that include -ve numbers or start with large
 * values, a "min-value" may be specified.  So that:
 *
 *   const char* foo_body[] =
 *   {
 *     [foo_val_a - foo_min]   = "A",
 *     [foo_val_b - foo_min]   = "B",
 *     ...
 *   } ;
 *
 *   const map_direct_t foo_map direct_map =
 *                          map_direct_min_s(foo_body, "UNKNOWN(%d)", foo_min) ;
 *
 * will work.
 */
typedef const struct map_direct
{
  const char** body ;
  const char* deflt ;

  int   min_val ;
  int   count ;
} map_direct_t[] ;

typedef const struct map_direct* map_direct_p ;

#define map_direct_min_s(_body, _default, _min_val) \
  {{.body    = _body, \
    .deflt   = _default, \
    .min_val = _min_val, \
    .count   = sizeof(_body) / sizeof(char*), \
  }}

#define map_direct_s(_body, _default) map_direct_min_s(_body, _default, 0)

/*------------------------------------------------------------------------------
 * Indirect Map -- TBA
 */

/*==============================================================================
 * Functions
 */
extern name_str_t map_direct(const map_direct_t map, int val) ;

#endif /* _ZEBRA_NAME_MAP_H */