libjson: added printing support (thanks spew)

This commit is contained in:
cinap_lenrek 2015-12-22 18:12:56 +01:00
parent f6e8b115d4
commit a53ae2782a
4 changed files with 127 additions and 12 deletions

View file

@ -4,6 +4,8 @@
typedef struct JSONEl JSONEl; typedef struct JSONEl JSONEl;
typedef struct JSON JSON; typedef struct JSON JSON;
#pragma varargck type "J" JSON*
enum { enum {
JSONNull, JSONNull,
JSONBool, JSONBool,
@ -33,3 +35,5 @@ JSON* jsonparse(char *);
void jsonfree(JSON *); void jsonfree(JSON *);
JSON* jsonbyname(JSON *, char *); JSON* jsonbyname(JSON *, char *);
char* jsonstr(JSON *); char* jsonstr(JSON *);
int JSONfmt(Fmt*);
void JSONfmtinstall(void);

View file

@ -40,10 +40,12 @@ struct JSON
}; };
}; };
JSON* jsonparse(char *); JSON* jsonparse(char *s);
void jsonfree(JSON *); void jsonfree(JSON *j);
JSON* jsonbyname(JSON *, char *); JSON* jsonbyname(JSON *j, char *s);
char* jsonstr(JSON *); char* jsonstr(JSON *j);
int JSONfmt(Fmt *f)
void JSONfmtinstall(void);
.EE .EE
.SH DESCRIPTION .SH DESCRIPTION
The The
@ -76,7 +78,7 @@ Dictionary objects have the
member set to the key of the association. member set to the key of the association.
.P .P
A json object is parsed by calling A json object is parsed by calling
.B jsonparse .I jsonparse
with a with a
.B UTF-8 .B UTF-8
string of the json encoded data. On success, a non-nil pointer to a string of the json encoded data. On success, a non-nil pointer to a
@ -84,26 +86,41 @@ newly allocated
.B JSON .B JSON
structure is returned. structure is returned.
To free the parsed objects, To free the parsed objects,
.B jsonfree .I jsonfree
has to be called. has to be called.
.P .P
The The
.B jsonbyname .I jsonbyname
function returns the associated value of a dictionary item. function returns the associated value of a dictionary item.
.P .P
The function The function
.B jsonstr .I jsonstr
returns the string value of a json object or returns the string value of a json object or
.B nil .B nil
for any other object type. for any other object type.
.P
.I JSONfmt
is a
.IR print (2)
formatting routine that prints a well-formatted JSON structure.
It can be installed by hand but
.I JSONfmtinstall
installs it under the standard format character J. The header
.B <json.h>
contains a #pragma statement so the compiler can
type-check uses of
.B %J
in
.IR print (2)
format strings.
.SH SOURCE .SH SOURCE
.B /sys/src/libjson .B /sys/src/libjson
.SH DIAGNOSTICS .SH DIAGNOSTICS
The functions The functions
.IB jsonparse , .I jsonparse,
.B jsonbyname .I jsonbyname
and and
.B jsonstr .I jsonstr
return return
.B nil .B nil
on error and set an error string (see on error and set an error string (see

View file

@ -2,7 +2,8 @@
LIB=/$objtype/lib/libjson.a LIB=/$objtype/lib/libjson.a
OFILES=\ OFILES=\
json.$O json.$O\
printjson.$O
HFILES=\ HFILES=\
/sys/include/json.h /sys/include/json.h

View file

@ -0,0 +1,93 @@
#include <u.h>
#include <libc.h>
#include <json.h>
static int printjson(Fmt*, JSON*, int);
static int printarray(Fmt*, JSON*, int);
static int printobject(Fmt*, JSON*, int);
static int
printarray(Fmt *f, JSON *j, int indent)
{
JSONEl *jl;
int i, r;
if(j->first == nil){
return fmtprint(f, "[]");
}
r = fmtprint(f, "[\n");
for(jl = j->first; jl != nil; jl = jl->next){
for(i = 0; i < indent; i++)
r += fmtprint(f, "\t");
r += printjson(f, jl->val, indent);
r += fmtprint(f, "%s\n", jl->next != nil ? "," : "");
}
for(i = 0; i < indent-1; i++)
r += fmtprint(f, "\t");
r += fmtprint(f, "]");
return r;
}
static int
printobject(Fmt *f, JSON *j, int indent)
{
JSONEl *jl;
int i, r;
if(j->first == nil){
return fmtprint(f, "{}");
}
r = fmtprint(f, "{\n");
for(jl = j->first; jl != nil; jl = jl->next){
for(i = 0; i < indent; i++)
fmtprint(f, "\t");
r += fmtprint(f, "\"%s\": ", jl->name);
r += printjson(f, jl->val, indent);
r += fmtprint(f, "%s\n", jl->next != nil ? "," : "");
}
for(i = 0; i < indent-1; i++)
r += fmtprint(f, "\t");
r += fmtprint(f, "}");
return r;
}
static int
printjson(Fmt *f, JSON *j, int indent)
{
switch(j->t){
case JSONNull:
return fmtprint(f, "null");
break;
case JSONBool:
return fmtprint(f, "%s", j->n ? "true" : "false");
break;
case JSONNumber:
return fmtprint(f, "%f", j->n);
break;
case JSONString:
return fmtprint(f, "\"%s\"", j->s);
break;
case JSONArray:
return printarray(f, j, indent+1);
break;
case JSONObject:
return printobject(f, j, indent+1);
break;
}
return 0;
}
int
JSONfmt(Fmt *f)
{
JSON *j;
j = va_arg(f->args, JSON*);
return printjson(f, j, 0);
}
void
JSONfmtinstall(void)
{
fmtinstall('J', JSONfmt);
}