work on cpp support
This commit is contained in:
parent
283ffaaad6
commit
c9d06ad189
@ -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
|
||||
|
||||
|
||||
33
Makefile
33
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)
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
-xc
|
||||
-std=c17
|
||||
-Iinclude
|
||||
# -xc
|
||||
# -std=c17
|
||||
-pedantic-errors
|
||||
-Wall
|
||||
-Wextra
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "collections.h"
|
||||
#include "json_collections.h"
|
||||
#include <assert.h>
|
||||
#include <stdbool.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 <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "collections.h"
|
||||
#include "json_collections.h"
|
||||
#include "json.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "collections.h"
|
||||
#include "json_collections.h"
|
||||
#include "json.h"
|
||||
#include <assert.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