123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- #ifndef HWCONFIG_TEST
- #include <config.h>
- #include <common.h>
- #include <exports.h>
- #include <hwconfig.h>
- #include <linux/types.h>
- #include <linux/string.h>
- #else
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #define min(a, b) (((a) < (b)) ? (a) : (b))
- #endif
- DECLARE_GLOBAL_DATA_PTR;
- static const char *hwconfig_parse(const char *opts, size_t maxlen,
- const char *opt, char *stopchs, char eqch,
- size_t *arglen)
- {
- size_t optlen = strlen(opt);
- char *str;
- const char *start = opts;
- const char *end;
- next:
- str = strstr(opts, opt);
- end = str + optlen;
- if (end - start > maxlen)
- return NULL;
- if (str && (str == opts || strpbrk(str - 1, stopchs) == str - 1) &&
- (strpbrk(end, stopchs) == end || *end == eqch ||
- *end == '\0')) {
- const char *arg_end;
- if (!arglen)
- return str;
- if (*end != eqch)
- return NULL;
- arg_end = strpbrk(str, stopchs);
- if (!arg_end)
- *arglen = min(maxlen, strlen(str)) - optlen - 1;
- else
- *arglen = arg_end - end - 1;
- return end + 1;
- } else if (str) {
- opts = end;
- goto next;
- }
- return NULL;
- }
- const char cpu_hwconfig[] __attribute__((weak)) = "";
- const char board_hwconfig[] __attribute__((weak)) = "";
- static const char *__hwconfig(const char *opt, size_t *arglen,
- const char *env_hwconfig)
- {
- const char *ret;
-
- if (!env_hwconfig) {
- if (!(gd->flags & GD_FLG_ENV_READY)) {
- printf("WARNING: Calling __hwconfig without a buffer "
- "and before environment is ready\n");
- return NULL;
- }
- env_hwconfig = getenv("hwconfig");
- }
- if (env_hwconfig) {
- ret = hwconfig_parse(env_hwconfig, strlen(env_hwconfig),
- opt, ";", ':', arglen);
- if (ret)
- return ret;
- }
- ret = hwconfig_parse(board_hwconfig, strlen(board_hwconfig),
- opt, ";", ':', arglen);
- if (ret)
- return ret;
- return hwconfig_parse(cpu_hwconfig, strlen(cpu_hwconfig),
- opt, ";", ':', arglen);
- }
- int hwconfig_f(const char *opt, char *buf)
- {
- return !!__hwconfig(opt, NULL, buf);
- }
- const char *hwconfig_arg_f(const char *opt, size_t *arglen, char *buf)
- {
- return __hwconfig(opt, arglen, buf);
- }
- int hwconfig_arg_cmp_f(const char *opt, const char *arg, char *buf)
- {
- const char *argstr;
- size_t arglen;
- argstr = hwconfig_arg_f(opt, &arglen, buf);
- if (!argstr || arglen != strlen(arg))
- return 0;
- return !strncmp(argstr, arg, arglen);
- }
- int hwconfig_sub_f(const char *opt, const char *subopt, char *buf)
- {
- size_t arglen;
- const char *arg;
- arg = __hwconfig(opt, &arglen, buf);
- if (!arg)
- return 0;
- return !!hwconfig_parse(arg, arglen, subopt, ",;", '=', NULL);
- }
- const char *hwconfig_subarg_f(const char *opt, const char *subopt,
- size_t *subarglen, char *buf)
- {
- size_t arglen;
- const char *arg;
- arg = __hwconfig(opt, &arglen, buf);
- if (!arg)
- return NULL;
- return hwconfig_parse(arg, arglen, subopt, ",;", '=', subarglen);
- }
- int hwconfig_subarg_cmp_f(const char *opt, const char *subopt,
- const char *subarg, char *buf)
- {
- const char *argstr;
- size_t arglen;
- argstr = hwconfig_subarg_f(opt, subopt, &arglen, buf);
- if (!argstr || arglen != strlen(subarg))
- return 0;
- return !strncmp(argstr, subarg, arglen);
- }
- #ifdef HWCONFIG_TEST
- int main()
- {
- const char *ret;
- size_t len;
- setenv("hwconfig", "key1:subkey1=value1,subkey2=value2;key2:value3;;;;"
- "key3;:,:=;key4", 1);
- ret = hwconfig_arg("key1", &len);
- printf("%zd %.*s\n", len, (int)len, ret);
- assert(len == 29);
- assert(hwconfig_arg_cmp("key1", "subkey1=value1,subkey2=value2"));
- assert(!strncmp(ret, "subkey1=value1,subkey2=value2", len));
- ret = hwconfig_subarg("key1", "subkey1", &len);
- printf("%zd %.*s\n", len, (int)len, ret);
- assert(len == 6);
- assert(hwconfig_subarg_cmp("key1", "subkey1", "value1"));
- assert(!strncmp(ret, "value1", len));
- ret = hwconfig_subarg("key1", "subkey2", &len);
- printf("%zd %.*s\n", len, (int)len, ret);
- assert(len == 6);
- assert(hwconfig_subarg_cmp("key1", "subkey2", "value2"));
- assert(!strncmp(ret, "value2", len));
- ret = hwconfig_arg("key2", &len);
- printf("%zd %.*s\n", len, (int)len, ret);
- assert(len == 6);
- assert(hwconfig_arg_cmp("key2", "value3"));
- assert(!strncmp(ret, "value3", len));
- assert(hwconfig("key3"));
- assert(hwconfig_arg("key4", &len) == NULL);
- assert(hwconfig_arg("bogus", &len) == NULL);
- unsetenv("hwconfig");
- assert(hwconfig(NULL) == 0);
- assert(hwconfig("") == 0);
- assert(hwconfig("key3") == 0);
- return 0;
- }
- #endif
|