Skip to content

Commit

Permalink
prep c testgen
Browse files Browse the repository at this point in the history
  • Loading branch information
jon-codes committed Oct 4, 2024
1 parent 98fb412 commit 271c976
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ root = true

[*]
indent_style = space
indent_size = 2
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
Expand Down
18 changes: 16 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
bin
tmp
*.test
*.out
go.work

/bin/
/tmp/
/obj/

.idea
.vscode/*
!.vscode/extensions.json

.vgcore.*
*.log
*.local
*.o
*.a
*.su
77 changes: 57 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
.DEFAULT_GOAL = all

GOFLAGS = -ldflags '-linkmode external -extldflags "-static"'
BINDIR = bin
TMPDIR = tmp
TESTGEN_SRC = cmd/testgen/main.go
TESTGEN_BIN = $(BINDIR)/testgen
GOPKG = github.com/jon-codes/getopt
GOPKG := github.com/jon-codes/getopt

BINDIR := bin
TMPDIR := tmp
OBJDIR := obj

CC := gcc
CFLAGS_BASE := -std=c23 -Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter -Wshadow -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Wredundant-decls -Wnested-externs -Wmissing-include-dirs -Wjump-misses-init -Wlogical-op
CFLAGS := $(CFLAGS_BASE) -O2 $(TESTGEN_INCL)
CFLAGS_DEBUG = $(CFLAGS_BASE) -g -O0 $(TESTGEN_INCL)

TESTGEN_SRCDIR := testgen
TESTGEN_DATADIR := testdata
TESTGEN_BIN := $(BINDIR)/testgen
TESTGEN_DEBUG_BIN := $(BINDIR)/testgen-debug
TESTGEN_SRCS := $(wildcard $(TESTGEN_SRCDIR)/*.c)
TESTGEN_OBJS := $(patsubst $(TESTGEN_SRCDIR)/%.c,$(OBJDIR)/%.o,$(TESTGEN_SRCS))
TESTGEN_DEBUG_OBJS := $(patsubst $(TESTGEN_SRCDIR)/%.c,$(OBJDIR)/%_debug.o,$(TESTGEN_SRCS))
TESTGEN_INCL := -I$(TESTGEN_SRCDIR) -I/usr/include -ljansson
TESTGEN_INPUT := $(TESTGEN_DATADIR)/cases.json
TESTGEN_OUTPUT := $(TESTGEN_DATADIR)/fixtures.json

## all: run development tasks (default target)
.PHONY: all
Expand Down Expand Up @@ -45,31 +60,53 @@ test:

.PHONY: test-check
test-check:
go test -v ./...
go test -count=1 -v ./...

## cover: go test coverage
.PHONY: cover
cover: temp
cover: $(TMPDIR)
go test -v -coverprofile $(TMPDIR)/cover.out $(GOPKG)
go tool cover -html=$(TMPDIR)/cover.out

## clean: clean output
.PHONY: clean
clean:
rm -rf $(BINDIR) $(TMPDIR) $(OBJDIR)

$(TMPDIR) $(BINDIR) $(OBJDIR):
mkdir -p $@

## testgen: generate test data
testgen: $(TESTGEN_OUTPUT)

## testgen-build: build testgen binary
.PHONY: testgen-build
testgen-build:
CC=$(shell which musl-gcc) go build $(GOFLAGS) -o $(TESTGEN_BIN) $(TESTGEN_SRC)
testgen-build: $(TESTGEN_BIN)

## testgen: generate tests
.PHONY: testgen
testgen:
$(TESTGEN_BIN)
.PHONY: testgen-debug
testgen-debug: $(TESTGEN_DEBUG_BIN)

## clean: clean output
.PHONY: clean
clean:
rm -r $(BINDIR) $(TMPDIR)
$(TESTGEN_BIN): $(TESTGEN_OBJS) | $(BINDIR)
$(CC) $(CFLAGS) -o $@ $(TESTGEN_OBJS)

$(TESTGEN_DEBUG_BIN): $(TESTGEN_DEBUG_OBJS) | $(BINDIR)
$(CC) $(CFLAGS_DEBUG) -o $@ $(TESTGEN_DEBUG_OBJS)

$(OBJDIR)/%.o: $(TESTGEN_SRCDIR)/%.c | $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@

$(OBJDIR)/%_debug.o: $(TESTGEN_SRCDIR)/%.c | $(OBJDIR)
$(CC) $(CFLAGS_DEBUG) -c $< -o $@

## valgrind: run testgen with valgrind
.PHONY: valgrind
valgrind: $(TESTGEN_DEBUG_BIN)
valgrind --leak-check=full $(TESTGEN_DEBUG_BIN) -o $(TESTGEN_OUTPUT) $(TESTGEN_INPUT)

temp:
mkdir -p tmp
## gdb: run testgen with gdb
.PHONY: gdb
gdb: $(TESTGEN_DEBUG_BIN)
gdb --args $(TESTGEN_DEBUG_BIN) -o $(TESTGEN_OUTPUT) $(TESTGEN_INPUT)

## help: display this help
.PHONY: help
Expand Down
139 changes: 139 additions & 0 deletions testgen/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#define _POSIX_C_SOURCE 200809L

#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef enum Result {
RESULT_OK,
RESULT_ERR,
RESULT_DONE,
} Result;

static void print_usage(const char *name) {
fprintf(stderr, "usage: %s -o <outfile> <infile>\n", name);
}

typedef struct Config {
const char *inpath;
const char *outpath;
} Config;

static void config_destroy(Config *cfg) {
if (cfg != NULL) {
free((char *)cfg->outpath);
free((char *)cfg->inpath);
free(cfg);
}
}

static Config *create_config(int argc, char *argv[]) {
Config *cfg = calloc(1, sizeof(Config));
if (cfg == NULL) {
fprintf(stderr, "error allocating config: %s\n", strerror(errno));
return NULL;
}

int opt;
while ((opt = getopt(argc, argv, ":o:")) != -1) {
switch (opt) {
case 'o':
cfg->outpath = strdup(optarg);
if (cfg->outpath == NULL) {
fprintf(stderr, "error allocating config: %s\n", strerror(errno));
config_destroy(cfg);
return NULL;
}
break;
case '?':
fprintf(stderr, "error: Unknown option \"%c\"\n", optopt);
print_usage(argv[0]);
config_destroy(cfg);
return NULL;
case ':':
fprintf(stderr, "error: Option \"%c\" requires an argument\n", optopt);
print_usage(argv[0]);
config_destroy(cfg);
return NULL;
default:
break;
}
}

if (cfg->outpath == NULL) {
fprintf(stderr, "error: Option -o is required\n");
print_usage(argv[0]);
config_destroy(cfg);
return NULL;
}

if (optind < argc) {
cfg->inpath = strdup(argv[optind]);
if (cfg->inpath == NULL) {
fprintf(stderr, "error allocating config: %s\n", strerror(errno));
config_destroy(cfg);
return NULL;
}
} else {
fprintf(stderr, "error: missing required infile parameter\n");
print_usage(argv[optind]);
config_destroy(cfg);
return NULL;
}

return cfg;
}

typedef struct Case {
char *label;
} Case;

void case_destroy(Case *c) {
if (c != NULL) {
free(c->label);
}
}

typedef struct CaseIterator {
bool has_next;
} CaseIterator;

CaseIterator *create_case_iterator(Config *cfg) {
return NULL;
}

int main(int argc, char *argv[]) {
Config *cfg = create_config(argc, argv);
if (cfg == NULL) {
return EXIT_FAILURE;
}

FILE *infile = fopen(cfg->inpath, "r");
if (infile == NULL) {
fprintf(stderr, "error opening %s: %s\n", cfg->inpath, strerror(errno));
config_destroy(cfg);
return EXIT_FAILURE;
}

FILE *outfile = fopen(cfg->outpath, "w");
if (outfile == NULL) {
fprintf(stderr, "error opening %s: %s\n", cfg->inpath, strerror(errno));
fclose(infile);
config_destroy(cfg);
return EXIT_FAILURE;
}

// CaseIterator *iter = create_case_iterator(cfg);
// if (iter == NULL) {
// config_destroy(cfg);
// return EXIT_FAILURE;
// }

fclose(infile);
fclose(outfile);
config_destroy(cfg);
return EXIT_SUCCESS;
}

0 comments on commit 271c976

Please sign in to comment.