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>