Blame src/libopts/save-flags.c

Packit Service 4684c1
/*   -*- buffer-read-only: t -*- vi: set ro:
Packit Service 4684c1
 *
Packit Service 4684c1
 *  DO NOT EDIT THIS FILE   (save-flags.c)
Packit Service 4684c1
 *
Packit Service 4684c1
 *  It has been AutoGen-ed
Packit Service 4684c1
 *  From the definitions    /tmp/.ag-ufBbQe/save-flags.def
Packit Service 4684c1
 *  and the template file   str2enum
Packit Service 4684c1
 *
Packit Service 4684c1
 * Redistribution and use in source and binary forms, with or without
Packit Service 4684c1
 * modification, are permitted provided that the following conditions
Packit Service 4684c1
 * are met:
Packit Service 4684c1
 * 1. Redistributions of source code must retain the above copyright
Packit Service 4684c1
 *    notice, this list of conditions and the following disclaimer.
Packit Service 4684c1
 * 2. Redistributions in binary form must reproduce the above copyright
Packit Service 4684c1
 *    notice, this list of conditions and the following disclaimer in the
Packit Service 4684c1
 *    documentation and/or other materials provided with the distribution.
Packit Service 4684c1
 * 3. Neither the name ``Bruce Korb'' nor the name of any other
Packit Service 4684c1
 *    contributor may be used to endorse or promote products derived
Packit Service 4684c1
 *    from this software without specific prior written permission.
Packit Service 4684c1
 *
Packit Service 4684c1
 * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
Packit Service 4684c1
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Packit Service 4684c1
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit Service 4684c1
 * ARE DISCLAIMED.  IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
Packit Service 4684c1
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit Service 4684c1
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit Service 4684c1
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
Packit Service 4684c1
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
Packit Service 4684c1
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
Packit Service 4684c1
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Packit Service 4684c1
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 4684c1
 */
Packit Service 4684c1
#include "save-flags.h"
Packit Service 4684c1
#include <sys/types.h>
Packit Service 4684c1
#ifndef MISSING_INTTYPES_H
Packit Service 4684c1
# include <inttypes.h>
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
typedef enum {
Packit Service 4684c1
    SVFL_BNM_DEFAULT  = 0,
Packit Service 4684c1
    SVFL_BNM_USAGE    = 1,
Packit Service 4684c1
    SVFL_BNM_UPDATE   = 2,
Packit Service 4684c1
    SVFL_COUNT_BNM
Packit Service 4684c1
} save_flags_enum_t;
Packit Service 4684c1
Packit Service 4684c1
static save_flags_enum_t
Packit Service 4684c1
find_save_flags_bnm(char const * str, size_t len);
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
#include <sys/types.h>
Packit Service 4684c1
#include <string.h>
Packit Service 4684c1
#ifndef NUL
Packit Service 4684c1
#define NUL '\0'
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
/* ANSI-C code produced by gperf version 3.1 */
Packit Service 4684c1
/* Command-line: gperf save-flags.gp  */
Packit Service 4684c1
/* Computed positions: -k'' */
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
# if 0 /* gperf build options: */
Packit Service 4684c1
// %struct-type
Packit Service 4684c1
// %language=ANSI-C
Packit Service 4684c1
// %includes
Packit Service 4684c1
// %global-table
Packit Service 4684c1
// %omit-struct-type
Packit Service 4684c1
// %readonly-tables
Packit Service 4684c1
// %compare-strncmp
Packit Service 4684c1
//
Packit Service 4684c1
// %define slot-name               svfl_name
Packit Service 4684c1
// %define hash-function-name      save_flags_hash
Packit Service 4684c1
// %define lookup-function-name    find_save_flags_name
Packit Service 4684c1
// %define word-array-name         save_flags_table
Packit Service 4684c1
// %define initializer-suffix      ,SVFL_COUNT_BNM
Packit Service 4684c1
//
Packit Service 4684c1
# endif
Packit Service 4684c1
Packit Service 4684c1
#include "save-flags.h"
Packit Service 4684c1
typedef struct {
Packit Service 4684c1
    char const *    svfl_name;
Packit Service 4684c1
    save_flags_enum_t svfl_id;
Packit Service 4684c1
} save_flags_map_t;
Packit Service 4684c1
#include <string.h>
Packit Service 4684c1
Packit Service 4684c1
/* maximum key range = 3, duplicates = 0 */
Packit Service 4684c1
Packit Service 4684c1
static unsigned int
Packit Service 4684c1
save_flags_hash (register const char *str, register size_t len)
Packit Service 4684c1
{
Packit Service 4684c1
  (void)str;
Packit Service 4684c1
  (void)len;
Packit Service 4684c1
  return len;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static const save_flags_map_t save_flags_table[] =
Packit Service 4684c1
  {
Packit Service 4684c1
    {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM},
Packit Service 4684c1
    {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM},
Packit Service 4684c1
    {"",SVFL_COUNT_BNM},
Packit Service 4684c1
    {"usage",    SVFL_BNM_USAGE},
Packit Service 4684c1
    {"update",   SVFL_BNM_UPDATE},
Packit Service 4684c1
    {"default",  SVFL_BNM_DEFAULT}
Packit Service 4684c1
  };
Packit Service 4684c1
Packit Service 4684c1
static inline const save_flags_map_t *
Packit Service 4684c1
find_save_flags_name (register const char *str, register size_t len)
Packit Service 4684c1
{
Packit Service 4684c1
  if (len <= 7 && len >= 5)
Packit Service 4684c1
    {
Packit Service 4684c1
      register unsigned int key = (int)save_flags_hash (str, len);
Packit Service 4684c1
Packit Service 4684c1
      if (key <= 7)
Packit Service 4684c1
        {
Packit Service 4684c1
          register const char *s = save_flags_table[key].svfl_name;
Packit Service 4684c1
Packit Service 4684c1
          if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
Packit Service 4684c1
            return &save_flags_table[key];
Packit Service 4684c1
        }
Packit Service 4684c1
    }
Packit Service 4684c1
  return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * Convert a command (keyword) to a save_flags_enum_t enumeration value.
Packit Service 4684c1
 *
Packit Service 4684c1
 * @param[in] str   a string that should start with a known key word.
Packit Service 4684c1
 * @param[in] len   the provided length of the keyword at \a str.
Packit Service 4684c1
 * @returns the enumeration value.
Packit Service 4684c1
 * If not found, that value is SVFL_COUNT_BNM.
Packit Service 4684c1
 */
Packit Service 4684c1
static save_flags_enum_t
Packit Service 4684c1
find_save_flags_bnm(char const * str, size_t len)
Packit Service 4684c1
{
Packit Service 4684c1
    save_flags_map_t const * map;
Packit Service 4684c1
Packit Service 4684c1
    map = find_save_flags_name(str, (unsigned int)len);
Packit Service 4684c1
    if (map != NULL)
Packit Service 4684c1
        return map->svfl_id;
Packit Service 4684c1
    /* Check for a partial match */
Packit Service 4684c1
    {
Packit Service 4684c1
        /*
Packit Service 4684c1
         * Indexes of valid save_flags_table entries in sorted order:
Packit Service 4684c1
         */
Packit Service 4684c1
        static unsigned int const ix_map[] = {
Packit Service 4684c1
            7, 6, 5 };
Packit Service 4684c1
        save_flags_enum_t res = SVFL_COUNT_BNM;
Packit Service 4684c1
        static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1;
Packit Service 4684c1
        int lo = 0;
Packit Service 4684c1
        int hi = HI;
Packit Service 4684c1
        int av;
Packit Service 4684c1
        int cmp;
Packit Service 4684c1
Packit Service 4684c1
        for (;;) {
Packit Service 4684c1
            av  = (hi + lo) / 2;
Packit Service 4684c1
            map = save_flags_table + ix_map[av];
Packit Service 4684c1
            cmp = strncmp(map->svfl_name, str, len);
Packit Service 4684c1
            if (cmp == 0) break;
Packit Service 4684c1
            if (cmp > 0)
Packit Service 4684c1
                 hi = av - 1;
Packit Service 4684c1
            else lo = av + 1;
Packit Service 4684c1
            if (lo > hi)
Packit Service 4684c1
                return SVFL_COUNT_BNM;
Packit Service 4684c1
        }
Packit Service 4684c1
        res = map->svfl_id;
Packit Service 4684c1
        /*
Packit Service 4684c1
         * If we have an exact match, accept it.
Packit Service 4684c1
         */
Packit Service 4684c1
        if (map->svfl_name[len] == NUL)
Packit Service 4684c1
            return res;
Packit Service 4684c1
        /*
Packit Service 4684c1
         * Check for a duplicate partial match (a partial match
Packit Service 4684c1
         * with a higher or lower index than "av".
Packit Service 4684c1
         */
Packit Service 4684c1
        if (av < HI) {
Packit Service 4684c1
            map = save_flags_table + ix_map[av + 1];
Packit Service 4684c1
            if (strncmp(map->svfl_name, str, len) == 0)
Packit Service 4684c1
                return SVFL_COUNT_BNM;
Packit Service 4684c1
        }
Packit Service 4684c1
        if (av > 0) {
Packit Service 4684c1
            map = save_flags_table + ix_map[av - 1];
Packit Service 4684c1
            if (strncmp(map->svfl_name, str, len) == 0)
Packit Service 4684c1
                return SVFL_COUNT_BNM;
Packit Service 4684c1
        }
Packit Service 4684c1
        return res;
Packit Service 4684c1
    }
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * Convert a string to a save_flags_mask_t mask.
Packit Service 4684c1
 * Bit names prefixed with a hyphen have the bit removed from the mask.
Packit Service 4684c1
 * If the string starts with a '-', '+' or '|' character, then
Packit Service 4684c1
 * the old value is used as a base, otherwise the result mask
Packit Service 4684c1
 * is initialized to zero.  Separating bit names with '+' or '|'
Packit Service 4684c1
 * characters is optional.  By default, the bits are "or"-ed into the
Packit Service 4684c1
 * result.
Packit Service 4684c1
 *
Packit Service 4684c1
 * @param[in] str string with a list of bit names
Packit Service 4684c1
 * @param[in] old previous value, used if \a str starts with a '+' or '-'.
Packit Service 4684c1
 *
Packit Service 4684c1
 * @returns an unsigned integer with the bits set.
Packit Service 4684c1
 */
Packit Service 4684c1
save_flags_mask_t
Packit Service 4684c1
save_flags_str2mask(char const * str, save_flags_mask_t old)
Packit Service 4684c1
{
Packit Service 4684c1
    static char const white[] = ", \t\f";
Packit Service 4684c1
    static char const name_chars[] =
Packit Service 4684c1
        "adefglpstu"
Packit Service 4684c1
        "ADEFGLPSTU";
Packit Service 4684c1
Packit Service 4684c1
    save_flags_mask_t res = 0;
Packit Service 4684c1
    int have_data = 0;
Packit Service 4684c1
Packit Service 4684c1
    for (;;) {
Packit Service 4684c1
        save_flags_enum_t val;
Packit Service 4684c1
        unsigned int val_len;
Packit Service 4684c1
        unsigned int invert = 0;
Packit Service 4684c1
Packit Service 4684c1
        str += strspn(str, white);
Packit Service 4684c1
        switch (*str) {
Packit Service 4684c1
        case NUL: return res;
Packit Service 4684c1
        case '-': case '~':
Packit Service 4684c1
            invert = 1;
Packit Service 4684c1
            /* FALLTHROUGH */
Packit Service 4684c1
Packit Service 4684c1
        case '+': case '|':
Packit Service 4684c1
            if (have_data == 0)
Packit Service 4684c1
                res = old;
Packit Service 4684c1
Packit Service 4684c1
            str += 1 + strspn(str + 1, white);
Packit Service 4684c1
            if (*str == NUL)
Packit Service 4684c1
                return 0;
Packit Service 4684c1
        }
Packit Service 4684c1
Packit Service 4684c1
        val_len = strspn(str, name_chars);
Packit Service 4684c1
        if (val_len == 0)
Packit Service 4684c1
            return 0;
Packit Service 4684c1
        val = find_save_flags_bnm(str, val_len);
Packit Service 4684c1
        if (val == SVFL_COUNT_BNM)
Packit Service 4684c1
            return 0;
Packit Service 4684c1
        if (invert)
Packit Service 4684c1
            res &= ~((save_flags_mask_t)1 << val);
Packit Service 4684c1
        else
Packit Service 4684c1
            res |= (save_flags_mask_t)1 << val;
Packit Service 4684c1
        have_data = 1;
Packit Service 4684c1
        str += val_len;
Packit Service 4684c1
    }
Packit Service 4684c1
}
Packit Service 4684c1
/* end of save-flags.c */