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>