busybox/libbb/compare_string_array.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   4 */
   5#include "libbb.h"
   6
   7/*
   8 * Return NULL if string is not prefixed with key. Return pointer to the
   9 * first character in string after the prefix key. If key is an empty string,
  10 * return pointer to the beginning of string.
  11 */
  12char* FAST_FUNC is_prefixed_with(const char *string, const char *key)
  13{
  14#if 0   /* Two passes over key - probably slower */
  15        int len = strlen(key);
  16        if (strncmp(string, key, len) == 0)
  17                return string + len;
  18        return NULL;
  19#else   /* Open-coded */
  20        while (*key != '\0') {
  21                if (*key != *string)
  22                        return NULL;
  23                key++;
  24                string++;
  25        }
  26        return (char*)string;
  27#endif
  28}
  29
  30/*
  31 * Return NULL if string is not suffixed with key. Return pointer to the
  32 * beginning of prefix key in string. If key is an empty string return pointer
  33 * to the end of string.
  34 */
  35char* FAST_FUNC is_suffixed_with(const char *string, const char *key)
  36{
  37        size_t key_len = strlen(key);
  38        ssize_t len_diff = strlen(string) - key_len;
  39
  40        if (len_diff >= 0) {
  41                string += len_diff;
  42                if (strcmp(string, key) == 0) {
  43                        return (char*)string;
  44                }
  45        }
  46
  47        return NULL;
  48}
  49
  50/* returns the array index of the string */
  51/* (index of first match is returned, or -1) */
  52int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key)
  53{
  54        int i;
  55
  56        for (i = 0; string_array[i] != 0; i++) {
  57                if (strcmp(string_array[i], key) == 0) {
  58                        return i;
  59                }
  60        }
  61        return -1;
  62}
  63
  64int FAST_FUNC index_in_strings(const char *strings, const char *key)
  65{
  66        int idx = 0;
  67
  68        while (*strings) {
  69                if (strcmp(strings, key) == 0) {
  70                        return idx;
  71                }
  72                strings += strlen(strings) + 1; /* skip NUL */
  73                idx++;
  74        }
  75        return -1;
  76}
  77
  78/* returns the array index of the string, even if it matches only a beginning */
  79/* (index of first match is returned, or -1) */
  80#ifdef UNUSED
  81int FAST_FUNC index_in_substr_array(const char *const string_array[], const char *key)
  82{
  83        int i;
  84        if (key[0]) {
  85                for (i = 0; string_array[i] != 0; i++) {
  86                        if (is_prefixed_with(string_array[i], key)) {
  87                                return i;
  88                        }
  89                }
  90        }
  91        return -1;
  92}
  93#endif
  94
  95int FAST_FUNC index_in_substrings(const char *strings, const char *key)
  96{
  97        int matched_idx = -1;
  98        const int len = strlen(key);
  99
 100        if (len) {
 101                int idx = 0;
 102                while (*strings) {
 103                        if (strncmp(strings, key, len) == 0) {
 104                                if (strings[len] == '\0')
 105                                        return idx; /* exact match */
 106                                if (matched_idx >= 0)
 107                                        return -1; /* ambiguous match */
 108                                matched_idx = idx;
 109                        }
 110                        strings += strlen(strings) + 1; /* skip NUL */
 111                        idx++;
 112                }
 113        }
 114        return matched_idx;
 115}
 116
 117const char* FAST_FUNC nth_string(const char *strings, int n)
 118{
 119        while (n) {
 120                n--;
 121                strings += strlen(strings) + 1;
 122        }
 123        return strings;
 124}
 125
 126#ifdef UNUSED_SO_FAR /* only brctl.c needs it yet */
 127/* Returns 0 for no, 1 for yes or a negative value on error.  */
 128smallint FAST_FUNC yesno(const char *str)
 129{
 130        static const char no_yes[] ALIGN1 =
 131                "0\0" "off\0" "no\0"
 132                "1\0" "on\0" "yes\0";
 133        int ret = index_in_substrings(no_yes, str);
 134        return ret / 3;
 135}
 136#endif
 137
 138#if ENABLE_UNIT_TEST
 139
 140BBUNIT_DEFINE_TEST(is_prefixed_with)
 141{
 142        BBUNIT_ASSERT_STREQ(" bar", is_prefixed_with("foo bar", "foo"));
 143        BBUNIT_ASSERT_STREQ("bar", is_prefixed_with("foo bar", "foo "));
 144        BBUNIT_ASSERT_STREQ("", is_prefixed_with("foo", "foo"));
 145        BBUNIT_ASSERT_STREQ("foo", is_prefixed_with("foo", ""));
 146        BBUNIT_ASSERT_STREQ("", is_prefixed_with("", ""));
 147
 148        BBUNIT_ASSERT_NULL(is_prefixed_with("foo", "bar foo"));
 149        BBUNIT_ASSERT_NULL(is_prefixed_with("foo foo", "bar"));
 150        BBUNIT_ASSERT_NULL(is_prefixed_with("", "foo"));
 151
 152        BBUNIT_ENDTEST;
 153}
 154
 155BBUNIT_DEFINE_TEST(is_suffixed_with)
 156{
 157        BBUNIT_ASSERT_STREQ("bar", is_suffixed_with("foo bar", "bar"));
 158        BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("foo", "foo"));
 159        BBUNIT_ASSERT_STREQ("", is_suffixed_with("foo", ""));
 160        BBUNIT_ASSERT_STREQ("", is_suffixed_with("", ""));
 161        BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("barfoofoo", "foo"));
 162
 163        BBUNIT_ASSERT_NULL(is_suffixed_with("foo", "bar foo"));
 164        BBUNIT_ASSERT_NULL(is_suffixed_with("foo foo", "bar"));
 165        BBUNIT_ASSERT_NULL(is_suffixed_with("", "foo"));
 166
 167        BBUNIT_ENDTEST;
 168}
 169
 170#endif /* ENABLE_UNIT_TEST */
 171