diff --git a/.clang-format b/.clang-format index 9e0bd38..1b2caee 100644 --- a/.clang-format +++ b/.clang-format @@ -1,3 +1,4 @@ +Language: C BasedOnStyle: WebKit IndentWidth: 4 ColumnLimit: 80 @@ -15,4 +16,24 @@ AllowAllParametersOfDeclarationOnNextLine: true PointerAlignment: Right QualifierAlignment: Right +--- +Language: Cpp + +BasedOnStyle: WebKit +IndentWidth: 4 +ColumnLimit: 80 + +IndentCaseLabels: true +InsertNewlineAtEOF: true +AllowShortFunctionsOnASingleLine: None + +BinPackArguments: false +BinPackLongBracedList: false +BinPackParameters: OnePerLine + +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true + +PointerAlignment: Left +QualifierAlignment: Left diff --git a/Makefile b/Makefile index 95d9c6f..702fae0 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ MAKEFLAGS += -j16 -CFLAGS=-std=c17 -pedantic-errors -Wall -Wextra -Wconversion +CFLAGS=-Iinclude -std=c17 -pedantic-errors -Wall -Wextra -Wconversion +CXXFLAGS=-Iinclude -std=c++20 -pedantic-errors -Wall -Wextra -Wconversion LDFLAGS= # Some of the sussy stuff needs this @@ -10,46 +11,60 @@ CFLAGS+=-Wno-strict-aliasing ASAN=0 ifeq ($(ASAN),1) CFLAGS += -fsanitize=address + CXXFLAGS += -fsanitize=address endif LTO=0 ifeq ($(ASAN),1) CFLAGS += -flto=auto + CXXFLAGS += -flto=auto endif RELEASE=0 ifeq ($(RELEASE),1) CFLAGS += -O3 + CXXFLAGS += -O3 else CFLAGS += -g -ggdb + CXXFLAGS += -g -ggdb endif build_dir = build obj_dir = $(build_dir)/obj -sources = \ - src/main.c \ +lib_sources = \ src/collections.c \ src/json_value.c \ src/json_parse.c \ src/json_query.c \ - src/json_stringify.c + src/json_stringify.c \ + src/json_cpp.cpp -target=$(build_dir)/jq +jq_sources = $(lib_sources) src/main.c -all: $(target) +lib_target=$(build_dir)/libjson.a +jq_target=$(build_dir)/jq -debug: $(target) +all: $(lib_target) $(jq_target) + +debug: $(jq_target) # gdb -ex 'r' --args build/jq '.' data.json - gdb -ex 'r' --args build/jq '[11350].payload.issues.user' large-file-formatted.json + gdb -ex 'r' --args $< '[11350].payload.issues.user' large-file-formatted.json -$(target): $(sources:%.c=$(obj_dir)/%.o) +$(lib_target): $(lib_sources:%.c=$(obj_dir)/%.o) + ar rcs $@ $^ + +$(jq_target): $(jq_sources:%.c=$(obj_dir)/%.o) gcc -o $@ $(CFLAGS) $(LDFLAGS) $^ $(obj_dir)/%.o: %.c @mkdir -p $(dir $@) gcc $< -c -o $@ -MMD -MP $(CFLAGS) +$(obj_dir)/%.o: %.cpp + @mkdir -p $(dir $@) + gcc $< -c -o $@ -MMD -MP $(CXXFLAGS) + clean: rm -rf $(build_dir) diff --git a/compile_flags.txt b/compile_flags.txt index abc7b40..d53c96a 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,5 +1,6 @@ --xc --std=c17 +-Iinclude +# -xc +# -std=c17 -pedantic-errors -Wall -Wextra diff --git a/src/collections.c b/src/collections.c index 233cb69..c613040 100644 --- a/src/collections.c +++ b/src/collections.c @@ -1,4 +1,4 @@ -#include "collections.h" +#include "json_collections.h" #include #include #include diff --git a/src/collections.h b/src/collections.h deleted file mode 100644 index 1fb386d..0000000 --- a/src/collections.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef COLLECTIONS_H -#define COLLECTIONS_H - -#include -#include -#include - -void *array_push(void **data, - size_t *capacity, - size_t *count, - void const *elem, - size_t elem_size); - -void *array_insert_at(void **data, - size_t *capacity, - size_t *count, - size_t idx, - void const *elem, - size_t elem_size); - -struct smallarray { - union { - size_t smalldata[3]; - struct { - void **data; - size_t capacity; - size_t count; - }; - }; -}; - -void smallarray_construct(struct smallarray *a); -void smallarray_destroy(struct smallarray *a); -void smallarray_push(struct smallarray *a, void *value); -size_t smallarray_count(struct smallarray const *a); -void *smallarray_get(struct smallarray *a, size_t idx); -void const *smallarray_get_const(struct smallarray const *a, size_t idx); - -struct hash_entry { - uint64_t hash; - void *value; -}; - -#define bucket_capacity 16 - -struct hash_bucket { - struct hash_entry entries[bucket_capacity]; - size_t count; - uint64_t first_hash; - uint64_t last_hash; -}; - -struct hash_key_entry { - uint64_t hash; - char *value; -}; - -struct hashmap { - struct hash_bucket *buckets; - size_t buckets_capacity; - size_t buckets_count; - struct hash_key_entry *keys; - size_t keys_capacity; - size_t keys_count; -}; - -void hashmap_construct(struct hashmap *m); -void hashmap_destroy(struct hashmap *m); -void hashmap_set(struct hashmap *m, char const *key, void *value); -void hashmap_set_sized( - struct hashmap *m, char const *key, size_t key_size, void *value); -bool hashmap_has(struct hashmap *m, char const *key); -void *hashmap_get(struct hashmap *m, char const *key); -void *hashmap_get_sized(struct hashmap *m, char const *key, size_t key_size); -void *hashmap_get_hash(struct hashmap *m, size_t hash); -void const *hashmap_get_hash_const(struct hashmap const *m, size_t hash); -void hashmap_keys( - struct hashmap const *m, struct hash_key_entry const **keys, size_t* count); - -#define blockalloc_default_block 4096 - -struct blockalloc_block; - -struct blockalloc { - struct blockalloc_block *blocks; - size_t capacity; - size_t count; - size_t p; -}; - -void blockalloc_construct(struct blockalloc *a); -void blockalloc_destroy(struct blockalloc *a); -void *blockalloc_alloc(struct blockalloc *a, size_t size, size_t align); - -#endif diff --git a/src/json.h b/src/json.h deleted file mode 100644 index 33030b0..0000000 --- a/src/json.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef JSON_H -#define JSON_H - -#include "collections.h" -#include -#include -#include - -enum json_type { - json_null = 1, - json_false = 2, - json_true = 3, - json_int, - json_float, - json_string, - json_array, - json_object, -}; - -struct json_value; - -struct json_value *json_new(enum json_type type); -void json_free(struct json_value *value); - -bool json_is(struct json_value const *value, enum json_type type); - -enum json_type json_get_type(struct json_value const *value); -bool json_get_bool(struct json_value const *value); -int64_t json_get_int(struct json_value const *value); -double json_get_float(struct json_value const *value); -char const *json_get_string(struct json_value const *value); - -void json_set_null(struct json_value **value); -void json_set_bool(struct json_value **value, bool val); -void json_set_int(struct json_value **value, int64_t val); -void json_set_float(struct json_value **value, double val); -void json_set_string(struct json_value *value, char *vaAl); - -struct json_value *json_new_int(int64_t val); -struct json_value *json_new_float(double val); - -size_t json_array_count(struct json_value const *array); -struct json_value *json_idx(struct json_value *array, size_t idx); -struct json_value const *json_idx_const( - struct json_value const *array, size_t idx); -void json_push(struct json_value *array, struct json_value *value); - -struct json_value *json_key(struct json_value *object, char const *key); -struct json_value *json_key_sized( - struct json_value *object, char const *key, size_t key_size); -struct json_value const *json_key_hash_const( - struct json_value const *object, size_t hash); -void json_set( - struct json_value *object, char const *key, struct json_value *value); -void json_set_sized(struct json_value *object, - char const *key, - size_t key_size, - struct json_value *value); -void json_object_keys(struct json_value const *object, - struct hash_key_entry const **keys, - size_t *count); - -struct json_value *json_parse( - char const *text, size_t text_size, struct blockalloc *alloc); - -struct json_value *json_query(struct json_value *val, char const *query); - -typedef int JsonWriteCb(void *self, char const *data, size_t size); - -int json_stringify( - struct json_value const *node, JsonWriteCb write, void *self); - -#endif diff --git a/src/json_parse.c b/src/json_parse.c index 65f7070..c1ee947 100644 --- a/src/json_parse.c +++ b/src/json_parse.c @@ -1,4 +1,4 @@ -#include "collections.h" +#include "json_collections.h" #include "json.h" #include #include diff --git a/src/json_stringify.c b/src/json_stringify.c index db8ec59..bf78a24 100644 --- a/src/json_stringify.c +++ b/src/json_stringify.c @@ -1,4 +1,4 @@ -#include "collections.h" +#include "json_collections.h" #include "json.h" #include #include diff --git a/src/json_value.c b/src/json_value.c index 6889a51..ceadc8f 100644 --- a/src/json_value.c +++ b/src/json_value.c @@ -1,4 +1,4 @@ -#include "collections.h" +#include "json_collections.h" #include "json.h" #include #include diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 5c65d2e..0000000 --- a/src/main.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "collections.h" -#include "json.h" -#include -#include -#include -#include -#include -#include -#include -#include - -static int stringify_cb(void *self, char const *data, unsigned long size) -{ - (void)self; - fwrite(data, size, 1, stdout); - return 0; -} - -int main(int argc, char *argv[]) -{ - if (argc < 3) { - fprintf(stderr, "error: incorrect arguments\n"); - return EXIT_FAILURE; - } - char const *query = argv[1]; - char const *filename = argv[2]; - - FILE *file = fopen(filename, "r"); - if (!file) { - fprintf(stderr, - "error: could not open file (%s) \"%s\"\n", - strerror(errno), - filename); - return EXIT_FAILURE; - } - - fseek(file, 0, SEEK_END); - long ftell_result = ftell(file); - if (ftell_result < 0) { - fprintf(stderr, "error: could not tell (%s)\n", strerror(errno)); - return EXIT_FAILURE; - } - fseek(file, 0, SEEK_SET); - size_t file_size = (size_t)ftell_result; - char *text = malloc(file_size + 1); - - size_t bytes_read = fread(text, 1, file_size, file); - if (bytes_read != file_size) { - fprintf(stderr, - "error: could not read %ld/%ld (%s)\n", - bytes_read, - file_size, - strerror(errno)); - return EXIT_FAILURE; - } - fclose(file); - - struct blockalloc alloc = { 0 }; - blockalloc_construct(&alloc); - - struct json_value *parsed = json_parse(text, file_size, &alloc); - if (!parsed) { - fprintf(stderr, "something went wrong\n"); - return EXIT_FAILURE; - } - free(text); - - struct json_value *result = json_query(parsed, query); - if (!result) { - return EXIT_FAILURE; - } - json_stringify(result, stringify_cb, NULL); - fputc('\n', stdout); - - json_free(parsed); - blockalloc_destroy(&alloc); -}