work on cpp support
This commit is contained in:
parent
283ffaaad6
commit
c9d06ad189
@ -1,3 +1,4 @@
|
|||||||
|
Language: C
|
||||||
BasedOnStyle: WebKit
|
BasedOnStyle: WebKit
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
@ -15,4 +16,24 @@ AllowAllParametersOfDeclarationOnNextLine: true
|
|||||||
|
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
QualifierAlignment: 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
|
||||||
|
|
||||||
|
|||||||
33
Makefile
33
Makefile
@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
MAKEFLAGS += -j16
|
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=
|
LDFLAGS=
|
||||||
|
|
||||||
# Some of the sussy stuff needs this
|
# Some of the sussy stuff needs this
|
||||||
@ -10,46 +11,60 @@ CFLAGS+=-Wno-strict-aliasing
|
|||||||
ASAN=0
|
ASAN=0
|
||||||
ifeq ($(ASAN),1)
|
ifeq ($(ASAN),1)
|
||||||
CFLAGS += -fsanitize=address
|
CFLAGS += -fsanitize=address
|
||||||
|
CXXFLAGS += -fsanitize=address
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LTO=0
|
LTO=0
|
||||||
ifeq ($(ASAN),1)
|
ifeq ($(ASAN),1)
|
||||||
CFLAGS += -flto=auto
|
CFLAGS += -flto=auto
|
||||||
|
CXXFLAGS += -flto=auto
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RELEASE=0
|
RELEASE=0
|
||||||
ifeq ($(RELEASE),1)
|
ifeq ($(RELEASE),1)
|
||||||
CFLAGS += -O3
|
CFLAGS += -O3
|
||||||
|
CXXFLAGS += -O3
|
||||||
else
|
else
|
||||||
CFLAGS += -g -ggdb
|
CFLAGS += -g -ggdb
|
||||||
|
CXXFLAGS += -g -ggdb
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build_dir = build
|
build_dir = build
|
||||||
obj_dir = $(build_dir)/obj
|
obj_dir = $(build_dir)/obj
|
||||||
|
|
||||||
sources = \
|
lib_sources = \
|
||||||
src/main.c \
|
|
||||||
src/collections.c \
|
src/collections.c \
|
||||||
src/json_value.c \
|
src/json_value.c \
|
||||||
src/json_parse.c \
|
src/json_parse.c \
|
||||||
src/json_query.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 '.' 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) $^
|
gcc -o $@ $(CFLAGS) $(LDFLAGS) $^
|
||||||
|
|
||||||
$(obj_dir)/%.o: %.c
|
$(obj_dir)/%.o: %.c
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
gcc $< -c -o $@ -MMD -MP $(CFLAGS)
|
gcc $< -c -o $@ -MMD -MP $(CFLAGS)
|
||||||
|
|
||||||
|
$(obj_dir)/%.o: %.cpp
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
gcc $< -c -o $@ -MMD -MP $(CXXFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(build_dir)
|
rm -rf $(build_dir)
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
-xc
|
-Iinclude
|
||||||
-std=c17
|
# -xc
|
||||||
|
# -std=c17
|
||||||
-pedantic-errors
|
-pedantic-errors
|
||||||
-Wall
|
-Wall
|
||||||
-Wextra
|
-Wextra
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "collections.h"
|
#include "json_collections.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|||||||
@ -1,95 +0,0 @@
|
|||||||
#ifndef COLLECTIONS_H
|
|
||||||
#define COLLECTIONS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
73
src/json.h
73
src/json.h
@ -1,73 +0,0 @@
|
|||||||
#ifndef JSON_H
|
|
||||||
#define JSON_H
|
|
||||||
|
|
||||||
#include "collections.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "collections.h"
|
#include "json_collections.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "collections.h"
|
#include "json_collections.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "collections.h"
|
#include "json_collections.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|||||||
77
src/main.c
77
src/main.c
@ -1,77 +0,0 @@
|
|||||||
#include "collections.h"
|
|
||||||
#include "json.h"
|
|
||||||
#include <assert.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user