Index: strfuns.c
===================================================================
--- strfuns.c	(revision 2314)
+++ strfuns.c	(working copy)
@@ -1157,5 +1157,147 @@
     return arg;
 } /* x_map_string () */
 
+#ifdef HAS_JSON
+/* support for javascript object notation
+ * depends on the json-c library
+ * see http://www.json.org for more information
+ */
+#include <json/json.h>
+#include "array.h"
+
+svalue_t *
+ldmud_json_inner_parse (svalue_t *sp, struct json_object *val) 
+{
+    if (is_error(val)) {
+	errorf("json_inner_parse: error");
+        /* NOTREACHED */
+        return sp;
+
+    }
+    if (val == NULL) {
+	/* TODO: I (fippo) am not sure, if this is a really good idea... */
+	put_number(sp, 0);
+	return sp;
+    }
+    switch(json_object_get_type(val)) {
+    case json_type_null: 
+	put_number(sp, 0);
+	break;
+    case json_type_boolean:
+	put_number(sp, json_object_get_boolean(val));
+	break;
+    case json_type_double:
+        put_float(sp, json_object_get_double(val));
+	break;
+    case json_type_int:
+	put_number(sp, json_object_get_int(val));
+	break;
+    case json_type_string:
+        put_c_string(sp, json_object_get_string(val));
+	break;
+    case json_type_object:
+      {
+	mapping_t *m;
+	struct lh_entry *e;
+	char *key;
+	struct json_object *newval;
+
+	m = allocate_mapping(json_object_get_object(val)->count, 1); 
+	for (e = json_object_get_object(val)->head; e ? (key = (char*)e->k, newval = (struct json_object *)e->v, e) : 0; e = e->next) {
+	    svalue_t mkey, *mval;
+	    put_c_string(&mkey, key);
+	    mval = get_map_lvalue(m, &mkey);
+	    free_svalue(&mkey);
+	    ldmud_json_inner_parse(mval, newval);
+	}
+	put_mapping(sp, m);
+	break;
+      }
+    case json_type_array:
+      {
+	vector_t *v;
+	struct array_list *a;
+	int size, i;
+	size = json_object_array_length(val);
+	v = allocate_array(size);
+	a = json_object_get_array(val);
+	for (i = 0; i < size; i++) {
+	    ldmud_json_inner_parse(&(v->item[i]), array_list_get_idx(a, i));
+	}
+	put_array(sp, v);
+	break;
+      }
+    }
+    return sp;
+}
+
+svalue_t *
+f_json_parse (svalue_t *sp) {
+    struct json_object *parsed;
+
+    parsed = json_tokener_parse(get_txt(sp->u.str));
+    free_svalue(sp);
+    ldmud_json_inner_parse (sp, parsed);
+    /* TODO: free the object */
+    return sp;
+}
+
+struct json_object *
+ldmud_json_inner_serialize (svalue_t *sp) {
+    struct json_object *val;
+    switch(sp->type) {
+    case T_NUMBER:
+	val = json_object_new_int(sp->u.number);
+	break;
+    case T_STRING:
+	val = json_object_new_string(get_txt(sp->u.str));
+	break;
+    case T_POINTER:
+      {
+	int i;
+	val = json_object_new_array();
+	for (i = VEC_SIZE(sp->u.vec) - 1; i >= 0; i--) 
+	    json_object_array_put_idx(val, i, 
+			ldmud_json_inner_serialize(&sp->u.vec->item[i]));
+	break;
+      }
+    case T_MAPPING:
+      {
+	int i;
+	val = json_object_new_object();
+	for (i = 0; i < MAP_SIZE(sp->u.map); i++) 
+	    walk_mapping(sp->u.map, &ldmud_json_walker, val);
+	break;
+      }
+    case T_FLOAT:
+	val = json_object_new_double(READ_DOUBLE(sp));
+	break;
+    default: /* those are unimplemented */
+	val = json_object_new_object();
+	break; 
+    }
+    return val;
+}
+
+void ldmud_json_walker(svalue_t *key, svalue_t *val, void *parent) 
+{
+    struct json_object *obj = (struct json_object *)parent;
+    if (key->type != T_STRING) 
+	errorf("json only serializes string keys\n");
+	/* NOTREACHED */
+    json_object_object_add(obj, get_txt(key->u.str), 
+			   ldmud_json_inner_serialize(val));
+}
+
+
+svalue_t *
+f_json_serialize (svalue_t *sp) {
+    struct json_object *val;
+    val = ldmud_json_inner_serialize(sp);
+    free_svalue(sp);
+    put_c_string(sp, json_object_to_json_string(val));
+    return sp;
+}
+#endif /* HAS_JSON */
 /*====================================================================*/
 
Index: strfuns.h
===================================================================
--- strfuns.h	(revision 2314)
+++ strfuns.h	(working copy)
@@ -40,4 +40,8 @@
 extern svalue_t * x_map_string (svalue_t *sp, int num_arg);
 extern svalue_t * x_filter_string (svalue_t *sp, int num_arg);
 
+#ifdef USE_JSON
+extern void ldmud_json_walker(svalue_t *key, svalue_t *val, void *parent);
+#endif
+
 #endif /* STRFUNS_H_ */
Index: func_spec
===================================================================
--- func_spec	(revision 2314)
+++ func_spec	(working copy)
@@ -752,6 +752,11 @@
 
 #endif /* USE_TLS */
 
+#ifdef HAS_JSON
+string	json_serialize(mixed);
+mixed	json_parse(string);
+#endif /* HAS_JSON */
+
 /* The following functions are optional and can be configured out.
  */
 
Index: autoconf/acconfig.h
===================================================================
--- autoconf/acconfig.h	(revision 2314)
+++ autoconf/acconfig.h	(working copy)
@@ -108,6 +108,9 @@
 /* Does SQLite3 use pthreads? */
 #undef SQLITE3_USES_PTHREADS
 
+/* Does the machine offer JSON (json-c)? */
+#undef HAS_JSON
+
 /* Does the machine offer GnuTLS? */
 #undef HAS_GNUTLS
 #undef HAS_GNUTLS_VERSION
Index: autoconf/configure.in
===================================================================
--- autoconf/configure.in	(revision 2314)
+++ autoconf/configure.in	(working copy)
@@ -121,6 +121,7 @@
 AC_MY_ARG_ENABLE(use-mysql,no,,[Enables mySQL support])
 AC_MY_ARG_ENABLE(use-pgsql,no,,[Enables PostgreSQL support])
 AC_MY_ARG_ENABLE(use-sqlite,no,,[Enables SQLite support])
+AC_MY_ARG_ENABLE(use-json,no,,[Enables JSON-C Support])
 AC_MY_ARG_ENABLE(use-pthreads,no,,[enable using of threads for socket writes])
 AC_MY_ARG_ENABLE(use-pcre,yes,,[Enables PCRE: no/yes/builtin/no-builtin])
 AC_MY_ARG_ENABLE(use-deprecated,yes,,[Enables obsolete and deprecated efuns])
@@ -320,6 +321,20 @@
   enable_use_sqlite="yes"
 fi
 
+AC_UPDATE_VAR(enable_use_json)
+if test "x$enable_use_json" = "x" || test "x$enable_use_json" = "xyes"; then
+  cdef_use_json="#define"
+  json_path=
+  enable_use_json="yes"
+elif test "x$enable_use_json" = "xno"; then
+  cdef_use_json="#undef"
+  json_path=
+else
+  cdef_use_json="#define"
+  json_path="$enable_use_json"
+  enable_use_json="yes"
+fi
+
 AC_UPDATE_VAR(enable_use_tls)
 if test "x$enable_use_tls" = "x" || test "x$enable_use_tls" = "xyes"; then
   cdef_use_tls="#define"
@@ -1632,6 +1647,23 @@
   fi
 fi
 
+# --- JSON ---
+cdef_enable_use_json="#undef"
+AC_CHECK_HEADER(json/json.h,,[
+		enable_use_json=no
+		lp_cv_has_json=no
+		])
+
+# The system has the json include files - now search for the libraries.
+if test "x$enable_use_json" = "x" || test "x$enable_use_json" = "xyes"; then
+    AC_CHECK_LIB(json, main, [
+		 AC_DEFINE(HAS_JSON)
+		 PKGLIBS="$PKGLIBS -ljson"
+		 lp_cv_has_json=yes
+		 cdef_use_json="#define"
+		 ])
+fi
+
 # --- Check if we need zlib libraries for mccp ---
 
 if test "x$enable_use_mccp" = "x" || test "x$enable_use_mccp" = "xyes"; then
@@ -2634,6 +2666,7 @@
 AC_SUBST(cdef_use_mysql)
 AC_SUBST(cdef_use_pgsql)
 AC_SUBST(cdef_use_sqlite)
+AC_SUBST(cdef_use_json)
 AC_SUBST(cdef_use_pthreads)
 AC_SUBST(cdef_use_alists)
 AC_SUBST(cdef_use_mccp)
Index: machine.h.in
===================================================================
--- machine.h.in	(revision 2314)
+++ machine.h.in	(working copy)
@@ -108,6 +108,9 @@
 /* Does SQLite3 use pthreads? */
 #undef SQLITE3_USES_PTHREADS
 
+/* Does the machine offer json-c support? */
+#undef HAS_JSON
+
 /* Does the machine offer GnuTLS? */
 #undef HAS_GNUTLS
 #undef HAS_GNUTLS_VERSION
Index: config.h.in
===================================================================
--- config.h.in	(revision 2314)
+++ config.h.in	(working copy)
@@ -353,6 +353,11 @@
  */
 @cdef_use_sqlite@ USE_SQLITE
 
+/*Define this if you want JSON support (assuming that your host
+ * actually offers this.
+ */
+@cdef_use_json@ USE_JSON
+
 /* Define this if you want alist support.
  */
 @cdef_use_alists@ USE_ALISTS
