From f51dd128c16fd6c654bdfbdcb19204bf9a867fe5 Mon Sep 17 00:00:00 2001 From: dinesh Date: Mon, 21 Jul 2008 09:18:42 +0530 Subject: [PATCH] commiting _info to json convertor --- tools/_infotojson/database.h | 30 ++++ tools/_infotojson/infotojson.c | 214 +++++++++++++++++++++++++++ tools/_infotojson/infotojson.h | 36 +++++ tools/_infotojson/sqlite3_database.c | 103 +++++++++++++ tools/_infotojson/utils.c | 55 +++++++ tools/_infotojson/utils.h | 17 +++ 6 files changed, 455 insertions(+) create mode 100644 tools/_infotojson/database.h create mode 100644 tools/_infotojson/infotojson.c create mode 100644 tools/_infotojson/infotojson.h create mode 100644 tools/_infotojson/sqlite3_database.c create mode 100644 tools/_infotojson/utils.c create mode 100644 tools/_infotojson/utils.h diff --git a/tools/_infotojson/database.h b/tools/_infotojson/database.h new file mode 100644 index 00000000..7081df43 --- /dev/null +++ b/tools/_infotojson/database.h @@ -0,0 +1,30 @@ +/* Simple SQL-style database ops. Currently implemented for sqlite3. */ +//#ifndef _UPLOAD_ANALYSIS_DATABASE_H +//#define _UPLOAD_ANALYSIS_DATABASE_H +#include + +/* Returns handle to the database.. */ +void *db_open(const char *file); + +/* Runs query (SELECT). Fills in columns. */ +struct db_query +{ + unsigned int num_rows; + char ***rows; +}; + +struct db_query *db_query(void *h, const char *query); + +/* Runs command (CREATE TABLE/INSERT) */ +void db_command(void *h, const char *command); + +/* Starts transaction. Doesn't need to nest. */ +//void db_transaction_start(void *h); + +/* Finishes transaction, or rolls it back and caller needs to start again. */ +//bool db_transaction_finish(void *h); + +/* Closes database (only called when everything OK). */ +void db_close(void *h); + +//#endif /* _UPLOAD_ANALYSIS_DATABASE_H */ diff --git a/tools/_infotojson/infotojson.c b/tools/_infotojson/infotojson.c new file mode 100644 index 00000000..dd90dc2a --- /dev/null +++ b/tools/_infotojson/infotojson.c @@ -0,0 +1,214 @@ +/* This extract info from _info.c and create json file and also optionally store to db */ +#include "infotojson.h" + +/* Is A == B ? */ +#define streq(a,b) (strcmp((a),(b)) == 0) + +/* Does A start with B ? */ +#define strstarts(a,b) (strncmp((a),(b),strlen(b)) == 0) + +/* This version adds one byte (for nul term) */ +static void *grab_file(void *ctx, const char *filename) +{ + unsigned int max = 16384, size = 0; + int ret, fd; + char *buffer; + + if (streq(filename, "-")) + fd = dup(STDIN_FILENO); + else + fd = open(filename, O_RDONLY, 0); + + if (fd < 0) + return NULL; + + buffer = talloc_array(ctx, char, max+1); + while ((ret = read(fd, buffer + size, max - size)) > 0) { + size += ret; + if (size == max) + buffer = talloc_realloc(ctx, buffer, char, max*=2 + 1); + } + if (ret < 0) { + talloc_free(buffer); + buffer = NULL; + } else + buffer[size] = '\0'; + close(fd); + return buffer; +} + +/* This is a dumb one which copies. We could mangle instead. */ +static char **split(const char *text) +{ + char **lines = NULL; + unsigned int max = 64, num = 0; + + lines = talloc_array(text, char *, max+1); + + while (*text != '\0') { + unsigned int len = strcspn(text, "\n"); + lines[num] = talloc_array(lines, char, len + 1); + memcpy(lines[num], text, len); + lines[num][len] = '\0'; + text += len + 1; + if (++num == max) + lines = talloc_realloc(text, lines, char *, max*=2 + 1); + } + lines[num] = NULL; + return lines; +} + +/*combin desc into an array to write to db*/ +static char *combinedesc(char **desc) +{ + unsigned int i = 0, size = 0;; + char *combine; + + for(i = 0; desc[i]; i++) + size += strlen(desc[i]); + + combine = (char *)palloc((size + i)* sizeof(char)); + strcpy(combine, desc[0]); + + for(i = 1; desc[i]; i++) { + strcat(combine, "\n"); + strcat(combine, desc[i]); + } + strreplace(combine,'\'',' '); + return combine; +} + +/*creating json structure for storing to file/db*/ +struct json * createjson(char **infofile, char *author) +{ + struct json *jsonobj; + unsigned int modulename; + + if(infofile == NULL || author == NULL) { + printf("Error Author or Info file is NULL\n"); + exit(1); + } + + jsonobj = (struct json *)palloc(sizeof(struct json)); + + jsonobj->author = author; + + modulename = strchr(infofile[0], '-') - infofile[0]; + jsonobj->module = (char *)palloc(sizeof(char) * (modulename - 1)); + strncpy(jsonobj->module, infofile[0], modulename - 1); + jsonobj->module[modulename - 1] = '\0'; + + jsonobj->title = infofile[0]; + jsonobj->desc = &infofile[1]; + + return jsonobj; +} + +/*extracting title and description from _info.c files*/ +char **extractinfo(char **file) +{ + char **infofile = NULL; + unsigned int count = 0, j = 0, size = 0; + bool printing = false; + + while(file[size++]); + infofile = (char **) palloc(size * sizeof(char *)); + + for (j = 0; j < size - 1; j++) { + if (streq(file[j], "/**")) { + printing = true; + } + else if (streq(file[j], " */")) + printing = false; + else if (printing) { + if (strstarts(file[j], " * ")) + infofile[count++] = file[j] + 3; + else if (strstarts(file[j], " *")) + infofile[count++] = file[j] + 2; + else { + printf("Error in comments structure\n%d",j); + exit(1); + } + } + } + infofile[count] = NULL; + return infofile; +} + +/*storing json structure to json file*/ +int storejsontofile(struct json *jsonobj, char *file) +{ + FILE *fp; + unsigned int j = 0; + fp = fopen(file, "wt"); + + fprintf(fp,"\"Module\":\"%s\",\n",jsonobj->module); + fprintf(fp,"\"Title\":\"%s\",\n",jsonobj->title); + fprintf(fp,"\"Author\":\"%s\",\n",jsonobj->author); + fprintf(fp,"\"Description\":[\n"); + while(jsonobj->desc[j++]) + fprintf(fp,"{\n\"str\":\"%s\"\n},\n",jsonobj->desc[j - 1]); + fprintf(fp,"]\n"); + fclose(fp); + return 1; + +} + +/*storing json structure to db*/ +int storejsontodb(struct json *jsonobj, char *db) +{ + char *cmd, *query; + sqlite3 *handle; + char *errstr; + struct db_query *q; + + handle = db_open(db); + + query = aprintf("SELECT module from search where module=\"%s\";", jsonobj->module); + q = db_query(handle, query); + if (!q->num_rows) + cmd = aprintf("INSERT INTO search VALUES(\"%s\",\"%s\",\"%s\",'%s\');", + jsonobj->module, jsonobj->author, jsonobj->title, combinedesc(jsonobj->desc)); + else + cmd = aprintf("UPDATE search set author=\"%s\", title=\"%s\", desc='%s\' where module=\"%s\";", + jsonobj->author, jsonobj->title, combinedesc(jsonobj->desc), jsonobj->module); + + db_command(handle, cmd); + db_close(handle); + return 1; +} + +int main(int argc, char *argv[]) +{ + char *file; + char **lines; + char **infofile; + + struct json *jsonobj = NULL; + + if(argc < 4) { + printf("usage: infotojson infofile jsonfile author sqlitedb\n"); + return 1; + } + + file = grab_file(NULL, argv[1]); + if (!file) + err(1, "Reading file %s", argv[1]); + + lines = split(file); + + //extract info from lines + infofile = extractinfo(lines); + + //create json obj + jsonobj = createjson(infofile, argv[3]); + + //store to file + storejsontofile(jsonobj, argv[2]); + + if(argv[4] != NULL) + storejsontodb(jsonobj, argv[4]); + + talloc_free(file); + return 0; +} diff --git a/tools/_infotojson/infotojson.h b/tools/_infotojson/infotojson.h new file mode 100644 index 00000000..5fb4ad3d --- /dev/null +++ b/tools/_infotojson/infotojson.h @@ -0,0 +1,36 @@ +/** json structure + * This file contains definition of json structure + **/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "database.h" +#include "ccan/talloc/talloc.h" +#include "utils.h" + + struct json + { + char *module; + char *title; + char *author; + char **desc; + }; + + /* Function for storing json structure to file given struct json*/ +int storejsontofile(struct json *jsonobj, char *jsonfile); + +/*Function to store in database*/ +int storejsontodb(struct json *jsonobj, char *db); + +/*create json structure*/ +struct json * createjson(char **infofile, char *author); + +/*Extract info from file*/ +char ** extractinfo(char **file); diff --git a/tools/_infotojson/sqlite3_database.c b/tools/_infotojson/sqlite3_database.c new file mode 100644 index 00000000..ed62aee0 --- /dev/null +++ b/tools/_infotojson/sqlite3_database.c @@ -0,0 +1,103 @@ +/* SQLite3 database backend. */ +#include +#include +#include +#include +#include "database.h" +#include "utils.h" + +/* sqlite3_busy_timeout sleeps for a *second*. What a piece of shit. */ +static int busy(void *unused __attribute__((unused)), int count) +{ + usleep(50000); + + /* If we've been stuck for 1000 iterations (at least 50 + * seconds), give up. */ + return (count < 1000); +} + +void *db_open(const char *file) +{ + sqlite3 *handle; + + int err = sqlite3_open(file, &handle); + if (err != SQLITE_OK) + printf("Error %i from sqlite3_open of db '%s'\n", err, file); + sqlite3_busy_handler(handle, busy, NULL); + + return handle; +} + +static int query_cb(void *data, int num, char**vals, + char**names __attribute__((unused))) +{ + int i; + struct db_query *query = data; + query->rows = realloc_array(query->rows, query->num_rows+1); + query->rows[query->num_rows] = new_array(char *, num); + for (i = 0; i < num; i++) { + /* We don't count rows with NULL results + * (eg. count(*),player where count turns out to be + * zero. */ + if (!vals[i]) + return 0; + query->rows[query->num_rows][i] = strdup(vals[i]); + } + query->num_rows++; + return 0; +} + +/* Runs query (SELECT). Fails if > 1 row returned. Fills in columns. */ +struct db_query *db_query(void *h, const char *query) +{ + struct db_query *ret; + char *err; + + ret = (struct db_query*) palloc(sizeof(struct db_query)); + ret->rows = NULL; + ret->num_rows = 0; + if (sqlite3_exec(h, query, query_cb, ret, &err) != SQLITE_OK) + printf("Failed sqlite3 query '%s': %s", query, err); + return ret; +} + +/* Runs command (CREATE TABLE/INSERT) */ +void db_command(void *h, const char *command) +{ + char *err; + + if (sqlite3_exec(h, command, NULL, NULL, &err) != SQLITE_OK) + printf("Failed sqlite3 command '%s': %s", command, err); +} + +/* Starts transaction. Doesn't need to nest. */ +/*void db_transaction_start(void *h) +{ + char *err; + if (sqlite3_exec(h, "BEGIN EXCLUSIVE TRANSACTION", NULL, NULL, &err)!=SQLITE_OK) + printf("Starting sqlite3 transaction: %s\n", err); +} + +/* Finishes transaction, or rolls it back and caller needs to start again. */ +/* +bool db_transaction_finish(void *h) +{ + switch (sqlite3_exec(h, "COMMIT TRANSACTION;", NULL, NULL, NULL)) { + case SQLITE_OK: + return true; + case SQLITE_BUSY: + if (sqlite3_exec(h, "ROLLBACK TRANSACTION;", NULL, NULL, NULL) + != SQLITE_OK) + printf("Ending sqlite3 busy rollback failed"); + return false; + default: + printf("Strange sqlite3 error return from COMMIT"); + } +}*/ + +/* Closes database (only called when everything OK). */ +void db_close(void *h) +{ + sqlite3_close(h); +} + diff --git a/tools/_infotojson/utils.c b/tools/_infotojson/utils.c new file mode 100644 index 00000000..9f99972d --- /dev/null +++ b/tools/_infotojson/utils.c @@ -0,0 +1,55 @@ +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" + +void * palloc(int size) +{ + void *p; + p = malloc(size); + if(p == NULL) { + printf("Error Malloc does not allocate\n"); + exit(1); + } + return p; +} + +char *aprintf(const char *fmt, ...) +{ + char *ret; + va_list arglist; + + va_start(arglist, fmt); + vasprintf(&ret, fmt, arglist); + va_end(arglist); + return ret; +} + +int strreplace(char * str, char src, char dest) +{ + int i; + for(i = 0; str[i]; i++) + if(str[i] == src) + str[i] = dest; +} + +void *_realloc_array(void *ptr, size_t size, size_t num) +{ + if (num >= SIZE_MAX/size) + return NULL; + return realloc_nofail(ptr, size * num); +} + +void *realloc_nofail(void *ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr) + return ptr; + printf("realloc of %zu failed", size); +} diff --git a/tools/_infotojson/utils.h b/tools/_infotojson/utils.h new file mode 100644 index 00000000..4a94e573 --- /dev/null +++ b/tools/_infotojson/utils.h @@ -0,0 +1,17 @@ +#include +#include +#include + + +#define new_array(type, num) realloc_array((type *)0, (num)) +#define realloc_array(ptr, num) ((__typeof__(ptr))_realloc_array((ptr), sizeof((*ptr)), (num))) + +void *realloc_nofail(void *ptr, size_t size); + +void *_realloc_array(void *ptr, size_t size, size_t num); + +void * palloc(int size); + +char *aprintf(const char *fmt, ...); + +int strreplace(char * str, char src, char dest); -- 2.39.2