openwrt中在shell中对json数据进行了处理,通过设置一些环境变量的值,来索引一个json数据。

jshc.sh是一个脚本,提供了一些设置json数据的环境变量
jshc是一个c写的获取环境变量,并解析出来json数据的函数,比如使用方法json -w。

gcc -o jshn jshn.c -ljson-c -I/usr/local/include/json-c        //可以使用的编译方式。

export K_J_V="hello world"


export J_V_hello=karl
export T_J_V_hello=string
export N_J_V_hello=kim


export J_V_world=liu
export T_J_V_world=object
export N_J_V_world=ssss


export K_liu="li dongwu"
export liu_li=my
export T_liu_li=string
export N_liu_li=yang


export liu_dongwu="mao"
export T_liu_dongwu=string
export N_liu_dongwu="cat"
./jshn -w


J_V为一个object,这个object包含了一系列的子object。所以必须有K_J_V表示每一个子object.


对于其中的一个子object,比如hello.
必须有如下资料
J_V_hello表示对象的值
T_J_V_hello 表示对象的类型
N_J_V_hello 表示对象的名字


比如字符串
J_V_hello="string value"
比如对象
J_V_hello="envsubobject"
envsubobject包含的对象如何去找到,则需要继续找
K_envsubobject="subobj1 subobj2"
这样后面的子对象
envsubobject_subobj1="value1"
T_envsuboject_subobj1=string
N_envsubobject_subobject1="subobj1"


附jshc.c源码:

点击(此处)折叠或打开

  1. /*
  2.  * Copyright (C) 2011-2013 Felix Fietkau <nbd@openwrt.org>
  3.  *
  4.  * Permission to use, copy, modify, and/or distribute this software for any
  5.  * purpose with or without fee is hereby granted, provided that the above
  6.  * copyright notice and this permission notice appear in all copies.
  7.  *
  8.  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9.  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10.  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11.  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13.  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15.  */
  16.         #include <json.h>

  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <stdbool.h>
  21. #include <ctype.h>
  22. #include <getopt.h>

  23. #define MAX_VARLEN    256


  24. static const char *var_prefix = "";
  25. static int var_prefix_len = 0;

  26. static int add_json_element(const char *key, json_object *obj);

  27. static int add_json_object(json_object *obj)
  28. {
  29.     int ret = 0;

  30.     json_object_object_foreach(obj, key, val) {
  31.         ret = add_json_element(key, val);
  32.         if (ret)
  33.             break;
  34.     }
  35.     return ret;
  36. }

  37. static int add_json_array(struct array_list *a)
  38. {
  39.     char seq[12];
  40.     int i, len;
  41.     int ret;

  42.     for (i = 0, len = array_list_length(a); i < len; i++) {
  43.         sprintf(seq, "%d", i);
  44.         ret = add_json_element(seq, array_list_get_idx(a, i));
  45.         if (ret)
  46.             return ret;
  47.     }

  48.     return 0;
  49. }

  50. static void add_json_string(const char *str)
  51. {
  52.     char *ptr = (char *) str;
  53.     int len;
  54.     char *c;

  55.     while ((c = strchr(ptr, '\'')) != NULL) {
  56.         len = c - ptr;
  57.         if (len > 0)
  58.             fwrite(ptr, len, 1, stdout);
  59.         ptr = c + 1;
  60.         c = "'\\''";
  61.         fwrite(c, strlen(c), 1, stdout);
  62.     }
  63.     len = strlen(ptr);
  64.     if (len > 0)
  65.         fwrite(ptr, len, 1, stdout);
  66. }

  67. static void write_key_string(const char *key)
  68. {
  69.     while (*key) {
  70.         putc(isalnum(*key) ? *key : '_', stdout);
  71.         key++;
  72.     }
  73. }

  74. static int add_json_element(const char *key, json_object *obj)
  75. {
  76.     char *type;

  77.     if (!obj)
  78.         return -1;

  79.     switch (json_object_get_type(obj)) {
  80.     case json_type_object:
  81.         type = "object";
  82.         break;
  83.     case json_type_array:
  84.         type = "array";
  85.         break;
  86.     case json_type_string:
  87.         type = "string";
  88.         break;
  89.     case json_type_boolean:
  90.         type = "boolean";
  91.         break;
  92.     case json_type_int:
  93.         type = "int";
  94.         break;
  95.     case json_type_double:
  96.         type = "double";
  97.         break;
  98.     default:
  99.         return -1;
  100.     }

  101.     fprintf(stdout, "json_add_%s '", type);
  102.     write_key_string(key);

  103.     switch (json_object_get_type(obj)) {
  104.     case json_type_object:
  105.         fprintf(stdout, "';\n");
  106.         add_json_object(obj);
  107.         fprintf(stdout, "json_close_object;\n");
  108.         break;
  109.     case json_type_array:
  110.         fprintf(stdout, "';\n");
  111.         add_json_array(json_object_get_array(obj));
  112.         fprintf(stdout, "json_close_array;\n");
  113.         break;
  114.     case json_type_string:
  115.         fprintf(stdout, "' '");
  116.         add_json_string(json_object_get_string(obj));
  117.         fprintf(stdout, "';\n");
  118.         break;
  119.     case json_type_boolean:
  120.         fprintf(stdout, "' %d;\n", json_object_get_boolean(obj));
  121.         break;
  122.     case json_type_int:
  123.         fprintf(stdout, "' %d;\n", json_object_get_int(obj));
  124.         break;
  125.     case json_type_double:
  126.         fprintf(stdout, "' %lf;\n", json_object_get_double(obj));
  127.         break;
  128.     default:
  129.         return -1;
  130.     }

  131.     return 0;
  132. }

  133. static int jshn_parse(const char *str)
  134. {
  135.     json_object *obj;

  136.     obj = json_tokener_parse(str);
  137.     if (!obj || json_object_get_type(obj) != json_type_object) {
  138.         fprintf(stderr, "Failed to parse message data\n");
  139.         return 1;
  140.     }
  141.     fprintf(stdout, "json_init;\n");
  142.     add_json_object(obj);
  143.     fflush(stdout);

  144.     return 0;
  145. }

  146. static char *get_keys(const char *prefix)
  147. {
  148.     char *keys;

  149.     keys = alloca(var_prefix_len + strlen(prefix) + sizeof("K_") + 1);
  150.     sprintf(keys, "%sK_%s", var_prefix, prefix);
  151.     printf("getenv %s\n", keys);
  152.     return getenv(keys);
  153. }

  154. static void get_var(const char *prefix, const char **name, char **var, char **type)
  155. {
  156.     char *tmpname, *varname;

  157.     tmpname = alloca(var_prefix_len + strlen(prefix) + 1 + strlen(*name) + 1 + sizeof("T_"));

  158.     sprintf(tmpname, "%s%s_%s", var_prefix, prefix, *name);
  159.     *var = getenv(tmpname);
  160.     printf("getenv %s=%s\n", tmpname, *var);

  161.     sprintf(tmpname, "%sT_%s_%s", var_prefix, prefix, *name);
  162.     *type = getenv(tmpname);
  163.     printf("getenv %s=%s\n", tmpname, *type);

  164.     sprintf(tmpname, "%sN_%s_%s", var_prefix, prefix, *name);
  165.     varname = getenv(tmpname);
  166.     printf("getenv %s=%s\n", tmpname, varname);
  167.     if (varname)
  168.         *name = varname;
  169. }

  170. static json_object *jshn_add_objects(json_object *obj, const char *prefix, bool array);

  171. static void jshn_add_object_var(json_object *obj, bool array, const char *prefix, const char *name)
  172. {
  173.     json_object *new;
  174.     char *var, *type;

  175.     get_var(prefix, &name, &var, &type);
  176.     if (!var || !type)
  177.         return;

  178.     if (!strcmp(type, "array")) {
  179.         new = json_object_new_array();
  180.         jshn_add_objects(new, var, true);
  181.     } else if (!strcmp(type, "object")) {
  182.         new = json_object_new_object();
  183.         jshn_add_objects(new, var, false);
  184.     } else if (!strcmp(type, "string")) {
  185.         new = json_object_new_string(var);
  186.     } else if (!strcmp(type, "int")) {
  187.         new = json_object_new_int(atoi(var));
  188.     } else if (!strcmp(type, "double")) {
  189.         new = json_object_new_double(strtod(var, NULL));
  190.     } else if (!strcmp(type, "boolean")) {
  191.         new = json_object_new_boolean(!!atoi(var));
  192.     } else {
  193.         return;
  194.     }

  195.     if (array)
  196.         json_object_array_add(obj, new);
  197.     else
  198.         json_object_object_add(obj, name, new);
  199. }

  200. static json_object *jshn_add_objects(json_object *obj, const char *prefix, bool array)
  201. {
  202.     char *keys, *key, *brk;

  203.     keys = get_keys(prefix);
  204.     printf("prefix=%s, keys=%s\n", prefix, keys);
  205.     if (!keys || !obj)
  206.         goto out;

  207.     for (key = strtok_r(keys, " ", &brk); key;
  208.      key = strtok_r(NULL, " ", &brk)) {
  209.         jshn_add_object_var(obj, array, prefix, key);
  210.     }

  211. out:
  212.     return obj;
  213. }

  214. static int jshn_format(bool no_newline, bool indent)
  215. {
  216.     json_object *obj;
  217.     const char *output;
  218.     int ret = -1;

  219.     if (!(obj = json_object_new_object()))
  220.         return -1;

  221.     jshn_add_objects(obj, "J_V", false);
  222.     if (!(output = json_object_to_json_string(obj)))
  223.         goto out;

  224.     if (indent) {
  225.     }
  226.     fprintf(stdout, "%s%s", output, no_newline ? "" : "\n");
  227.     ret = 0;

  228. out:
  229.     json_object_put(obj);
  230.     return ret;
  231. }

  232. static int usage(const char *progname)
  233. {
  234.     fprintf(stderr, "Usage: %s [-n] [-i] -r |-w\n", progname);
  235.     return 2;
  236. }

  237. int main(int argc, char **argv)
  238. {
  239.     bool no_newline = false;
  240.     bool indent = false;
  241.     int ch;

  242.     while ((ch = getopt(argc, argv, "p:nir:w")) != -1) {
  243.         switch(ch) {
  244.         case 'p':
  245.             var_prefix = optarg;
  246.             var_prefix_len = strlen(var_prefix);
  247.             break;
  248.         case 'r':
  249.             return jshn_parse(optarg);
  250.         case 'w':
  251.             return jshn_format(no_newline, indent);
  252.         case 'n':
  253.             no_newline = true;
  254.             break;
  255.         case 'i


10-21 13:36