/* Ok, this version avoids the bubble sort by walking the level once to * load them all into a ULIST, qsort'ing the list, and then dumping them * back out... */ NEOERR *hdf_sort_obj (HDF *h, int (*compareFunc)(const void *, const void *)) { NEOERR *err = STATUS_OK; ULIST *level = NULL; HDF *p, *c; int x; if (h == NULL) return STATUS_OK; c = h->child; if (c == NULL) return STATUS_OK; do { err = uListInit(&level, 40, 0); if (err) return nerr_pass(err); for (p = c; p; p = p->next) { err = uListAppend(level, p); if (err) break; } err = uListSort(level, compareFunc); if (err) break; uListGet(level, 0, (void *)&c); h->child = c; for (x = 1; x < uListLength(level); x++) { uListGet(level, x, (void *)&p); c->next = p; p->next = NULL; c = p; } h->last_child = c; } while (0); uListDestroy(&level, 0); return nerr_pass(err); }
NEOERR *wdb_column_delete (WDB *wdb, const char *name) { WDBColumn *col; NEOERR *err = STATUS_OK; int len, x, r; len = uListLength(wdb->cols_l); for (x = 0; x < len; x++) { err = uListGet (wdb->cols_l, x, (void *)&col); if (err) return nerr_pass(err); if (!strcmp(col->name, name)) { err = uListDelete (wdb->cols_l, x, NULL); if (err) return nerr_pass(err); break; } } r = dictRemove (wdb->cols, name); /* Only failure is key not found */ if (!r) { return nerr_raise (NERR_NOT_FOUND, "Unable to find column for key %s", name); } wdb->defn_dirty = 1; wdb->table_version = rand(); return STATUS_OK; }
NEOERR *wdb_column_update (WDB *wdb, const char *oldkey, const char *newkey) { WDBColumn *ocol, *col; WDBColumn *vcol; NEOERR *err = STATUS_OK; int x, len, r; ocol = (WDBColumn *) dictSearch (wdb->cols, oldkey, NULL); if (ocol == NULL) return nerr_raise (NERR_NOT_FOUND, "Unable to find column for key %s", oldkey); col = (WDBColumn *) calloc (1, sizeof (WDBColumn)); if (col == NULL) { return nerr_raise (NERR_NOMEM, "Unable to allocate memory for column update %s", newkey); } *col = *ocol; col->name = strdup(newkey); if (col->name == NULL) { free(col); return nerr_raise (NERR_NOMEM, "Unable to allocate memory for column update %s", oldkey); } len = uListLength(wdb->cols_l); for (x = 0; x < len; x++) { err = uListGet (wdb->cols_l, x, (void *)&vcol); if (err) return nerr_pass(err); if (!strcmp(vcol->name, oldkey)) { err = uListSet (wdb->cols_l, x, (void *)col); if (err) return nerr_pass(err); break; } } if (x>len) { return nerr_raise (NERR_ASSERT, "Unable to find cols_l for key %s", oldkey); } r = dictRemove (wdb->cols, oldkey); /* Only failure is key not found */ err = dictSetValue(wdb->cols, newkey, col); if (err) { free (col->name); free (col); return nerr_pass_ctx (err, "Unable to insert for update of col %s->%s", oldkey, newkey); } wdb->defn_dirty = 1; wdb->table_version = rand(); return STATUS_OK; }
/* * get fileset's info * inp: urls, url list you want to get * out: files, file list with file_t elements. don't forget free */ int file_get_infos_by_list(mdb_conn *conn, ULIST *urls, ULIST **files, int *noksn) { int listlen; char *url; file_t *file; NEOERR *err; int ret; listlen = uListLength(urls); if (listlen <= 0 || urls == NULL || files == NULL) { return RET_RBTOP_INPUTE; } err = uListInit(files, 0, 0); RETURN_V_NOK(err, RET_RBTOP_MEMALLOCE); int pid = 1; int i; for (i = 0; i < listlen; i++) { err = uListGet(urls, i, (void**)&url); RETURN_V_NOK(err, RET_RBTOP_GETLISTE); ret = file_get_info_by_id(conn, 0, url, pid, &file); if (ret != RET_RBTOP_OK) { mtc_warn("can't get file info for %s", url); *noksn = i; return RET_RBTOP_GETLISTE; } else { pid = file->id; uListAppend(*files, file); } } *noksn = -1; return RET_RBTOP_OK; }
int main(int argc, char **argv) { char *path; ULIST *files = NULL; char *filename; NEOERR *err; int x; if (argc > 1) path = argv[1]; else path = "."; ne_warn("Testing ne_listdir()"); err = ne_listdir(path, &files); if (err) { nerr_log_error(err); return -1; } for (x = 0; x < uListLength(files); x++) { err = uListGet(files, x, (void *)&filename); printf("%s\n", filename); } uListDestroy(&files, ULIST_FREE); ne_warn("Testing ne_listdir_match() with *.c"); err = ne_listdir_match(path, &files, "*.c"); if (err) { nerr_log_error(err); return -1; } for (x = 0; x < uListLength(files); x++) { err = uListGet(files, x, (void *)&filename); printf("%s\n", filename); } uListDestroy(&files, ULIST_FREE); return 0; }
void nerr_error_traceback (NEOERR *err, NEOSTRING *str) { NEOERR *more; char buf[1024]; char buf2[1024]; char *err_name; if (err == STATUS_OK) return; if (err == INTERNAL_ERR) { string_append (str, "Internal error"); return; } more = err; string_append (str, "Traceback (innermost last):\n"); while (more && more != INTERNAL_ERR) { err = more; more = err->next; if (err->error != NERR_PASS) { NEOERR *r; if (err->error == 0) { err_name = buf; snprintf (buf, sizeof (buf), "Unknown Error"); } else { r = uListGet (Errors, err->error - 1, (void *)&err_name); if (r != STATUS_OK) { err_name = buf; snprintf (buf, sizeof (buf), "Error %d", err->error); } } snprintf (buf2, sizeof(buf2), " File \"%s\", line %d, in %s()\n%s: %s\n", err->file, err->lineno, err->func, err_name, err->desc); string_append(str, buf2); } else { snprintf (buf2, sizeof(buf2), " File \"%s\", line %d, in %s()\n", err->file, err->lineno, err->func); string_append(str, buf2); if (err->desc[0]) { snprintf (buf2, sizeof(buf2), " %s\n", err->desc); string_append(str, buf2); } } } }
NEOERR *wdb_keys (WDB *wdb, char **primary_key, ULIST **data) { NEOERR *err; int x, len; WDBColumn *col; ULIST *my_data; char *my_key = NULL; char *my_col = NULL; *data = NULL; *primary_key = NULL; my_key = strdup(wdb->key); if (my_key == NULL) return nerr_raise (NERR_NOMEM, "Unable to allocate memory for keys"); len = uListLength(wdb->cols_l); err = uListInit (&my_data, len, 0); if (err != STATUS_OK) { free(my_key); return nerr_pass(err); } for (x = 0; x < len; x++) { err = uListGet (wdb->cols_l, x, (void *)&col); if (err) goto key_err; my_col = strdup(col->name); if (my_col == NULL) { err = nerr_raise (NERR_NOMEM, "Unable to allocate memory for keys"); goto key_err; } err = uListAppend (my_data, my_col); my_col = NULL; if (err) goto key_err; } *data = my_data; *primary_key = my_key; return STATUS_OK; key_err: if (my_key != NULL) free (my_key); if (my_col != NULL) free (my_col); *primary_key = NULL; uListDestroy (&my_data, 0); return nerr_pass(err); }
NEOERR *wdbr_destroy (WDB *wdb, WDBRow **row) { WDBColumn *col; WDBRow *my_row; int len, x; NEOERR *err; err = STATUS_OK; if (*row == NULL) return err; my_row = *row; /* Verify this row maps to this table, or else we could do something * bad */ if (wdb->table_version != my_row->table_version) return nerr_raise (NERR_ASSERT, "Row %s doesn't match current table", my_row->key_value); if (my_row->key_value != NULL) free (my_row->key_value); len = uListLength(wdb->cols_l); for (x = 0; x < len; x++) { if (my_row->data[x] != NULL) { err = uListGet (wdb->cols_l, x, (void *)&col); if (err) break; switch (col->type) { case WDB_TYPE_INT: break; case WDB_TYPE_STR: free (my_row->data[x]); break; default: return nerr_raise (NERR_ASSERT, "Unknown type %d", col->type); } } } free (my_row); *row = NULL; return nerr_pass(err); }
NEOERR* masset_node_load(char *dir, char *name, RendAsset **pa) { AssetDriver *driver; RendAsset *asset = NULL; int driverindex; HASH *mh; NEOERR *err; mh = hash_lookup(g_datah, ASSET_KEY); MCS_NOT_NULLC(name, pa, mh); *pa = NULL; asset = hash_lookup(mh, name); if (asset) goto done; char *p = strrchr(name, '.'); if (p) p = p + 1; if (!p || !*p) return nerr_raise(NERR_ASSERT, "unknown asset type %s", name); driverindex = uListIndex(asset_drivers, p, asset_driver_comp); if (driverindex < 0) return nerr_raise(NERR_ASSERT, "unknown asset type %s", name); err = uListGet(asset_drivers, driverindex, (void**)&driver); if (err != STATUS_OK) return nerr_pass(err); mtc_dbg("load asset %s%s", dir, name); err = driver->load(dir, name, &asset); if (err != STATUS_OK) return nerr_pass(err); if (!asset) return nerr_raise(NERR_ASSERT, "asset node %s empty", name); asset->name = strdup(name); asset->driverindex = driverindex; hash_remove(mh, name); hash_insert(mh, strdup(name), asset); done: *pa = asset; return STATUS_OK; }
void nerr_error_string (NEOERR *err, NEOSTRING *str) { NEOERR *more; char buf[1024]; char *err_name; if (err == STATUS_OK) return; if (err == INTERNAL_ERR) { string_append (str, "Internal error"); return; } more = err; while (more && more != INTERNAL_ERR) { err = more; more = err->next; if (err->error != NERR_PASS) { NEOERR *r; if (err->error == 0) { err_name = buf; snprintf (buf, sizeof (buf), "Unknown Error"); } else { r = uListGet (Errors, err->error - 1, (void **)&err_name); if (r != STATUS_OK) { err_name = buf; snprintf (buf, sizeof (buf), "Error %d", err->error); } } string_appendf(str, "%s: %s", err_name, err->desc); return; } } }
void masset_node_unload(void *p) { NEOERR *err; if (!p) return; RendAsset *a = p; AssetDriver *driver; err = uListGet(asset_drivers, a->driverindex, (void**)&driver); RETURN_NOK(err); mtc_dbg("unload asset %s", a->name); if (driver) driver->unload(a); SAFE_FREE(a->name); SAFE_FREE(a); /* TODO remove from asset hash table? */ }
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 *pack_row (WDB *wdb, WDBRow *row, void **rdata, int *rdlen) { char *data; int x, len, dlen, dmax; char *s; int n; WDBColumn *col; NEOERR *err; *rdata = NULL; *rdlen = 0; /* allocate */ data = (char *)malloc(sizeof (char) * 1024); if (data == NULL) return nerr_raise (NERR_NOMEM, "Unable to allocate memory to pack row"); dmax = 1024; dlen = 0; PACK_UB4 (data, dlen, dmax, PACK_VERSION_1); /* PACK_UB4 (data, dlen, dmax, time(NULL)); */ len = uListLength(wdb->cols_l); if (len > row->data_count) len = row->data_count; PACK_UB4 (data, dlen, dmax, len); for (x = 0; x < len; x++) { err = uListGet (wdb->cols_l, x, (void *)&col); if (err) goto pack_err; PACK_UB4 (data, dlen, dmax, col->ondisk_index); PACK_BYTE (data, dlen, dmax, col->type); switch (col->type) { case WDB_TYPE_INT: n = (int)(row->data[x]); PACK_UB4 (data, dlen, dmax, n); break; case WDB_TYPE_STR: s = (char *)(row->data[x]); if (s == NULL) { s = ""; } n = strlen(s); PACK_STRING (data, dlen, dmax, n, s); break; default: free (data); return nerr_raise (NERR_ASSERT, "Unknown type %d", col->type); } } *rdata = data; *rdlen = dlen; return STATUS_OK; pack_err: if (data != NULL) free (data); if (err == STATUS_OK) return nerr_raise(NERR_NOMEM, "Unable to allocate memory for pack_row"); return nerr_pass(err); }
static NEOERR *wdb_save_defn_v1 (WDB *wdb, FILE *fp) { NEOERR *err = STATUS_OK; WDBColumn *col; char *s = NULL; char *key = NULL; int r, x, len; char *k = NULL; char *v = NULL; /* Write version string */ r = fprintf (fp, "%s\n", DEFN_VERSION_1); if (!r) goto save_err; err = wdb_encode_str_alloc (wdb->name, &s); if (err) goto save_err; r = fprintf (fp, "name:%s\n", s); if (!r) goto save_err; free (s); err = wdb_encode_str_alloc (wdb->key, &s); if (err != STATUS_OK) goto save_err; r = fprintf (fp, "key:%s\n", s); if (!r) goto save_err; free (s); s = NULL; r = fprintf (fp, "ondisk:%d\n", wdb->last_ondisk); if (!r) goto save_err; r = fprintf (fp, "attributes\n"); if (!r) goto save_err; key = NULL; s = (char *) dictNext (wdb->attrs, &key, NULL); while (s) { err = wdb_encode_str_alloc (key, &k); if (err != STATUS_OK) goto save_err; err = wdb_encode_str_alloc (s, &v); if (err != STATUS_OK) goto save_err; r = fprintf (fp, "%s:%s\n", k, v); if (!r) goto save_err; free (k); free (v); k = NULL; v = NULL; s = (char *) dictNext (wdb->attrs, &key, NULL); } s = NULL; r = fprintf (fp, "columns\n"); if (!r) goto save_err; len = uListLength(wdb->cols_l); for (x = 0; x < len; x++) { err = uListGet (wdb->cols_l, x, (void *)&col); if (err) goto save_err; err = wdb_encode_str_alloc (col->name, &s); if (err != STATUS_OK) goto save_err; r = fprintf (fp, "%s:%c:%d\n", s, col->type, col->ondisk_index); if (!r) goto save_err; free(s); s = NULL; } return STATUS_OK; save_err: if (s != NULL) free (s); if (k != NULL) free (k); if (v != NULL) free (v); if (err == STATUS_OK) return nerr_pass(err); return nerr_raise (r, "Unable to save defn"); }
NEOERR *wdb_create (WDB **wdb, const char *path, const char *name, const char *key, ULIST *col_def, int flags) { WDB *my_wdb; char d_path[_POSIX_PATH_MAX]; NEOERR *err = STATUS_OK; int x, len, r; char *s; *wdb = NULL; err = wdb_alloc (&my_wdb, flags); if (err) return nerr_pass(err); my_wdb->name = strdup (name); my_wdb->key = strdup (key); my_wdb->path = strdup(path); if (my_wdb->name == NULL || my_wdb->key == NULL || my_wdb->path == NULL) { wdb_destroy (&my_wdb); return nerr_raise (NERR_NOMEM, "Unable to allocate memory for creation of %s", name); } /* ondisk must start at one because of skipList */ my_wdb->last_ondisk = 1; len = uListLength(col_def); for (x = 0; x < len; x++) { err = uListGet (col_def, x, (void *)&s); if (err) { wdb_destroy (&my_wdb); return nerr_pass(err); } err = wdb_column_insert (my_wdb, -1, s, WDB_TYPE_STR); my_wdb->defn_dirty = 0; /* So we don't save on error destroy */ if (err) { wdb_destroy (&my_wdb); return nerr_pass(err); } } err = wdb_save_defn (my_wdb, path); if (err) { wdb_destroy (&my_wdb); return nerr_pass(err); } snprintf (d_path, sizeof(d_path), "%s.wdb", path); r = db_open(d_path, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0, NULL, NULL, &(my_wdb->db)); if (r) { wdb_destroy (&my_wdb); return nerr_raise (NERR_DB, "Unable to create db file %s: %d", d_path, r); } *wdb = my_wdb; return STATUS_OK; }