]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/libjson/json.c
etheriwl: don't break controller on command flush timeout
[plan9front.git] / sys / src / libjson / json.c
index 1cf77be3bfa9ba1c245bfebab009e904cbb21883..74fd5eeb0cd9e9f264b22d58064fbe84d4c8ce9f 100644 (file)
@@ -22,8 +22,6 @@ struct Lex
        double n;
        char *buf;
        Rune peeked;
-       jmp_buf jmp;
-       int canjmp;
 };
 
 static Rune
@@ -36,6 +34,8 @@ getch(Lex *l)
                l->peeked = 0;
                return r;
        }
+       if(l->s[0] == '\0')
+               return 0;
        l->s += chartorune(&r, l->s);
        return r;
 }
@@ -48,6 +48,20 @@ peekch(Lex *l)
        return l->peeked;
 }
 
+static Rune
+peeknonspace(Lex *l)
+{
+       Rune r;
+
+       for(;;){
+               r = peekch(l);
+               if(r != 0x20 && r != 0x09 && r != 0x0A && r != 0x0D)
+                       break;
+               getch(l);
+       }
+       return r;
+}
+
 static int
 fixsurrogate(Rune *rp, Rune r2)
 {
@@ -79,16 +93,8 @@ lex(Lex *l)
        int i;
        char c;
 
-       for(;;){
-               r = peekch(l);
-               if(r != 0x20 && r != 0x09 && r != 0x0A && r != 0x0D)
-                       break;
-               getch(l);
-       }
+       peeknonspace(l);
        r = getch(l);
-       if(r == ']' && l->canjmp)
-               longjmp(l->jmp, 1);
-       l->canjmp = 0;
        if(r == 0 || r == '{' || r == '[' || r == ']' || r == '}' || r == ':' || r == ','){
                l->t = r;
                return 0;
@@ -203,13 +209,9 @@ jsonobj(Lex *l)
        JSONEl **ln;
        int obj;
 
-       l->buf = mallocz(l->slen, 1);
-       if(l->buf == nil)
+       if((j = mallocz(sizeof(*j), 1)) == nil)
                return nil;
 
-       j = mallocz(sizeof(*j), 1);
-       if(j == nil)
-               return nil;
        if(lex(l) < 0){
 error:
                free(j);
@@ -232,8 +234,7 @@ error:
                break;
        case TSTRING:
                j->t = JSONString;
-               j->s = strdup(l->buf);
-               if(j->s == nil)
+               if((j->s = strdup(l->buf)) == nil)
                        goto error;
                break;
        case TNUM:
@@ -244,7 +245,6 @@ error:
        case '[':
                obj = l->t == '{';
                ln = &j->first;
-               e = nil;
                if(obj){
                        j->t = JSONObject;
                        if(lex(l) < 0)
@@ -254,9 +254,8 @@ error:
                        goto firstobj;
                }else{
                        j->t = JSONArray;
-                       l->canjmp = 1;
-                       if(setjmp(l->jmp) > 0){
-                               free(e);
+                       if(peeknonspace(l) == ']'){
+                               getch(l);
                                return j;
                        }
                }
@@ -269,8 +268,7 @@ error:
                                        werrstr("json: syntax error, not string");
                                        goto abort;
                                }
-                               e = mallocz(sizeof(*e), 1);
-                               if(e == nil)
+                               if((e = mallocz(sizeof(*e), 1)) == nil)
                                        goto abort;
                                e->name = strdup(l->buf);
                                if(e->name == nil || lex(l) < 0){
@@ -283,8 +281,7 @@ error:
                                        goto abort;
                                }
                        }else{
-                               e = mallocz(sizeof(*e), 1);
-                               if(e == nil)
+                               if((e = mallocz(sizeof(*e), 1)) == nil)
                                        goto abort;
                        }
                        e->val = jsonobj(l);
@@ -320,12 +317,18 @@ error:
 JSON*
 jsonparse(char *s)
 {
+       JSON *j;
        Lex l;
 
        memset(&l, 0, sizeof(l));
        l.s = s;
-       l.slen = strlen(s)+1;
-       return jsonobj(&l);
+       l.slen = strlen(s);
+       if((l.buf = mallocz(l.slen+UTFmax+1, 1)) == nil)
+               return nil;
+
+       j = jsonobj(&l);
+       free(l.buf);
+       return j;
 }
 
 void
@@ -333,6 +336,8 @@ jsonfree(JSON *j)
 {
        JSONEl *e, *f;
 
+       if(j == nil)
+               return;
        switch(j->t){
        case JSONString:
                if(j->s)