int settings_create()

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;
}