mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-26 01:17:51 +08:00
Add port of cJSON from Darcy Gong
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5267 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -384,4 +384,7 @@
|
||||
by one (Mike Smith).
|
||||
* apps/examples/elf: Test example for the ELF loader.
|
||||
* apps/examples/elf: The ELF module test example appears fully functional.
|
||||
* apps/netutils/json: Add a snapshot of the cJSON project. Contributed by
|
||||
Darcy Gong.
|
||||
* apps/examples/json: Test example for cJSON from Darcy Gong
|
||||
|
||||
|
||||
+1
-155
@@ -3,210 +3,56 @@
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
menu "ADC Example"
|
||||
source "$APPSDIR/examples/adc/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Buttons Example"
|
||||
source "$APPSDIR/examples/buttons/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "CAN Example"
|
||||
source "$APPSDIR/examples/can/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "USB CDC/ACM Class Driver Example"
|
||||
source "$APPSDIR/examples/cdcacm/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "USB composite Class Driver Example"
|
||||
source "$APPSDIR/examples/composite/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "DHCP Server Example"
|
||||
source "$APPSDIR/examples/dhcpd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "ELF Loader Example"
|
||||
source "$APPSDIR/examples/elf/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "FTP Client Example"
|
||||
source "$APPSDIR/examples/ftpc/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "FTP Server Example"
|
||||
source "$APPSDIR/examples/ftpd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "\"Hello, World!\" Example"
|
||||
source "$APPSDIR/examples/hello/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "\"Hello, World!\" C++ Example"
|
||||
source "$APPSDIR/examples/helloxx/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "USB HID Keyboard Example"
|
||||
source "$APPSDIR/examples/json/Kconfig"
|
||||
source "$APPSDIR/examples/hidkbd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "IGMP Example"
|
||||
source "$APPSDIR/examples/igmp/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "LCD Read/Write Example"
|
||||
source "$APPSDIR/examples/lcdrw/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Memory Management Example"
|
||||
source "$APPSDIR/examples/mm/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "File System Mount Example"
|
||||
source "$APPSDIR/examples/mount/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "FreeModBus Example"
|
||||
source "$APPSDIR/examples/modbus/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Network Test Example"
|
||||
source "$APPSDIR/examples/nettest/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NuttShell (NSH) Example"
|
||||
source "$APPSDIR/examples/nsh/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NULL Example"
|
||||
source "$APPSDIR/examples/null/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NX Graphics Example"
|
||||
source "$APPSDIR/examples/nx/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NxConsole Example"
|
||||
source "$APPSDIR/examples/nxconsole/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NXFFS File System Example"
|
||||
source "$APPSDIR/examples/nxffs/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NXFLAT Example"
|
||||
source "$APPSDIR/examples/nxflat/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NX Graphics \"Hello, World!\" Example"
|
||||
source "$APPSDIR/examples/nxhello/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NX Graphics image Example"
|
||||
source "$APPSDIR/examples/nximage/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NX Graphics lines Example"
|
||||
source "$APPSDIR/examples/nxlines/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "NX Graphics Text Example"
|
||||
source "$APPSDIR/examples/nxtext/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "OS Test Example"
|
||||
source "$APPSDIR/examples/ostest/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Pascal \"Hello, World!\"example"
|
||||
source "$APPSDIR/examples/pashello/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Pipe Example"
|
||||
source "$APPSDIR/examples/pipe/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Poll Example"
|
||||
source "$APPSDIR/examples/poll/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Pulse Width Modulation (PWM) Example"
|
||||
source "$APPSDIR/examples/pwm/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Quadrature Encoder Example"
|
||||
source "$APPSDIR/examples/qencoder/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "RGMP Example"
|
||||
source "$APPSDIR/examples/rgmp/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "ROMFS Example"
|
||||
source "$APPSDIR/examples/romfs/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "sendmail Example"
|
||||
source "$APPSDIR/examples/sendmail/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Serial Loopback Example"
|
||||
source "$APPSDIR/examples/serloop/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Telnet Daemon Example"
|
||||
source "$APPSDIR/examples/telnetd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "THTTPD Web Server Example"
|
||||
source "$APPSDIR/examples/thttpd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "TIFF Generation Example"
|
||||
source "$APPSDIR/examples/tiff/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Touchscreen Example"
|
||||
source "$APPSDIR/examples/touchscreen/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "UDP Example"
|
||||
source "$APPSDIR/examples/udp/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "UDP Discovery Daemon Example"
|
||||
source "$APPSDIR/examples/discover/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "uIP Web Server Example"
|
||||
source "$APPSDIR/examples/uip/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "USB Serial Test Example"
|
||||
source "$APPSDIR/examples/usbserial/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "USB Mass Storage Class Example"
|
||||
source "$APPSDIR/examples/usbstorage/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "USB Serial Terminal Example"
|
||||
source "$APPSDIR/examples/usbterm/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Watchdog timer Example"
|
||||
source "$APPSDIR/examples/watchdog/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "wget Example"
|
||||
source "$APPSDIR/examples/wget/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "WLAN Example"
|
||||
source "$APPSDIR/examples/wlan/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "XML RPC Example"
|
||||
source "$APPSDIR/examples/xmlrpc/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -90,6 +90,10 @@ ifeq ($(CONFIG_EXAMPLES_IGMP),y)
|
||||
CONFIGURED_APPS += examples/igmp
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_EXAMPLES_JSON),y)
|
||||
CONFIGURED_APPS += examples/json
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_EXAMPLES_LCDRW),y)
|
||||
CONFIGURED_APPS += examples/lcdrw
|
||||
endif
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
# Sub-directories
|
||||
|
||||
SUBDIRS = adc buttons can cdcacm composite dhcpd discover elf ftpc ftpd hello
|
||||
SUBDIRS += helloxx hidkbd igmp lcdrw mm modbus mount nettest nsh null nx
|
||||
SUBDIRS += helloxx hidkbd igmp json lcdrw mm modbus mount nettest nsh null nx
|
||||
SUBDIRS += nxconsole nxffs nxflat nxhello nximage nxlines nxtext ostest
|
||||
SUBDIRS += pashello pipe poll pwm qencoder rgmp romfs serloop telnetd
|
||||
SUBDIRS += thttpd tiff touchscreen udp uip usbserial sendmail usbstorage
|
||||
@@ -57,8 +57,8 @@ SUBDIRS += usbterm watchdog wget wlan
|
||||
CNTXTDIRS = pwm
|
||||
|
||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||
CNTXTDIRS += adc can cdcacm composite discover ftpd dhcpd modbus nettest
|
||||
CNTXTDIRS += qencoder telnetd watchdog
|
||||
CNTXTDIRS += adc can cdcacm composite dhcpd discover ftpd json modbus
|
||||
CNTXTDIRS += nettest qencoder telnetd watchdog
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
|
||||
|
||||
@@ -542,6 +542,19 @@ examples/igmp
|
||||
|
||||
CONFIGURED_APPS += uiplib
|
||||
|
||||
examples/json
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
This example exercises the cJSON implementation at apps/netutils/json.
|
||||
This example contains logic taken from the cJSON project:
|
||||
|
||||
http://sourceforge.net/projects/cjson/
|
||||
|
||||
The example corresponds to SVN revision r42 (with lots of changes for
|
||||
NuttX coding standards). As of r42, the SVN repository was last updated
|
||||
on 2011-10-10 so I presume that the code is stable and there is no risk
|
||||
of maintaining duplicate logic in the NuttX repository.
|
||||
|
||||
examples/lcdrw
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config EXAMPLES_JSON
|
||||
bool "JSON example"
|
||||
default n
|
||||
select NETUTILS_JSON
|
||||
---help---
|
||||
An example for the netutils/json library.
|
||||
|
||||
if EXAMPLES_JSON
|
||||
endif
|
||||
@@ -0,0 +1,103 @@
|
||||
############################################################################
|
||||
# apps/examples/json/Makefile
|
||||
#
|
||||
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
-include $(TOPDIR)/.config
|
||||
-include $(TOPDIR)/Make.defs
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
# cJSON built-in application info
|
||||
|
||||
APPNAME = json
|
||||
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||
STACKSIZE = 2048
|
||||
|
||||
ASRCS =
|
||||
CSRCS = json_main.c
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
ifeq ($(WINTOOL),y)
|
||||
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
|
||||
else
|
||||
BIN = "$(APPDIR)/libapps$(LIBEXT)"
|
||||
endif
|
||||
|
||||
ROOTDEPPATH = --dep-path .
|
||||
|
||||
# Common build
|
||||
|
||||
VPATH =
|
||||
|
||||
all: .built
|
||||
.PHONY: clean depend distclean
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(call ASSEMBLE, $<, $@)
|
||||
|
||||
$(COBJS): %$(OBJEXT): %.c
|
||||
$(call COMPILE, $<, $@)
|
||||
|
||||
.built: $(OBJS)
|
||||
@( for obj in $(OBJS) ; do \
|
||||
$(call ARCHIVE, $(BIN), $${obj}); \
|
||||
done ; )
|
||||
@touch .built
|
||||
|
||||
.context:
|
||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||
@touch $@
|
||||
endif
|
||||
|
||||
context: .context
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
@touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
@rm -f *.o *~ .*.swp .built
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
||||
@rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
@@ -0,0 +1,258 @@
|
||||
apps/examples/json/README.txt
|
||||
=============================
|
||||
|
||||
This directory contains logic taken from the cJSON project:
|
||||
|
||||
http://sourceforge.net/projects/cjson/
|
||||
|
||||
This corresponds to SVN revision r42 (with lots of changes for NuttX coding
|
||||
standards). As of r42, the SVN repository was last updated on 2011-10-10
|
||||
so I presume that the code is stable and there is no risk of maintaining
|
||||
duplicate logic in the NuttX repository.
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
o License
|
||||
o Welcome to cJSON
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Welcome to cJSON
|
||||
================
|
||||
|
||||
cJSON aims to be the dumbest possible parser that you can get your job done with.
|
||||
It's a single file of C, and a single header file.
|
||||
|
||||
JSON is described best here: http://www.json.org/
|
||||
It's like XML, but fat-free. You use it to move data around, store things, or just
|
||||
generally represent your program's state.
|
||||
|
||||
First up, how do I build?
|
||||
Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
|
||||
For example, to build the test app:
|
||||
|
||||
gcc cJSON.c test.c -o test -lm
|
||||
./test
|
||||
|
||||
As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
|
||||
As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
|
||||
in one of two modes: Auto and Manual. Let's have a quick run-through.
|
||||
|
||||
I lifted some JSON from this page: http://www.json.org/fatfree.html
|
||||
That page inspired me to write cJSON, which is a parser that tries to share the same
|
||||
philosophy as JSON itself. Simple, dumb, out of the way.
|
||||
|
||||
Some JSON:
|
||||
{
|
||||
"name": "Jack (\"Bee\") Nimble",
|
||||
"format": {
|
||||
"type": "rect",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"interlace": false,
|
||||
"frame rate": 24
|
||||
}
|
||||
}
|
||||
|
||||
Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
|
||||
you have a char * to it. Everything is a cJSON struct.
|
||||
Get it parsed:
|
||||
cJSON *root = cJSON_Parse(my_json_string);
|
||||
|
||||
This is an object. We're in C. We don't have objects. But we do have structs.
|
||||
What's the framerate?
|
||||
|
||||
cJSON *format = cJSON_GetObjectItem(root,"format");
|
||||
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
|
||||
|
||||
Want to change the framerate?
|
||||
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
|
||||
|
||||
Back to disk?
|
||||
char *rendered=cJSON_Print(root);
|
||||
|
||||
Finished? Delete the root (this takes care of everything else).
|
||||
cJSON_Delete(root);
|
||||
|
||||
That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
|
||||
before you dereference them. If you want to see how you'd build this struct in code?
|
||||
cJSON *root,*fmt;
|
||||
root=cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
|
||||
cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(fmt,"type", "rect");
|
||||
cJSON_AddNumberToObject(fmt,"width", 1920);
|
||||
cJSON_AddNumberToObject(fmt,"height", 1080);
|
||||
cJSON_AddFalseToObject (fmt,"interlace");
|
||||
cJSON_AddNumberToObject(fmt,"frame rate", 24);
|
||||
|
||||
Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
|
||||
Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
|
||||
a few from elsewhere.
|
||||
|
||||
What about manual mode? First up you need some detail.
|
||||
Let's cover how the cJSON objects represent the JSON data.
|
||||
cJSON doesn't distinguish arrays from objects in handling; just type.
|
||||
Each cJSON has, potentially, a child, siblings, value, a name.
|
||||
|
||||
The root object has: Object Type and a Child
|
||||
The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
|
||||
Sibling has type Object, name "format", and a child.
|
||||
That child has type String, name "type", value "rect", and a sibling:
|
||||
Sibling has type Number, name "width", value 1920, and a sibling:
|
||||
Sibling has type Number, name "height", value 1080, and a sibling:
|
||||
Sibling hs type False, name "interlace", and a sibling:
|
||||
Sibling has type Number, name "frame rate", value 24
|
||||
|
||||
Here's the structure:
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev;
|
||||
struct cJSON *child;
|
||||
|
||||
int type;
|
||||
|
||||
char *valuestring;
|
||||
int valueint;
|
||||
double valuedouble;
|
||||
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
By default all values are 0 unless set by virtue of being meaningful.
|
||||
|
||||
next/prev is a doubly linked list of siblings. next takes you to your sibling,
|
||||
prev takes you back from your sibling to you.
|
||||
Only objects and arrays have a "child", and it's the head of the doubly linked list.
|
||||
A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
|
||||
The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
|
||||
cJSON.h
|
||||
|
||||
A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
|
||||
valuedouble.
|
||||
|
||||
Any entry which is in the linked list which is the child of an object will have a "string"
|
||||
which is the "name" of the entry. When I said "name" in the above example, that's "string".
|
||||
"string" is the JSON name for the 'variable name' if you will.
|
||||
|
||||
Now you can trivially walk the lists, recursively, and parse as you please.
|
||||
You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
|
||||
the root object, and traverse the structure (which is, formally, an N-tree),
|
||||
and tokenise as you please. If you wanted to build a callback style parser, this is how
|
||||
you'd do it (just an example, since these things are very specific):
|
||||
|
||||
void parse_and_callback(cJSON *item,const char *prefix)
|
||||
{
|
||||
while (item)
|
||||
{
|
||||
char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
|
||||
sprintf(newprefix,"%s/%s",prefix,item->name);
|
||||
int dorecurse=callback(newprefix, item->type, item);
|
||||
if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
|
||||
item=item->next;
|
||||
free(newprefix);
|
||||
}
|
||||
}
|
||||
|
||||
The prefix process will build you a separated list, to simplify your callback handling.
|
||||
The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
|
||||
let you invoke it per-item. For the item above, your callback might look like this:
|
||||
|
||||
int callback(const char *name,int type,cJSON *item)
|
||||
{
|
||||
if (!strcmp(name,"name")) { /* populate name */ }
|
||||
else if (!strcmp(name,"format/type") { /* handle "rect" */ }
|
||||
else if (!strcmp(name,"format/width") { /* 800 */ }
|
||||
else if (!strcmp(name,"format/height") { /* 600 */ }
|
||||
else if (!strcmp(name,"format/interlace") { /* false */ }
|
||||
else if (!strcmp(name,"format/frame rate") { /* 24 */ }
|
||||
return 1;
|
||||
}
|
||||
|
||||
Alternatively, you might like to parse iteratively.
|
||||
You'd use:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
int i; for (i=0;i<cJSON_GetArraySize(item);i++)
|
||||
{
|
||||
cJSON *subitem=cJSON_GetArrayItem(item,i);
|
||||
// handle subitem.
|
||||
}
|
||||
}
|
||||
|
||||
Or, for PROPER manual mode:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
cJSON *subitem=item->child;
|
||||
while (subitem)
|
||||
{
|
||||
// handle subitem
|
||||
if (subitem->child) parse_object(subitem->child);
|
||||
|
||||
subitem=subitem->next;
|
||||
}
|
||||
}
|
||||
|
||||
Of course, this should look familiar, since this is just a stripped-down version
|
||||
of the callback-parser.
|
||||
|
||||
This should cover most uses you'll find for parsing. The rest should be possible
|
||||
to infer.. and if in doubt, read the source! There's not a lot of it! ;)
|
||||
|
||||
In terms of constructing JSON data, the example code above is the right way to do it.
|
||||
You can, of course, hand your sub-objects to other functions to populate.
|
||||
Also, if you find a use for it, you can manually build the objects.
|
||||
For instance, suppose you wanted to build an array of objects?
|
||||
|
||||
cJSON *objects[24];
|
||||
|
||||
cJSON *Create_array_of_anything(cJSON **items,int num)
|
||||
{
|
||||
int i;cJSON *prev, *root=cJSON_CreateArray();
|
||||
for (i=0;i<24;i++)
|
||||
{
|
||||
if (!i) root->child=objects[i];
|
||||
else prev->next=objects[i], objects[i]->prev=prev;
|
||||
prev=objects[i];
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
and simply: Create_array_of_anything(objects,24);
|
||||
|
||||
cJSON doesn't make any assumptions about what order you create things in.
|
||||
You can attach the objects, as above, and later add children to each
|
||||
of those objects.
|
||||
|
||||
As soon as you call cJSON_Print, it renders the structure to text.
|
||||
|
||||
The test.c code shows how to handle a bunch of typical cases. If you uncomment
|
||||
the code, it'll load, parse and print a bunch of test files, also from json.org,
|
||||
which are more complex than I'd care to try and stash into a const char array[].
|
||||
|
||||
Enjoy cJSON!
|
||||
|
||||
- Dave Gamble, Aug 2009
|
||||
@@ -0,0 +1,325 @@
|
||||
/****************************************************************************
|
||||
* apps/examples/json/json_main.c
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Ported by: Darcy Gong
|
||||
*
|
||||
* And derives from the cJSON Project which has an MIT license:
|
||||
*
|
||||
* Copyright (c) 2009 Dave Gamble
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <apps/netutils/cJSON.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Used by some code below as an example datatype. */
|
||||
|
||||
struct record
|
||||
{
|
||||
const char *precision;
|
||||
double lat;
|
||||
double lon;
|
||||
const char *address;
|
||||
const char *city;
|
||||
const char *state;
|
||||
const char *zip;
|
||||
const char *country;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: doit
|
||||
*
|
||||
* Description:
|
||||
* Parse text to JSON, then render back to text, and print!
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void doit(const char *text)
|
||||
{
|
||||
char *out;
|
||||
cJSON *json;
|
||||
json = cJSON_Parse(text);
|
||||
if (!json)
|
||||
{
|
||||
printf("Error before: [%s]\n", cJSON_GetErrorPtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
out = cJSON_Print(json);
|
||||
cJSON_Delete(json);
|
||||
printf("%s\n", out);
|
||||
free(out);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dofile
|
||||
*
|
||||
* Description:
|
||||
* Read a file, parse, render back, etc.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if 0 /* Not used */
|
||||
static void dofile(char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
long len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
char *data = malloc(len + 1);
|
||||
fread(data, 1, len, f);
|
||||
fclose(f);
|
||||
doit(data);
|
||||
free(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: create_objects
|
||||
*
|
||||
* Description:
|
||||
* Create a bunch of objects as demonstration.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void create_objects(void)
|
||||
{
|
||||
cJSON *root;
|
||||
cJSON *fmt;
|
||||
cJSON *img;
|
||||
cJSON *thm;
|
||||
cJSON *fld;
|
||||
char *out;
|
||||
int i;
|
||||
|
||||
/* Our "days of the week" array */
|
||||
|
||||
static const char *strings[7] =
|
||||
{
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday"
|
||||
};
|
||||
|
||||
/* Our matrix: */
|
||||
|
||||
static const int numbers[3][3] = { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} };
|
||||
|
||||
/* Our "gallery" item: */
|
||||
|
||||
static const int ids[4] = { 116, 943, 234, 38793 };
|
||||
|
||||
/* Our array of "records": */
|
||||
|
||||
static const struct record fields[2] =
|
||||
{
|
||||
{"zip", 37.7668, -1.223959e+2, "", "SAN FRANCISCO", "CA", "94107", "US"},
|
||||
{"zip", 37.371991, -1.22026e+2, "", "SUNNYVALE", "CA", "94085", "US"}
|
||||
};
|
||||
|
||||
/* Here we construct some JSON standards, from the JSON site. */
|
||||
/* Our "Video" datatype: */
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
|
||||
cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(fmt, "type", "rect");
|
||||
cJSON_AddNumberToObject(fmt, "width", 1920);
|
||||
cJSON_AddNumberToObject(fmt, "height", 1080);
|
||||
cJSON_AddFalseToObject(fmt, "interlace");
|
||||
cJSON_AddNumberToObject(fmt, "frame rate", 24);
|
||||
out = cJSON_Print(root);
|
||||
cJSON_Delete(root);
|
||||
printf("%s\n", out);
|
||||
free(out);
|
||||
|
||||
/* Print to text, Delete the cJSON, print it, release the string. */
|
||||
|
||||
root = cJSON_CreateStringArray(strings, 7);
|
||||
out = cJSON_Print(root);
|
||||
cJSON_Delete(root);
|
||||
printf("%s\n", out);
|
||||
free(out);
|
||||
|
||||
root = cJSON_CreateArray();
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
cJSON_AddItemToArray(root, cJSON_CreateIntArray(numbers[i], 3));
|
||||
}
|
||||
|
||||
/*cJSON_ReplaceItemInArray(root,1,cJSON_CreateString("Replacement")); */
|
||||
out = cJSON_Print(root);
|
||||
cJSON_Delete(root);
|
||||
printf("%s\n", out);
|
||||
free(out);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "Image", img = cJSON_CreateObject());
|
||||
cJSON_AddNumberToObject(img, "Width", 800);
|
||||
cJSON_AddNumberToObject(img, "Height", 600);
|
||||
cJSON_AddStringToObject(img, "Title", "View from 15th Floor");
|
||||
cJSON_AddItemToObject(img, "Thumbnail", thm = cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(thm, "Url", "http:/*www.example.com/image/481989943");
|
||||
cJSON_AddNumberToObject(thm, "Height", 125);
|
||||
cJSON_AddStringToObject(thm, "Width", "100");
|
||||
cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));
|
||||
out = cJSON_Print(root);
|
||||
cJSON_Delete(root);
|
||||
printf("%s\n", out);
|
||||
free(out);
|
||||
|
||||
root = cJSON_CreateArray();
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
cJSON_AddItemToArray(root, fld = cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(fld, "precision", fields[i].precision);
|
||||
cJSON_AddNumberToObject(fld, "Latitude", fields[i].lat);
|
||||
cJSON_AddNumberToObject(fld, "Longitude", fields[i].lon);
|
||||
cJSON_AddStringToObject(fld, "Address", fields[i].address);
|
||||
cJSON_AddStringToObject(fld, "City", fields[i].city);
|
||||
cJSON_AddStringToObject(fld, "State", fields[i].state);
|
||||
cJSON_AddStringToObject(fld, "Zip", fields[i].zip);
|
||||
cJSON_AddStringToObject(fld, "Country", fields[i].country);
|
||||
}
|
||||
|
||||
/*cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root,1),"City",cJSON_CreateIntArray(ids,4)); */
|
||||
out = cJSON_Print(root);
|
||||
cJSON_Delete(root);
|
||||
printf("%s\n", out);
|
||||
free(out);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int json_main(int argc, const char *argv[])
|
||||
{
|
||||
/* a bunch of json: */
|
||||
|
||||
static const char text1[] =
|
||||
"{\n"
|
||||
" \"name\": \"Jack (\\\"Bee\\\") Nimble\",\n"
|
||||
" \"format\": {\n"
|
||||
" \"type\": \"rect\",\n"
|
||||
" \"width\": 1920,\n"
|
||||
" \"height\": 1080,\n"
|
||||
" \"interlace\": false,\n"
|
||||
" \"frame rate\": 24\n"
|
||||
" }\n"
|
||||
"}";
|
||||
|
||||
static const char text2[] =
|
||||
"[\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]";
|
||||
|
||||
static const char text3[] =
|
||||
"[\n"
|
||||
" [0, -1, 0],\n"
|
||||
" [1, 0, 0],\n"
|
||||
" [0, 0, 1]\n"
|
||||
"]\n";
|
||||
|
||||
static const char text4[] =
|
||||
"{\n"
|
||||
" \"Image\": {\n"
|
||||
" \"Width\": 800,\n"
|
||||
" \"Height\": 600,\n"
|
||||
" \"Title\": \"View from 15th Floor\",\n"
|
||||
" \"Thumbnail\": {\n"
|
||||
" \"Url\": \"http:/*www.example.com/image/481989943\",\n"
|
||||
" \"Height\": 125,\n"
|
||||
" \"Width\": \"100\"\n"
|
||||
" },\n"
|
||||
" \"IDs\": [116, 943, 234, 38793]\n"
|
||||
" }\n"
|
||||
"}";
|
||||
|
||||
static const char text5[] =
|
||||
"[\n"
|
||||
" {\n"
|
||||
" \"precision\": \"zip\",\n"
|
||||
" \"Latitude\": 37.7668,\n"
|
||||
" \"Longitude\": -122.3959,\n"
|
||||
" \"Address\": \"\",\n"
|
||||
" \"City\": \"SAN FRANCISCO\",\n"
|
||||
" \"State\": \"CA\",\n"
|
||||
" \"Zip\": \"94107\",\n"
|
||||
" \"Country\": \"US\"\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"precision\": \"zip\",\n"
|
||||
" \"Latitude\": 37.371991,\n"
|
||||
" \"Longitude\": -122.026020,\n"
|
||||
" \"Address\": \"\",\n"
|
||||
" \"City\": \"SUNNYVALE\",\n"
|
||||
" \"State\": \"CA\",\n"
|
||||
" \"Zip\": \"94085\",\n"
|
||||
" \"Country\": \"US\"\n"
|
||||
" }\n"
|
||||
"]";
|
||||
|
||||
/* Process each json textblock by parsing, then rebuilding: */ doit(text1);
|
||||
|
||||
doit(text2);
|
||||
doit(text3);
|
||||
doit(text4);
|
||||
doit(text5);
|
||||
|
||||
/* Parse standard testfiles: */
|
||||
|
||||
#if 0 /* Not yet */
|
||||
dofile("../../tests/test1");
|
||||
dofile("../../tests/test2");
|
||||
dofile("../../tests/test3");
|
||||
dofile("../../tests/test4");
|
||||
dofile("../../tests/test5");
|
||||
#endif
|
||||
|
||||
/* Now some samplecode for building objects concisely: */
|
||||
|
||||
create_objects();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/json/cJSON.c
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Ported by: Darcy Gong
|
||||
*
|
||||
* And derives from the cJSON Project which has an MIT license:
|
||||
*
|
||||
* Copyright (c) 2009 Dave Gamble
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APPS_INCLUDE_NETUTILS_JSON_H
|
||||
#define __APPS_INCLUDE_NETUTILS_JSON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
#define cJSON_AddNullToObject(object,name) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateTrue())cd
|
||||
#define cJSON_AddFalseToObject(object,name) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddNumberToObject(object,name,n) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* The cJSON structure: */
|
||||
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use
|
||||
* GetArraySize/GetArrayItem/GetObjectItem
|
||||
*/
|
||||
|
||||
struct cJSON *next,*prev;
|
||||
|
||||
/* An array or object item will have a child pointer pointing to a chain
|
||||
* of the items in the array/object.
|
||||
*/
|
||||
|
||||
struct cJSON *child;
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list
|
||||
* of subitems of an object.
|
||||
*/
|
||||
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
|
||||
void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can
|
||||
* interrogate. Call cJSON_Delete when finished.
|
||||
*/
|
||||
|
||||
cJSON *cJSON_Parse(const char *value);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when
|
||||
* finished.
|
||||
*/
|
||||
|
||||
char *cJSON_Print(cJSON *item);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage without any
|
||||
* formatting. Free the char* when finished.
|
||||
*/
|
||||
|
||||
char *cJSON_PrintUnformatted(cJSON *item);
|
||||
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
|
||||
void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
|
||||
int cJSON_GetArraySize(cJSON *array);
|
||||
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if
|
||||
* unsuccessful.
|
||||
*/
|
||||
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array, int item);
|
||||
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
|
||||
cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error.
|
||||
* You'll probably need to look a few chars back to make sense of it.
|
||||
* Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds.
|
||||
*/
|
||||
|
||||
const char *cJSON_GetErrorPtr();
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
|
||||
cJSON *cJSON_CreateNull();
|
||||
cJSON *cJSON_CreateTrue();
|
||||
cJSON *cJSON_CreateFalse();
|
||||
cJSON *cJSON_CreateBool(int b);
|
||||
cJSON *cJSON_CreateNumber(double num);
|
||||
cJSON *cJSON_CreateString(const char *string);
|
||||
cJSON *cJSON_CreateArray();
|
||||
cJSON *cJSON_CreateObject();
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
|
||||
cJSON *cJSON_CreateIntArray(const int *numbers, int count);
|
||||
cJSON *cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
cJSON *cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
cJSON *cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Append reference to item to the specified array/object. Use this when you
|
||||
* want to add an existing cJSON to a new cJSON, but don't want to corrupt
|
||||
* your existing cJSON.
|
||||
*/
|
||||
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
void cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
void cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
|
||||
void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APPS_INCLUDE_NETUTILS_JSON_H */
|
||||
+1
-41
@@ -5,58 +5,18 @@
|
||||
|
||||
comment "Networking Utilities"
|
||||
|
||||
menu "DHCP client"
|
||||
source "$APPSDIR/netutils/dhcpc/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "DHCP server"
|
||||
source "$APPSDIR/netutils/dhcpd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "FTP client"
|
||||
source "$APPSDIR/netutils/ftpc/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "FTP server"
|
||||
source "$APPSDIR/netutils/ftpd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "Name resolution"
|
||||
source "$APPSDIR/netutils/json/Kconfig"
|
||||
source "$APPSDIR/netutils/resolv/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "SMTP"
|
||||
source "$APPSDIR/netutils/smtp/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "TFTP client"
|
||||
source "$APPSDIR/netutils/telnetd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "TFTP client"
|
||||
source "$APPSDIR/netutils/tftpc/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "THTTPD web server"
|
||||
source "$APPSDIR/netutils/thttpd/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "uIP support library"
|
||||
source "$APPSDIR/netutils/uiplib/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "uIP web client"
|
||||
source "$APPSDIR/netutils/webclient/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "uIP web server"
|
||||
source "$APPSDIR/netutils/webserver/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "UDP Discovery Utility"
|
||||
source "$APPSDIR/netutils/discover/Kconfig"
|
||||
endmenu
|
||||
|
||||
menu "XML-RPC library"
|
||||
source "$APPSDIR/netutils/xmlrpc/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -50,6 +50,10 @@ ifeq ($(CONFIG_NETUTILS_FTPD),y)
|
||||
CONFIGURED_APPS += netutils/ftpd
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NETUTILS_JSON),y)
|
||||
CONFIGURED_APPS += netutils/json
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NETUTILS_RESOLV),y)
|
||||
CONFIGURED_APPS += netutils/resolv
|
||||
endif
|
||||
|
||||
@@ -37,8 +37,9 @@
|
||||
|
||||
# Sub-directories
|
||||
|
||||
SUBDIRS = json
|
||||
ifeq ($(CONFIG_NET),y)
|
||||
SUBDIRS = uiplib dhcpc dhcpd discover ftpc ftpd resolv smtp telnetd
|
||||
SUBDIRS += uiplib dhcpc dhcpd discover ftpc ftpd resolv smtp telnetd
|
||||
SUBDIRS += webclient webserver tftpc thttpd xmlrpc
|
||||
endif
|
||||
|
||||
|
||||
@@ -47,6 +47,12 @@ highly influenced by uIP) include:
|
||||
device class so that groups of devices can be discovered.
|
||||
It is also possible to address all classes with a kind of
|
||||
broadcast discover. (Contributed by Max Holtzberg).
|
||||
json - cJSON is an ultra-lightweight, portable, single-file,
|
||||
simple-as-can-be ANSI-C compliant JSON parser, under MIT
|
||||
license. Embeddable Lightweight XML-RPC Server discussed at
|
||||
http://www.drdobbs.com/web-development/an-embeddable-lightweight-xml-rpc-server/184405364.
|
||||
This code was taken from http://sourceforge.net/projects/cjson/
|
||||
and adapted for NuttX by Darcy Gong.
|
||||
tftpc - TFTP client. See apps/include/netutils/tftp.h
|
||||
for interface information.
|
||||
telnetd - TELNET server. This is the Telnet logic adapted from
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config NETUTILS_JSON
|
||||
bool "cJSON library"
|
||||
default n
|
||||
---help---
|
||||
Enables the cJSON library. cJSON is an ultra-lightweight, portable,
|
||||
single-file, simple-as-can-be ANSI-C compliant JSON parser, under MIT
|
||||
license. Embeddable Lightweight XML-RPC Server discussed at
|
||||
http://www.drdobbs.com/web-development/an-embeddable-lightweight-xml-rpc-server/184405364.
|
||||
This code was taken from http://sourceforge.net/projects/cjson/ and
|
||||
adapted for NuttX by Darcy Gong.
|
||||
|
||||
if NETUTILS_JSON
|
||||
endif
|
||||
@@ -0,0 +1,91 @@
|
||||
############################################################################
|
||||
# apps/netutils/json/Makefile
|
||||
#
|
||||
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
-include $(TOPDIR)/.config
|
||||
-include $(TOPDIR)/Make.defs
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
ASRCS =
|
||||
CSRCS = cJSON.c
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
ifeq ($(WINTOOL),y)
|
||||
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
|
||||
else
|
||||
BIN = "$(APPDIR)/libapps$(LIBEXT)"
|
||||
endif
|
||||
|
||||
ROOTDEPPATH = --dep-path .
|
||||
|
||||
# Common build
|
||||
|
||||
VPATH =
|
||||
|
||||
all: .built
|
||||
.PHONY: context depend clean distclean
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(call ASSEMBLE, $<, $@)
|
||||
|
||||
$(COBJS): %$(OBJEXT): %.c
|
||||
$(call COMPILE, $<, $@)
|
||||
|
||||
.built: $(OBJS)
|
||||
@( for obj in $(OBJS) ; do \
|
||||
$(call ARCHIVE, $(BIN), $${obj}); \
|
||||
done ; )
|
||||
@touch .built
|
||||
|
||||
context:
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
@touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
@rm -f *.o *~ .*.swp .built
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
||||
@rm -f Make.dep .depend
|
||||
|
||||
-include Make.dep
|
||||
@@ -0,0 +1,258 @@
|
||||
apps/netutils/json/README.txt
|
||||
=============================
|
||||
|
||||
This directory contains logic taken from the cJSON project:
|
||||
|
||||
http://sourceforge.net/projects/cjson/
|
||||
|
||||
This corresponds to SVN revision r42 (with lots of changes for NuttX coding
|
||||
standards). As of r42, the SVN repository was last updated on 2011-10-10
|
||||
so I presume that the code is stable and there is no risk of maintaining
|
||||
duplicate logic in the NuttX repository.
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
o License
|
||||
o Welcome to cJSON
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Welcome to cJSON
|
||||
================
|
||||
|
||||
cJSON aims to be the dumbest possible parser that you can get your job done with.
|
||||
It's a single file of C, and a single header file.
|
||||
|
||||
JSON is described best here: http://www.json.org/
|
||||
It's like XML, but fat-free. You use it to move data around, store things, or just
|
||||
generally represent your program's state.
|
||||
|
||||
First up, how do I build?
|
||||
Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
|
||||
For example, to build the test app:
|
||||
|
||||
gcc cJSON.c test.c -o test -lm
|
||||
./test
|
||||
|
||||
As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
|
||||
As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
|
||||
in one of two modes: Auto and Manual. Let's have a quick run-through.
|
||||
|
||||
I lifted some JSON from this page: http://www.json.org/fatfree.html
|
||||
That page inspired me to write cJSON, which is a parser that tries to share the same
|
||||
philosophy as JSON itself. Simple, dumb, out of the way.
|
||||
|
||||
Some JSON:
|
||||
{
|
||||
"name": "Jack (\"Bee\") Nimble",
|
||||
"format": {
|
||||
"type": "rect",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"interlace": false,
|
||||
"frame rate": 24
|
||||
}
|
||||
}
|
||||
|
||||
Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
|
||||
you have a char * to it. Everything is a cJSON struct.
|
||||
Get it parsed:
|
||||
cJSON *root = cJSON_Parse(my_json_string);
|
||||
|
||||
This is an object. We're in C. We don't have objects. But we do have structs.
|
||||
What's the framerate?
|
||||
|
||||
cJSON *format = cJSON_GetObjectItem(root,"format");
|
||||
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
|
||||
|
||||
Want to change the framerate?
|
||||
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
|
||||
|
||||
Back to disk?
|
||||
char *rendered=cJSON_Print(root);
|
||||
|
||||
Finished? Delete the root (this takes care of everything else).
|
||||
cJSON_Delete(root);
|
||||
|
||||
That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
|
||||
before you dereference them. If you want to see how you'd build this struct in code?
|
||||
cJSON *root,*fmt;
|
||||
root=cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
|
||||
cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(fmt,"type", "rect");
|
||||
cJSON_AddNumberToObject(fmt,"width", 1920);
|
||||
cJSON_AddNumberToObject(fmt,"height", 1080);
|
||||
cJSON_AddFalseToObject (fmt,"interlace");
|
||||
cJSON_AddNumberToObject(fmt,"frame rate", 24);
|
||||
|
||||
Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
|
||||
Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
|
||||
a few from elsewhere.
|
||||
|
||||
What about manual mode? First up you need some detail.
|
||||
Let's cover how the cJSON objects represent the JSON data.
|
||||
cJSON doesn't distinguish arrays from objects in handling; just type.
|
||||
Each cJSON has, potentially, a child, siblings, value, a name.
|
||||
|
||||
The root object has: Object Type and a Child
|
||||
The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
|
||||
Sibling has type Object, name "format", and a child.
|
||||
That child has type String, name "type", value "rect", and a sibling:
|
||||
Sibling has type Number, name "width", value 1920, and a sibling:
|
||||
Sibling has type Number, name "height", value 1080, and a sibling:
|
||||
Sibling hs type False, name "interlace", and a sibling:
|
||||
Sibling has type Number, name "frame rate", value 24
|
||||
|
||||
Here's the structure:
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev;
|
||||
struct cJSON *child;
|
||||
|
||||
int type;
|
||||
|
||||
char *valuestring;
|
||||
int valueint;
|
||||
double valuedouble;
|
||||
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
By default all values are 0 unless set by virtue of being meaningful.
|
||||
|
||||
next/prev is a doubly linked list of siblings. next takes you to your sibling,
|
||||
prev takes you back from your sibling to you.
|
||||
Only objects and arrays have a "child", and it's the head of the doubly linked list.
|
||||
A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
|
||||
The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
|
||||
cJSON.h
|
||||
|
||||
A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
|
||||
valuedouble.
|
||||
|
||||
Any entry which is in the linked list which is the child of an object will have a "string"
|
||||
which is the "name" of the entry. When I said "name" in the above example, that's "string".
|
||||
"string" is the JSON name for the 'variable name' if you will.
|
||||
|
||||
Now you can trivially walk the lists, recursively, and parse as you please.
|
||||
You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
|
||||
the root object, and traverse the structure (which is, formally, an N-tree),
|
||||
and tokenise as you please. If you wanted to build a callback style parser, this is how
|
||||
you'd do it (just an example, since these things are very specific):
|
||||
|
||||
void parse_and_callback(cJSON *item,const char *prefix)
|
||||
{
|
||||
while (item)
|
||||
{
|
||||
char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
|
||||
sprintf(newprefix,"%s/%s",prefix,item->name);
|
||||
int dorecurse=callback(newprefix, item->type, item);
|
||||
if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
|
||||
item=item->next;
|
||||
free(newprefix);
|
||||
}
|
||||
}
|
||||
|
||||
The prefix process will build you a separated list, to simplify your callback handling.
|
||||
The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
|
||||
let you invoke it per-item. For the item above, your callback might look like this:
|
||||
|
||||
int callback(const char *name,int type,cJSON *item)
|
||||
{
|
||||
if (!strcmp(name,"name")) { /* populate name */ }
|
||||
else if (!strcmp(name,"format/type") { /* handle "rect" */ }
|
||||
else if (!strcmp(name,"format/width") { /* 800 */ }
|
||||
else if (!strcmp(name,"format/height") { /* 600 */ }
|
||||
else if (!strcmp(name,"format/interlace") { /* false */ }
|
||||
else if (!strcmp(name,"format/frame rate") { /* 24 */ }
|
||||
return 1;
|
||||
}
|
||||
|
||||
Alternatively, you might like to parse iteratively.
|
||||
You'd use:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
int i; for (i=0;i<cJSON_GetArraySize(item);i++)
|
||||
{
|
||||
cJSON *subitem=cJSON_GetArrayItem(item,i);
|
||||
// handle subitem.
|
||||
}
|
||||
}
|
||||
|
||||
Or, for PROPER manual mode:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
cJSON *subitem=item->child;
|
||||
while (subitem)
|
||||
{
|
||||
// handle subitem
|
||||
if (subitem->child) parse_object(subitem->child);
|
||||
|
||||
subitem=subitem->next;
|
||||
}
|
||||
}
|
||||
|
||||
Of course, this should look familiar, since this is just a stripped-down version
|
||||
of the callback-parser.
|
||||
|
||||
This should cover most uses you'll find for parsing. The rest should be possible
|
||||
to infer.. and if in doubt, read the source! There's not a lot of it! ;)
|
||||
|
||||
In terms of constructing JSON data, the example code above is the right way to do it.
|
||||
You can, of course, hand your sub-objects to other functions to populate.
|
||||
Also, if you find a use for it, you can manually build the objects.
|
||||
For instance, suppose you wanted to build an array of objects?
|
||||
|
||||
cJSON *objects[24];
|
||||
|
||||
cJSON *Create_array_of_anything(cJSON **items,int num)
|
||||
{
|
||||
int i;cJSON *prev, *root=cJSON_CreateArray();
|
||||
for (i=0;i<24;i++)
|
||||
{
|
||||
if (!i) root->child=objects[i];
|
||||
else prev->next=objects[i], objects[i]->prev=prev;
|
||||
prev=objects[i];
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
and simply: Create_array_of_anything(objects,24);
|
||||
|
||||
cJSON doesn't make any assumptions about what order you create things in.
|
||||
You can attach the objects, as above, and later add children to each
|
||||
of those objects.
|
||||
|
||||
As soon as you call cJSON_Print, it renders the structure to text.
|
||||
|
||||
The test.c code shows how to handle a bunch of typical cases. If you uncomment
|
||||
the code, it'll load, parse and print a bunch of test files, also from json.org,
|
||||
which are more complex than I'd care to try and stash into a const char array[].
|
||||
|
||||
Enjoy cJSON!
|
||||
|
||||
- Dave Gamble, Aug 2009
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3523,4 +3523,6 @@
|
||||
Add a configuration for testing the ARM ELF loader.
|
||||
* binfmt/libelf: Can't use fstat(). NuttX does not yet support it. Damn!
|
||||
* binfmt/libelf: The basic ELF module execution appears fully functional.
|
||||
* configs/shenzhou/src/up_relays.c: Add support for relays from the
|
||||
Shenzhou board. Contributed by Darcy Gong.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX README Files</i></font></big></h1>
|
||||
<p>Last Updated: September 25, 2012</p>
|
||||
<p>Last Updated: October 27, 2012</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -247,6 +247,7 @@
|
||||
`- apps/
|
||||
|- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/README.txt"><b>README.txt</b></a>
|
||||
|- examples/
|
||||
| |- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/examples/json/README.txt">json/README.txt</a>
|
||||
| |- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/examples/pashello/README.txt">pashello/README.txt</a>
|
||||
| `- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/examples/README.txt"><b><i>README.txt</i></b></a>
|
||||
|- graphics/
|
||||
@@ -259,6 +260,7 @@
|
||||
|- netutils/
|
||||
| | |- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/netutils/discover/README.txt">discover/README.txt</a>
|
||||
| | |- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/netutils/ftpc/README.txt">ftpc/README.txt</a>
|
||||
| | |- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/netutils/json/README.txt">json/README.txt</a>
|
||||
| | |- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/netutils/telnetd/README.txt">telnetd/README.txt</a>
|
||||
| `- <a href="http://svn.code.sf.net/p/nuttx/code/trunk/apps/netutils/README.txt"><b><i>README.txt</i></b></a>
|
||||
|- nshlib/
|
||||
|
||||
@@ -828,6 +828,7 @@ nuttx
|
||||
|
||||
apps
|
||||
|- examples/
|
||||
| |- json/README.txt
|
||||
| |- pashello/README.txt
|
||||
| `- README.txt
|
||||
|- graphics/
|
||||
@@ -843,6 +844,8 @@ apps
|
||||
| | `- README.txt
|
||||
| |- ftpc
|
||||
| | `- README.txt
|
||||
| |- json
|
||||
| | `- README.txt
|
||||
| |- telnetd
|
||||
| | `- README.txt
|
||||
| `- README.txt
|
||||
|
||||
Reference in New Issue
Block a user