diff --git a/TODO.txt b/TODO.txt index 8d7be9c..40d3049 100644 --- a/TODO.txt +++ b/TODO.txt @@ -28,8 +28,9 @@ Milestone: v0.3.0 [x] Built on HTTP client API [ ] http man page [~] Simple command line tool for working with JSON - [x] Should pretty-print Json - [ ] Query fields for use in shell scripts. + [x] Pretty-print Json + [x] Query fields for use in shell scripts. + [ ] Encode user-provided JSON strings [ ] json man page [ ] Move configuration to database diff --git a/tools/src/http.c b/tools/src/http.c index e25693f..b116f76 100644 --- a/tools/src/http.c +++ b/tools/src/http.c @@ -83,7 +83,7 @@ main(int argc, char **argv) if (!method) { fprintf(stderr, "Unknown request method: %s\n", optarg); - return -1; + return 1; } break; case 'H': @@ -107,21 +107,21 @@ main(int argc, char **argv) break; default: usage(argv[0]); - return -1; + return 1; } } if (argc - optind < 1) { usage(argv[0]); - return -1; + return 1; } uri = UriParse(argv[optind]); if (!uri) { fprintf(stderr, "Failed to parse URI: %s\n", argv[optind]); - return -1; + return 1; } if (!uri->port) @@ -140,7 +140,7 @@ main(int argc, char **argv) { fprintf(stderr, "Unknown protocol: %s\n", uri->proto); UriFree(uri); - return -1; + return 1; } if (strcmp(uri->proto, "https") == 0) @@ -154,7 +154,7 @@ main(int argc, char **argv) { fprintf(stderr, "Failed to connect.\n"); UriFree(uri); - return -1; + return 1; } while (HashMapIterate(requestHeaders, &key, (void **) &val)) @@ -180,7 +180,7 @@ main(int argc, char **argv) fprintf(stderr, "Failed to send request.\n"); HttpClientContextFree(cx); UriFree(uri); - return -1; + return 1; } if (flags & FLAG_HEADERS) diff --git a/tools/src/json.c b/tools/src/json.c index a010523..765700f 100644 --- a/tools/src/json.c +++ b/tools/src/json.c @@ -22,7 +22,12 @@ * SOFTWARE. */ #include +#include +#include +#include +#include +#include #include int @@ -38,8 +43,131 @@ main(int argc, char **argv) return 1; } - JsonEncode(json, stdout, JSON_PRETTY); - printf("\n"); + if (argc > 1) + { + char *select = argv[1]; + char *key; + JsonValue *val = JsonValueObject(json); + key = strtok(select, "->"); + + while (key) + { + char keyName[128]; + size_t arrInd; + int expectArr = 0; + int func = 0; + + expectArr = (sscanf(key, "%127[^[][%lu]", keyName, &arrInd) == 2); + + if (keyName[0] == '@') + { + if (strcmp(keyName + 1, "length") == 0) + { + switch (JsonValueType(val)) + { + case JSON_ARRAY: + val = JsonValueInteger(ArraySize(JsonValueAsArray(val))); + break; + case JSON_STRING: + val = JsonValueInteger(strlen(JsonValueAsString(val))); + break; + default: + val = NULL; + break; + } + } + else if (JsonValueType(val) == JSON_OBJECT && strcmp(keyName + 1, "keys") == 0) + { + HashMap *obj = JsonValueAsObject(val); + Array *arr = ArrayCreate(); + char *k; + void *v; + + while (HashMapIterate(obj, &k, &v)) + { + ArrayAdd(arr, JsonValueString(k)); + } + + val = JsonValueArray(arr); + } + else if (JsonValueType(val) == JSON_STRING && strcmp(keyName + 1, "decode") == 0) + { + printf("%s", JsonValueAsString(val)); + val = NULL; + break; + } + else + { + val = NULL; + break; + } + + func = 1; + } + else if (keyName[0] == '!') + { + if (JsonValueType(val) == JSON_OBJECT) + { + HashMap *obj = JsonValueAsObject(val); + + JsonValueFree(HashMapDelete(obj, keyName + 1)); + } + else if (JsonValueType(val) == JSON_ARRAY) + { + size_t i; + + sscanf(keyName + 1, "%lu", &i); + JsonValueFree(ArrayDelete(JsonValueAsArray(val), i)); + } + else + { + val = NULL; + break; + } + + func = 1; + } + + if (!func) + { + if (JsonValueType(val) == JSON_OBJECT) + { + val = HashMapGet(JsonValueAsObject(val), keyName); + } + else + { + val = NULL; + break; + } + } + + if (expectArr && JsonValueType(val) == JSON_ARRAY) + { + val = ArrayGet(JsonValueAsArray(val), arrInd); + } + + if (!val) + { + break; + } + + key = strtok(NULL, "->"); + } + + if (val) + { + JsonEncodeValue(val, stdout, JSON_PRETTY); + } + + printf("\n"); + } + else + { + JsonEncode(json, stdout, JSON_PRETTY); + JsonFree(json); + } + + MemoryFreeAll(); return 0; }