Beispiel #1
0
NEOERR* ltpl_init(HASH **tplh, char *path)
{
    HASH *ltplh = NULL;
    NEOERR *err;

    *tplh = NULL;
    
    path = path ? path: PATH_TPL"config/run/";
	
    err = hash_init(&ltplh, hash_str_hash, hash_str_comp);
    if (err != STATUS_OK) return nerr_pass(err);

    err = ltpl_parse_dir(path, ltplh);
    if (err != STATUS_OK) return nerr_pass_ctx(err, "pase dir %s", path);
    
    *tplh = ltplh;
    return STATUS_OK;
}
Beispiel #2
0
NEOERR* ldml_init(HASH **datah, char *path)
{
    HASH *ldatah = NULL;
    char path_data[_POSIX_PATH_MAX], *temps;
    NEOERR *err;

    *datah = NULL;

    temps = hdf_get_value(g_cfg, PRE_CONFIG".site_path", NULL);
    if (!temps || *temps == '\0') temps = PATH_SITE;

    snprintf(path_data, sizeof(path_data), "%s/%s/", temps, PATH_DATA);

    path = path ? path: path_data;

    err = hash_init(&ldatah, hash_str_hash, hash_str_comp, hash_str_free);
    if (err != STATUS_OK) return nerr_pass(err);

    err = ldml_parse_dir(path, ldatah);
    if (err != STATUS_OK) return nerr_pass_ctx(err, "pase dir %s", path);

    *datah = ldatah;
    return STATUS_OK;
}
NEOERR *wdb_column_insert (WDB *wdb, int loc, const char *key, char type)
{
  NEOERR *err;
  WDBColumn *col, *ocol;
  int x, len;

  col = (WDBColumn *) dictSearch (wdb->cols, key, NULL);

  if (col != NULL)
    return nerr_raise (NERR_DUPLICATE, 
	"Duplicate key %s:%d", key, col->inmem_index);

  col = (WDBColumn *) calloc (1, sizeof (WDBColumn));
  if (col == NULL)
  {
    return nerr_raise (NERR_NOMEM, 
	"Unable to allocate memory for creation of col %s:%d", key, loc);
  }

  col->name = strdup(key);
  if (col->name == NULL)
  {
    free(col);
    return nerr_raise (NERR_NOMEM, 
	"Unable to allocate memory for creation of col %s:%d", key, loc);
  }
  col->type = type;
  col->ondisk_index = wdb->last_ondisk++;
  /* -1 == append */
  if (loc == -1)
  {
    err = dictSetValue(wdb->cols, key, col);
    if (err)
    {
      free (col->name);
      free (col);
      return nerr_pass_ctx (err,
	  "Unable to insert for creation of col %s:%d", key, loc);
    }
    err = uListAppend (wdb->cols_l, (void *)col);
    if (err) return nerr_pass(err);
    x = uListLength (wdb->cols_l);
    col->inmem_index = x;
    err = skipInsert (wdb->ondisk, col->ondisk_index, 
	            (void *)(col->inmem_index), 0);
    if (err)
      return nerr_pass_ctx (err, "Unable to update ondisk mapping for %s", key);
  }
  else
  {
    /* We are inserting this in middle, so the skipList ondisk is now
     * invalid, as is the inmem_index for all cols */
    err = dictSetValue(wdb->cols, key, col);
    if (err)
    {
      free (col->name);
      free (col);
      return nerr_pass_ctx (err,
	  "Unable to insert for creation of col %s:%d", key, loc);
    }
    err = uListInsert (wdb->cols_l, loc, (void *)col);
    if (err) return nerr_pass(err);
    len = uListLength (wdb->cols_l);
    /* Fix up inmem_index and ondisk skipList */
    for (x = 0; x < len; x++)
    {
      err = uListGet (wdb->cols_l, x, (void *)&ocol);
      if (err) return nerr_pass(err);
      ocol->inmem_index = x + 1;
      err = skipInsert (wdb->ondisk, ocol->ondisk_index, 
	              (void *)(ocol->inmem_index), TRUE);
      if (err)
	return nerr_pass_ctx (err, "Unable to update ondisk mapping for %s", key);
    }
  }

  wdb->defn_dirty = 1;
  wdb->table_version = rand();

  return STATUS_OK;
}
static NEOERR *wdb_load_defn_v1 (WDB *wdb, FILE *fp)
{
  char line[1024];
  int state = 1;
  char *k, *v;
  NEOERR *err = STATUS_OK;
  int colindex = 1;
  WDBColumn *col;

  while (fgets(line, sizeof(line), fp) != NULL)
  {
    string_rstrip(line);
    switch (state)
    {
      case STATE_REQUIRED:
	if (!strcmp(line, "attributes"))
	  state = STATE_ATTRIBUTES;
	else if (!strcmp(line, "columns"))
	  state = STATE_COLUMN_DEF;
	else
	{
	  k = line;
	  v = strchr(line, ':');
	  /* HACK */
	  if (!strcmp(k, "name") && ((v == NULL) || (v[1] == '\0')))
	  {
	    v = "dNone";
	  }
	  else 
	  {
	    if (v == NULL)
	      return nerr_raise (NERR_PARSE, "Error parsing %s", line);
	    if (v[1] == '\0')
	      return nerr_raise (NERR_PARSE, "Error parsing %s", line);
	  }
	  v[0] = '\0';
	  v++;
	  if (!strcmp(k, "key"))
	  { 
	    err = wdb_decode_str_alloc (v, &(wdb->key));
	    if (err) return nerr_pass(err);
	  } 
	  else if (!strcmp(k, "name"))
	  {
	    err = wdb_decode_str_alloc (v, &(wdb->name));
	    if (err) return nerr_pass(err);
	  }
	  else if (!strcmp(k, "ondisk"))
	  {
	    wdb->last_ondisk = atoi (v);
	  }
	}
	break;
      case STATE_ATTRIBUTES:
	if (!strcmp(line, "columns"))
	  state = STATE_COLUMN_DEF;
	else
	{
	  k = line;
	  v = strchr(line, ':');
	  if (v == NULL)
	    return nerr_raise (NERR_PARSE, "Error parsing %s", line);
	  v[0] = '\0';
	  v++;
	  err = wdb_decode_str_alloc (k, &k);
	  if (err) return nerr_pass(err);
	  err = wdb_decode_str_alloc (v, &v);
	  if (err) return nerr_pass(err);
	  err = dictSetValue(wdb->attrs, k, v);
	  free(k);
	  if (err)
	    return nerr_pass_ctx(err, "Error parsing %s", line);
	}
	break;
      case STATE_COLUMN_DEF:
	k = line;
	v = strchr(line, ':');
	if (v == NULL)
	  return nerr_raise (NERR_PARSE, "Error parsing %s", line);
	if (v[1] == '\0')
	  return nerr_raise (NERR_PARSE, "Error parsing %s", line);
	v[0] = '\0';
	v++;
	err = wdb_decode_str_alloc (k, &k);
	if (err) return nerr_pass(err);
	col = (WDBColumn *) calloc (1, sizeof (WDBColumn));
	col->name = k;
	col->inmem_index = colindex++;
	col->type = *v;
	v+=2;
	col->ondisk_index = atoi(v);
	err = dictSetValue(wdb->cols, k, col);
	if (err)
	  return nerr_raise (NERR_PARSE, "Error parsing %s", line);
	err = uListAppend(wdb->cols_l, col);
	if (err) return nerr_pass(err);
	/* stupid skiplist will assert */
	if (col->ondisk_index == 0)
	{
	  return nerr_raise (NERR_ASSERT, "Invalid ondisk mapping for %s", k);
	}
	err = skipInsert (wdb->ondisk, col->ondisk_index, 
	    (void *)(col->inmem_index), 0);
	if (err)
	  return nerr_pass_ctx(err, "Unable to update ondisk mapping for %s", k);
	break;
      default:
	return nerr_raise (NERR_ASSERT, "Invalid state %d", state);
    }
  }
  return STATUS_OK;
}
Beispiel #5
0
static NEOERR* _hdf_read_string (HDF *hdf, const char **str, STRING *line,
                                 const char *path, int *lineno,
                                 int include_handle)
{
  NEOERR *err;
  HDF *lower;
  char *s;
  char *name, *value;
  HDF_ATTR *attr = NULL;

  while (**str != '\0')
  {
    /* Reset string length, but don't free the reserved buffer */
    line->len = 0;
    err = _copy_line_advance(str, line);
    if (err) return nerr_pass(err);
    attr = NULL;
    (*lineno)++;
    s = line->buf;
    SKIPWS(s);
    if (!strncmp(s, "#include ", 9) && include_handle != INCLUDE_IGNORE)
    {
      if (include_handle == INCLUDE_ERROR)
      {
	return nerr_raise (NERR_PARSE,
                           "[%d]: #include not supported in string parse",
                           *lineno);
      }
      else if (include_handle < INCLUDE_MAX_DEPTH)
      {
        int l;
        s += 9;
        name = neos_strip(s);
        l = strlen(name);
        if (name[0] == '"' && name[l-1] == '"')
        {
          name[l-1] = '\0';
          name++;
        }
        err = hdf_read_file_internal(hdf, name, include_handle + 1);
        if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else
      {
        return nerr_raise (NERR_MAX_RECURSION,
                                     "[%d]: Too many recursion levels.",
                                     *lineno
                                     );
      }
    }
    else if (s[0] == '#')
    {
      /* comment: pass */
    }
    else if (s[0] == '}') /* up */
    {
      s = neos_strip(s);
      if (strcmp(s, "}"))
      {
        err = nerr_raise(NERR_PARSE,
	    "[%s:%d] Trailing garbage on line following }: %s", path, *lineno,
	    line->buf);
        return err;
      }
      return STATUS_OK;
    }
    else if (s[0])
    {
      /* Valid hdf name is [0-9a-zA-Z_.]+ */
      name = s;
      while (*s && (isalnum(*s) || *s == '_' || *s == '.' || *(unsigned char*)s > 127)) s++;
      SKIPWS(s);

      if (s[0] == '[') /* attributes */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	err = parse_attr(&s, &attr);
	if (err)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	SKIPWS(s);
      }
      if (s[0] == '=') /* assignment */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':' && s[1] == '=') /* copy */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	value = hdf_get_value(hdf->top, value, "");
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':') /* link */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 1, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '{') /* deeper */
      {
	*s = '\0';
	name = neos_strip(name);
	lower = hdf_get_obj (hdf, name);
	if (lower == NULL)
	{
	  err = _set_value (hdf, name, NULL, 1, 1, 0, attr, &lower);
	}
	else
	{
	  err = _set_value (lower, NULL, lower->value, 1, 1, 0, attr, NULL);
	}
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	err = _hdf_read_string (lower, str, line, path, lineno, include_handle);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '<' && s[1] == '<') /* multi-line assignment */
      {
	char *m;
	int msize = 0;
	int mmax = 128;
	int l;

	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	l = strlen(value);
	if (l == 0)
        {
	  err = nerr_raise(NERR_PARSE,
	      "[%s:%d] No multi-assignment terminator given: %s", path, *lineno,
	      line->buf);
          return err;
        }
	m = (char *) malloc (mmax * sizeof(char));
	if (m == NULL)
        {
	  return nerr_raise(NERR_NOMEM,
	    "[%s:%d] Unable to allocate memory for multi-line assignment to %s",
	    path, *lineno, name);
        }
	while (_copy_line (str, m+msize, mmax-msize) != 0)
	{
          (*lineno)++;
	  if (!strncmp(value, m+msize, l) && isspace(m[msize+l]))
	  {
	    m[msize] = '\0';
	    break;
	  }
	  msize += strlen(m+msize);
	  if (msize + l + 10 > mmax)
	  {
            void *new_ptr;
	    mmax += 128;
	    new_ptr = realloc (m, mmax * sizeof(char));
	    if (new_ptr == NULL)
            {
              free(m);
	      return nerr_raise(NERR_NOMEM,
		  "[%s:%d] Unable to allocate memory for multi-line assignment to %s: size=%d",
		  path, *lineno, name, mmax);
            }
            m = (char *) new_ptr;
	  }
	}
	err = _set_value (hdf, name, m, 0, 1, 0, attr, NULL);
	if (err != STATUS_OK)
	{
	  free (m);
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
	}

      }
      else
      {
	err = nerr_raise(NERR_PARSE, "[%s:%d] Unable to parse line %s", path,
	    *lineno, line->buf);
        return err;
      }
    }
  }
  return STATUS_OK;
}
Beispiel #6
0
static NEOERR* _hdf_read_string (HDF *hdf, const char **str, STRING *line,
                                 const char *path, int *lineno,
                                 int include_handle, int expect_end_brace) {
  NEOERR *err;
  HDF *lower;
  char *s;
  char *name, *value;
  HDF_ATTR *attr = NULL;

  while (**str != '\0')
  {
    /* Reset string length, but don't free the reserved buffer */
    line->len = 0;
    err = _copy_line_advance(str, line);
    if (err) return nerr_pass(err);
    attr = NULL;
    (*lineno)++;
    s = line->buf;
    SKIPWS(s);
    if ((!strncmp(s, "#include ", 9) || !strncmp(s, "-include ", 9)) && include_handle != INCLUDE_IGNORE)
    {
      int required = !strncmp(s, "#include ", 9);
      if (include_handle == INCLUDE_ERROR)
      {
	return nerr_raise (NERR_PARSE,
                           "[%d]: #include not supported in string parse",
                           *lineno);
      }
      else if (include_handle < INCLUDE_MAX_DEPTH)
      {
        int l;
        s += 9;
        name = neos_strip(s);
        l = strlen(name);
        if (name[0] == '"' && name[l-1] == '"')
        {
          name[l-1] = '\0';
          name++;
        }
        char fullpath[PATH_MAX];
        if (name[0] != '/') {
          memset(fullpath, 0, PATH_MAX);

          char *p = strrchr(path, '/');
          if (p == NULL) {
            char pwd[PATH_MAX];
            memset(pwd, 0, PATH_MAX);
            getcwd(pwd, PATH_MAX);
            snprintf(fullpath, PATH_MAX, "%s/%s", pwd, name);
          } else {
            int dir_len = p - path + 1;
            snprintf(fullpath, PATH_MAX, "%s", path);
            snprintf(fullpath + dir_len, PATH_MAX - dir_len, "%s", name);
          }
          name = fullpath;
        }
        err = hdf_read_file_internal(hdf, name, include_handle + 1);
        if (err != STATUS_OK && required)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else {
        return nerr_raise (NERR_MAX_RECURSION,
                           "[%d]: Too many recursion levels.",
                           *lineno
                           );
      }
    }
    else if (s[0] == '#')
    {
      /* comment: pass */
    }
    else if (s[0] == '}') /* up */
    {
      s = neos_strip(s);
      if (strcmp(s, "}"))
      {
        err = nerr_raise(NERR_PARSE,
	    "[%s:%d] Trailing garbage on line following }: %s", path, *lineno,
	    line->buf);
        return err;
      }
      return STATUS_OK;
    }
    else if (s[0])
    {
      /* Valid hdf name is [0-9a-zA-Z_.]+ */
      int splice = *s == '@';
      if (splice) s++;
      name = s;
      while (*s && (isalnum(*s) || *s == '_' || *s == '.' || *s == '*')) s++;
      SKIPWS(s);

      char num[16];
      static int counter = 0;
      if (*name == '*') {
        snprintf(num, sizeof(num), "%d", counter++);
        name = num;
      }

      if (s[0] == '[') /* attributes */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	err = parse_attr(&s, &attr);
	if (err)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	SKIPWS(s);
      }
      if (splice) {
        name = neos_strip(name);
        HDF *h = hdf_get_obj(hdf->top, name);
        if (h) {
          HDF *c = hdf_obj_child(h);
          while (c) {
            err = hdf_copy (hdf, hdf_obj_name(c), c);
            if (err != STATUS_OK) break;
            c = hdf_obj_next(c);
          }
        }
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      } else if (s[0] == '=') /* assignment */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':' && s[1] == '=') /* copy */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
        HDF *h = hdf_get_obj(hdf->top, value);
        if (!h)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to copy a node that is not loaded "
                           "yet: %s", path, *lineno, value);
          return err;
        }
        err = hdf_copy(hdf, name, h);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '!' && s[1] == '=') /* exec */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);

        FILE *f = popen(value, "r");
	if (f == NULL)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to exec specified command: %s",
                           path, *lineno, line->buf);
          return err;
        }
        char *content = _read_file(f);
        fclose(f);
        int len = strlen(content);
        if (len > 0 && content[len - 1] == '\n') {
          content[len - 1] = '\0'; // remove \n artifact
        }
	err = _set_value (hdf, name, content, 1, 1, 0, attr, NULL);
        free(content);

	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':') /* link */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 1, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '{') /* deeper */
      {
	*s = '\0';
	name = neos_strip(name);
	lower = hdf_get_obj (hdf, name);
	if (lower == NULL)
	{
	  err = _set_value (hdf, name, NULL, 1, 1, 0, attr, &lower);
	}
	else
	{
	  err = _set_value (lower, NULL, lower->value, 1, 1, 0, attr, NULL);
	}
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	err = _hdf_read_string (lower, str, line, path, lineno, include_handle,
                                1);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '<' && s[1] == '<') /* multi-line assignment */
      {
	char *m;
	int msize = 0;
	int mmax = 128;
	int l;

	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	l = strlen(value);
	if (l == 0)
        {
	  err = nerr_raise(NERR_PARSE,
	      "[%s:%d] No multi-assignment terminator given: %s", path, *lineno,
	      line->buf);
          return err;
        }
	m = (char *) malloc (mmax * sizeof(char));
	if (m == NULL)
        {
	  return nerr_raise(NERR_NOMEM,
	    "[%s:%d] Unable to allocate memory for multi-line assignment to %s",
	    path, *lineno, name);
        }
	while (_copy_line (str, m+msize, mmax-msize) != 0)
	{
          (*lineno)++;
	  if (!strncmp(value, m+msize, l) && isspace(m[msize+l]))
	  {
	    m[msize] = '\0';
	    break;
	  }
	  msize += strlen(m+msize);
	  if (msize + l + 10 > mmax)
	  {
	    void *new_ptr;
	    mmax += 128;
	    new_ptr = realloc (m, mmax * sizeof(char));
	    if (new_ptr == NULL)
	    {
        free(m);
	      return nerr_raise(NERR_NOMEM,
		  "[%s:%d] Unable to allocate memory for multi-line assignment to %s: size=%d",
		  path, *lineno, name, mmax);
      }
      m = (char *) new_ptr;
	  }
	}
	err = _set_value (hdf, name, m, 0, 1, 0, attr, NULL);
	if (err != STATUS_OK)
	{
	  free (m);
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
	}

      }
      else
      {
	err = nerr_raise(NERR_PARSE, "[%s:%d] Unable to parse line %s", path,
	    *lineno, line->buf);
        return err;
      }
    }
  }
  if (expect_end_brace) {
    err = nerr_raise(NERR_PARSE, "[%s:%d] Missing matching }", path, *lineno);
    return err;
  }
  return STATUS_OK;
}