Annotation of embedaddon/strongswan/src/libstrongswan/utils/enum.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2006 Martin Willi
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include <stddef.h>
17: #include <stdio.h>
18:
19: #include <library.h>
20: #include <utils/utils.h>
21:
22: #include "enum.h"
23:
24: /**
25: * See header.
26: */
27: char *enum_to_name(enum_name_t *e, int val)
28: {
29: if (!e)
30: {
31: return NULL;
32: }
33: do
34: {
35: if (val >= e->first && val <= e->last)
36: {
37: return e->names[val - e->first];
38: }
39: }
40: while ((e = e->next));
41: return NULL;
42: }
43:
44: /**
45: * See header.
46: */
47: bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val)
48: {
49: do
50: {
51: int i, count = e->last - e->first + 1;
52:
53: for (i = 0; i < count; i++)
54: {
55: if (name && strcaseeq(name, e->names[i]))
56: {
57: *val = e->first + i;
58: return TRUE;
59: }
60: }
61: }
62: while ((e = e->next));
63: return FALSE;
64: }
65:
66: /**
67: * Get the position of a flag name using offset calculation
68: */
69: static int find_flag_pos(u_int val, u_int first)
70: {
71: int offset = 0;
72:
73: while (val != 0x01)
74: {
75: val = val >> 1;
76: offset++;
77: }
78: return first - offset;
79: }
80:
81: /**
82: * Described in header.
83: */
84: char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
85: {
86: char *pos = buf, *delim = "";
87: int i, wr;
88:
89: if (e->next != ENUM_FLAG_MAGIC)
90: {
91: if (snprintf(buf, len, "(%d)", (int)val) >= len)
92: {
93: return NULL;
94: }
95: return buf;
96: }
97:
98: if (snprintf(buf, len, "(unset)") >= len)
99: {
100: return NULL;
101: }
102:
103: for (i = 0; val; i++)
104: {
105: u_int flag = 1 << i;
106:
107: if (val & flag)
108: {
109: char *name = NULL, hex[32];
110:
111: if (flag >= (u_int)e->first && flag <= (u_int)e->last)
112: {
113: name = e->names[find_flag_pos(e->first, i)];
114: }
115: else
116: {
117: snprintf(hex, sizeof(hex), "(0x%X)", flag);
118: name = hex;
119: }
120: if (name)
121: {
122: wr = snprintf(pos, len, "%s%s", delim, name);
123: if (wr >= len)
124: {
125: return NULL;
126: }
127: len -= wr;
128: pos += wr;
129: delim = " | ";
130: }
131: val &= ~flag;
132: }
133: }
134: return buf;
135: }
136:
137: /**
138: * See header.
139: */
140: int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
141: const void *const *args)
142: {
143: enum_name_t *ed = *((enum_name_t**)(args[0]));
144: int val = *((int*)(args[1]));
145: char *name, buf[512];
146:
147: if (ed && ed->next == ENUM_FLAG_MAGIC)
148: {
149: name = enum_flags_to_string(ed, val, buf, sizeof(buf));
150: if (name == NULL)
151: {
152: snprintf(buf, sizeof(buf), "(0x%X)", val);
153: name = buf;
154: }
155: }
156: else
157: {
158: name = enum_to_name(ed, val);
159: if (name == NULL)
160: {
161: snprintf(buf, sizeof(buf), "(%d)", val);
162: name = buf;
163: }
164: }
165: if (spec->minus)
166: {
167: return print_in_hook(data, "%-*s", spec->width, name);
168: }
169: return print_in_hook(data, "%*s", spec->width, name);
170: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>