in system/settings/settings.c [1111:1295]
int settings_create(FAR char *key, enum settings_type_e type, ...)
{
int ret = OK;
FAR setting_t *setting = NULL;
int j;
if (!g_settings.initialized)
{
assert(0);
}
assert(type != SETTING_EMPTY);
assert(strlen(key));
if (strlen(key) == 0)
{
return -EINVAL;
}
assert(strlen(key) < CONFIG_SYSTEM_SETTINGS_KEY_SIZE);
if (strlen(key) >= CONFIG_SYSTEM_SETTINGS_KEY_SIZE)
{
return -EINVAL;
}
assert(isalpha(key[0]) && (sanity_check(key) == OK));
if (!isalpha(key[0]) || (sanity_check(key) < 0))
{
return -EINVAL;
}
ret = pthread_mutex_lock(&g_settings.mtx);
if (ret < 0)
{
return ret;
}
for (j = 0; j < CONFIG_SYSTEM_SETTINGS_MAP_SIZE; j++)
{
if (strcmp(key, map[j].key) == 0)
{
setting = &map[j];
/* We found a setting with this key name */
goto errout;
}
if (map[j].type == SETTING_EMPTY)
{
setting = &map[j];
strncpy(setting->key, key, CONFIG_SYSTEM_SETTINGS_KEY_SIZE);
setting->key[CONFIG_SYSTEM_SETTINGS_KEY_SIZE - 1] = '\0';
/* This setting is empty/unused - we can use it */
break;
}
}
assert(setting);
if (setting == NULL)
{
goto errout;
}
if ((setting->type == SETTING_EMPTY) ||
(setting->type != type))
{
bool set_val = false;
va_list ap;
va_start(ap, type);
switch (type)
{
case SETTING_STRING:
{
FAR char *str = va_arg(ap, FAR char *);
if ((setting->type == SETTING_STRING) ||
(setting->type == SETTING_IP_ADDR))
{
break;
}
set_val = true;
setting->type = SETTING_STRING;
ret = set_string(setting, str);
}
break;
case SETTING_INT:
{
int i = va_arg(ap, int);
if ((setting->type == SETTING_INT) ||
(setting->type == SETTING_BOOL) ||
(setting->type == SETTING_FLOAT))
{
break;
}
set_val = true;
setting->type = SETTING_INT;
ret = set_int(setting, i);
}
break;
case SETTING_BOOL:
{
int i = va_arg(ap, int);
if ((setting->type == SETTING_BOOL) ||
(setting->type == SETTING_INT))
{
break;
}
set_val = true;
setting->type = SETTING_BOOL;
ret = set_bool(setting, i);
}
break;
case SETTING_FLOAT:
{
double f = va_arg(ap, double);
if ((setting->type == SETTING_FLOAT) ||
(setting->type == SETTING_INT))
{
break;
}
set_val = true;
setting->type = SETTING_FLOAT;
ret = set_float(setting, f);
}
break;
case SETTING_IP_ADDR:
{
FAR struct in_addr *ip = va_arg(ap, FAR struct in_addr *);
if ((setting->type == SETTING_IP_ADDR) ||
(setting->type == SETTING_STRING))
{
break;
}
set_val = true;
setting->type = SETTING_IP_ADDR;
ret = set_ip(setting, ip);
}
break;
default:
case SETTING_EMPTY:
{
assert(0);
ret = -EINVAL;
}
break;
}
va_end(ap);
if ((ret < 0) || !set_val)
{
memset(setting, 0, sizeof(setting_t));
setting = NULL;
}
else
{
g_settings.hash = hash_calc();
save();
}
}
errout:
pthread_mutex_unlock(&g_settings.mtx);
return ret;
}