diff options
| author | ame <[email protected]> | 2023-12-28 19:02:03 -0600 |
|---|---|---|
| committer | ame <[email protected]> | 2023-12-28 19:02:03 -0600 |
| commit | 6c0a32d32ee310a78a8c5651dca443d378bb1f32 (patch) | |
| tree | 6a266ec7e4f61e90c23ce6df557203f948d36d29 | |
| parent | 730313437437a9495390b7c2f0a6eded3dbc2653 (diff) | |
json parsing :p
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | docs/io.md | 9 | ||||
| -rw-r--r-- | readme.md | 2 | ||||
| -rw-r--r-- | src/i_str.c | 35 | ||||
| -rw-r--r-- | src/i_str.h | 14 | ||||
| -rw-r--r-- | src/io.c | 102 | ||||
| -rw-r--r-- | src/io.h | 3 |
7 files changed, 167 insertions, 0 deletions
@@ -1,2 +1,4 @@ *.so *.lua +a.out +*.json @@ -42,3 +42,12 @@ llib.io.readfile("./docs/io.md") -- (this file) - file_chunksize (512) - size of chunk to be allocated +### json_parse + +'accepts a json string + +returns a table represented by the string + +```lua +llib.io.json_parse('{"test":[5,4,3]}') -- {"test" : {5, 4, 3}} +``` @@ -8,3 +8,5 @@ todo: - (working on seperatley) gui for graphs - fix -O3 breaking some hashes (not sure if i care) + + - fix pprint (make it look better) diff --git a/src/i_str.c b/src/i_str.c new file mode 100644 index 0000000..804a33d --- /dev/null +++ b/src/i_str.c @@ -0,0 +1,35 @@ +#include "i_str.h" + +str* str_init(char* init){ + if(init == NULL){ + char cc = '\0'; + init = &cc; + } + + size_t len = strlen(init); + str* s = malloc(sizeof * s); + s->c = malloc(len + 1); + s->len = len ; + + memcpy(s->c, init, len + 1); + return s; +} + +void str_free(str* s){ + free(s->c); + return free(s); +} + +void str_push(str* s, char* insert){ + s->len += strlen(insert); + s->c = realloc(s->c, s->len + 5); + strcat(s->c, insert); +} + +void str_clear(str* s){ + memset(s->c, 0, s->len); + + s->len = 0; +} + + diff --git a/src/i_str.h b/src/i_str.h new file mode 100644 index 0000000..18409bf --- /dev/null +++ b/src/i_str.h @@ -0,0 +1,14 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +typedef struct { + size_t len; + size_t _bytes; //may be used in the future + char* c; +} str; + +str* str_init(char*); +void str_free(str*); +void str_push(str*, char*); +void str_clear(str*); @@ -1,4 +1,5 @@ #include <unistd.h> +#include "i_str.h" #include "io.h" #include "stdlib.h" #include "stdio.h" @@ -139,8 +140,109 @@ void i_pprint(lua_State* L, int indent, int skip_indent){ } } + int l_pprint(lua_State* L){ i_pprint(L,0,0); printf("\n"); return 0; } + +enum json_state { + normal, reading +}; + +#define push() \ + if(is_array){\ + lua_pushinteger(L, i);\ + } else {\ + char kbuf[key->len];\ + memset(kbuf, 0, key->len);\ + strncpy(kbuf, key->c + 1, key->len - 2);\ + lua_pushstring(L, kbuf);\ + }\ + char buf[value->len];\ + memset(buf, 0, value->len);\ + switch(value->c[0]){\ + case '{': case '[':\ + json_parse(L, value);\ + break;\ + case '"':\ + strncpy(buf, value->c + 1, value->len - 2);\ + lua_pushstring(L, buf);\ + break;\ + default:\ + lua_pushnumber(L, atof(value->c));\ + break;\ + }\ + lua_settable(L, last_idx); + +void json_parse(lua_State* L, str* raw){ + enum json_state state = normal; + char topush[2] = {0,0}; + int count = 0; + char last = '\0'; + int token_depth = 0; + + str* key = str_init(""); + str* value = str_init(""); + + lua_newtable(L); + int last_idx = lua_gettop(L); + int is_array = raw->c[0] == '['; + int i = 1; + for(i = 1; i != raw->len - 1; i++){ + topush[0] = *(raw->c + i); + if(state == normal && (topush[0] == ' ' || topush[0] == '\n')) continue; + + switch(topush[0]){ + case '"': + case '{': case '}': + case '[': case ']': + if(last == '{' && topush[0] == '}' || last == '[' && topush[0] == ']') token_depth--; + + if((last == '\0' || last == '"' && topush[0] == '"' + || last == '{' && topush[0] == '}' || last == '[' && topush[0] == ']')){ + if(token_depth == 0){ + if(last == '\0'){ + last = topush[0]; + } else { + last = '\0'; + } + + if(state==reading) state = normal; + else state = reading; + } + } + break; + case ',': + if(state == normal){ + push() + str_clear(key); + str_clear(value); + count = 0; + continue; + } + break; + case ':': + if(state == normal){ + count++; + continue; + } + break; + } + if(last == '{' && topush[0] == '{' || last == '[' && topush[0] == '[') token_depth++; + + if(count == 0 && !is_array) str_push(key, topush); + else str_push(value, topush); + } + push() + str_free(key); + str_free(value); + //printf("key: %s, value : %s\n",key.c,value.c); +} + +int l_json_parse(lua_State* L){ + str* raw_json = str_init((char*)luaL_checklstring(L, 1, NULL)); + json_parse(L, raw_json); + return 1; +} @@ -25,6 +25,8 @@ int l_warn(lua_State*); int l_error(lua_State*); int l_pprint(lua_State*); +int l_json_parse(lua_State*); + static const luaL_Reg io_function_list [] = { {"readfile",l_readfile}, {"debug",l_debug}, @@ -32,5 +34,6 @@ static const luaL_Reg io_function_list [] = { {"warn",l_warn}, {"error",l_error}, {"pprint",l_pprint}, + {"json_parse",l_json_parse}, {NULL,NULL} }; |
