work on cpp support

This commit is contained in:
sfja 2026-03-28 00:48:07 +01:00
parent 283ffaaad6
commit c9d06ad189
10 changed files with 52 additions and 260 deletions

View File

@ -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

View File

@ -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)

View File

@ -1,5 +1,6 @@
-xc
-std=c17
-Iinclude
# -xc
# -std=c17
-pedantic-errors
-Wall
-Wextra

View File

@ -1,4 +1,4 @@
#include "collections.h"
#include "json_collections.h"
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,4 @@
#include "collections.h"
#include "json_collections.h"
#include "json.h"
#include <assert.h>
#include <stdbool.h>

View File

@ -1,4 +1,4 @@
#include "collections.h"
#include "json_collections.h"
#include "json.h"
#include <stdio.h>
#include <string.h>

View File

@ -1,4 +1,4 @@
#include "collections.h"
#include "json_collections.h"
#include "json.h"
#include <assert.h>
#include <stdbool.h>

View File

@ -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);
}