aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--docs/io.md9
-rw-r--r--readme.md2
-rw-r--r--src/i_str.c35
-rw-r--r--src/i_str.h14
-rw-r--r--src/io.c102
-rw-r--r--src/io.h3
7 files changed, 167 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 4c0ec0e..88b1648 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
*.so
*.lua
+a.out
+*.json
diff --git a/docs/io.md b/docs/io.md
index 443c978..4dba6b2 100644
--- a/docs/io.md
+++ b/docs/io.md
@@ -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}}
+```
diff --git a/readme.md b/readme.md
index f7f4255..c13dfe5 100644
--- a/readme.md
+++ b/readme.md
@@ -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*);
diff --git a/src/io.c b/src/io.c
index 997b4cd..8250ad1 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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;
+}
diff --git a/src/io.h b/src/io.h
index d32d313..570e4b4 100644
--- a/src/io.h
+++ b/src/io.h
@@ -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}
};