NEOERR* ltpl_init(HASH **tplh, char *path) { HASH *ltplh = NULL; NEOERR *err; *tplh = NULL; path = path ? path: PATH_TPL"config/run/"; err = hash_init(<plh, 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; }
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; }
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; }
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; }