diff --git a/.gitignore b/.gitignore index 37ea8911..68b3f1c6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,10 @@ gst # Generated files -*.genh +*.gen.h + +# Tools +xxd # Tags tags diff --git a/Makefile b/Makefile index 9b45c464..6a43c827 100644 --- a/Makefile +++ b/Makefile @@ -8,18 +8,32 @@ PREFIX?=/usr/local BINDIR=$(PREFIX)/bin VERSION=\"0.0.0-beta\" -CFLAGS=-std=c99 -Wall -Wextra -I./include -g -DGST_VERSION=$(VERSION) +CFLAGS=-std=c99 -Wall -Wextra -I./include -I./libs -g -DGST_VERSION=$(VERSION) PREFIX=/usr/local GST_TARGET=gst -GST_CORELIB=core/libgst.a +GST_XXD=xxd +# Use gdb. On mac use lldb +DEBUGGER=gdb GST_INTERNAL_HEADERS=$(addprefix core/, cache.h) GST_HEADERS=$(addprefix include/gst/, gst.h) -# Use gdb. On mac use lldb -DEBUGGER=gdb +############################# +##### Generated headers ##### +############################# +GST_LANG_SOURCES=$(addprefix libs/, bootstrap.gst) +GST_LANG_HEADERS=$(patsubst %.gst,%.gen.h,$(GST_LANG_SOURCES)) all: $(GST_TARGET) +####################### +##### Build tools ##### +####################### +$(GST_XXD): libs/xxd.c + $(CC) -o $(GST_XXD) libs/xxd.c + +%.gen.h : %.gst $(GST_XXD) + ./$(GST_XXD) $< $@ $(basename $(notdir $<)) + ################################### ##### The core vm and runtime ##### ################################### @@ -34,11 +48,11 @@ GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES)) ###################### GST_CLIENT_SOURCES=client/main.c GST_CLIENT_OBJECTS=$(patsubst %.c,%.o,$(GST_CLIENT_SOURCES)) -$(GST_TARGET): $(GST_CLIENT_OBJECTS) $(GST_CORE_OBJECTS) +$(GST_TARGET): $(GST_CLIENT_OBJECTS) $(GST_CORE_OBJECTS) $(GST_LANG_HEADERS) $(CC) $(CFLAGS) -o $(GST_TARGET) $(GST_CLIENT_OBJECTS) $(GST_CORE_OBJECTS) # Compile all .c to .o -%.o : %.c $(GST_HEADERS) $(GST_INTERNAL_HEADERS) +%.o : %.c $(GST_HEADERS) $(GST_INTERNAL_HEADERS) $(GST_LANG_HEADERS) $(CC) $(CFLAGS) -o $@ -c $< run: $(GST_TARGET) @@ -52,10 +66,11 @@ valgrind: $(GST_TARGET) clean: rm $(GST_TARGET) || true - rm $(GST_CORELIB) || true rm $(GST_CORE_OBJECTS) || true rm $(GST_CLIENT_OBJECTS) || true + rm $(GST_LANG_HEADERS) || true rm vgcore.* || true + rm $(GST_XXD) || true test: $(GST_TARGET) @ ./$(GST_TARGET) gsttests/basic.gst diff --git a/libs/xxd.c b/libs/xxd.c new file mode 100644 index 00000000..dc91402e --- /dev/null +++ b/libs/xxd.c @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2017 Calvin Rose +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +/* Simple clone of the xxd tool used at build time. Used to + * create headers out of source files. Only used for core libraries + * like the bootstrapping code and the stl. */ + +#include +#include +#include + +#define BUFSIZE 1024 +#define PERLINE 16 + +int main(int argc, const char **argv) { + + static const char hex[] = "0123456789ABCDEF"; + char buf[BUFSIZE]; + size_t bytesRead = 0; + int lineIndex = 0; + int line = 0; + + if (argc != 4) { + fprintf(stderr, "Usage: %s infile outfile symbol\n", argv[0]); + return 1; + } + + /* Open the files */ + FILE *in = fopen(argv[1], "rb"); + FILE *out = fopen(argv[2], "wb"); + + /* Check if files open successfully */ + if (in == NULL) { + fprintf(stderr, "Could not open input file %s\n", argv[1]); + return 1; + } else if (out == NULL) { + fprintf(stderr, "Could not open output file %s\n", argv[2]); + return 1; + } + + /* Write the header */ + fprintf(out, "/* Auto generated - DO NOT EDIT */\n\n"); + fprintf(out, "#include \n\n"); + fprintf(out, "const uint8_t gst_gen_%s[] = {", argv[3]); + + /* Read in chunks from buffer */ + while ((bytesRead = fread(buf, 1, sizeof(buf), in)) > 0) { + int i; + for (i = 0; i < bytesRead; ++i) { + int byte = ((uint8_t *)buf) [i]; + + /* Write the byte */ + if (lineIndex++ == 0) { + if (line++) + fputc(',', out); + fputs("\n\t", out); + } else { + fputs(", ", out); + } + fputs("0x", out); + fputc(hex[byte & 0xF], out); + fputc(hex[byte >> 4], out); + + /* Make line index wrap */ + if (lineIndex >= PERLINE) + lineIndex = 0; + + } + } + + /* Write the tail */ + fputs("\n};\n", out); + + /* Close the file handles */ + fclose(in); + fclose(out); + + return 0; +} \ No newline at end of file