libjson: added printing support (thanks spew)
This commit is contained in:
parent
f6e8b115d4
commit
a53ae2782a
4 changed files with 127 additions and 12 deletions
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
93
sys/src/libjson/printjson.c
Normal file
93
sys/src/libjson/printjson.c
Normal 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);
|
||||||
|
}
|
Loading…
Reference in a new issue