Annotation of embedaddon/strongswan/src/libstrongswan/utils/enum.c, revision 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>