fabricate

commit d71e2c2bb1c7ea6ca6aeaaf59a247c25ce0d0ca8

Author: PQCraft <0456523@gmail.com>

A little setup work

 .gitignore | 16 ++++++++
 Makefile | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/errors.h | 11 +++++
 src/filesystem.c | 10 +++++
 src/filesystem.h | 49 ++++++++++++++++++++++++++
 src/main.c | 56 +++++++++++++++++++++++++++++
 src/string.c | 17 +++++++++
 src/string.h | 10 +++++
 src/vlb.h | 81 +++++++++++++++++++++++++++++++++++++++++++


diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d6a0d2816321e1d809008a71de53546c63c30385
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+*
+!/docs/
+!/docs/**
+!/examples/
+!/examples/**
+!/src/
+!/src/**
+!/tests/
+!/tests/**
+!/*.md
+!/*.sh
+!/LICENSE
+!/Makefile
+.**
+!/.gitattributes
+!/.gitignore




diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..abb5b71cf554a93f30698c4f2ffc902c0ca4050a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,94 @@
+ifneq ($(OS),Windows_NT)
+    PLAT := $(shell uname -s | tr '[:upper:]' '[:lower:]')
+else
+    PLAT := win32
+endif
+
+SRCDIR ?= src
+OBJDIR ?= obj
+OUTDIR ?= .
+
+SYSROOT ?= /usr
+SYSBIN ?= $(SYSROOT)/bin
+
+ifneq ($(DEBUG),y)
+    OBJDIR := $(OBJDIR)/release
+else
+    OBJDIR := $(OBJDIR)/debug
+    ifeq ($(ASAN),y)
+        OBJDIR := $(OBJDIR)_asan
+    endif
+endif
+
+SOURCES := $(wildcard $(SRCDIR)/*.c)
+OBJECTS := $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES))
+
+BIN := $(OUTDIR)/fabricate
+ifeq ($(PLAT),win32)
+    BIN := $(BIN).exe
+endif
+
+CC ?= gcc
+LD := $(CC)
+_CC := $(TOOLCHAIN)$(CC)
+_LD := $(TOOLCHAIN)$(LD)
+
+_CFLAGS := $(CFLAGS) -std=c99 -Wall -Wextra -Wuninitialized -Wundef
+_CPPFLAGS := $(CPPFLAGS)
+_LDFLAGS := $(LDFLAGS)
+_LDLIBS := $(LDLIBS)
+
+ifneq ($(DEBUG),y)
+    _CPPFLAGS += -DNDEBUG
+else
+    _CFLAGS += -g -Wdouble-promotion
+    O ?= g
+    ifeq ($(ASAN),y)
+        _CFLAGS += -fsanitize=address -fno-omit-frame-pointer
+        _LDFLAGS += -fsanitize=address
+    endif
+endif
+_CFLAGS += -O$(O)
+
+.SECONDEXPANSION:
+
+define mkdir
+if [ ! -d '$(1)' ]; then echo 'Creating $(1)/...'; mkdir -p '$(1)'; fi; true
+endef
+define rm
+if [ -f '$(1)' ]; then echo 'Removing $(1)...'; rm -f '$(1)'; fi; true
+endef
+define rmdir
+if [ -d '$(1)' ]; then echo 'Removing $(1)/...'; rm -rf '$(1)'; fi; true
+endef
+
+deps.filter := %.c %.h
+deps.option := -MM
+define deps
+$$(filter $$(deps.filter),,$$(shell $(_CC) $(CFLAGS) $(CPPFLAGS) -E $(deps.option) $(1)))
+endef
+
+build: $(BIN)
+	@:
+
+$(OUTDIR) $(OBJDIR):
+	@$(call mkdir,$@)
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.c $(call deps,$(SRCDIR)/%.c) | $(OBJDIR)
+	@echo Compiling $<...
+	@$(_CC) -c $(_CFLAGS) $(_CPPFLAGS) $< -o $@
+	@echo Compiled $<
+
+$(BIN): $(OBJECTS) | $(OUTDIR)
+	@echo Linking $@...
+	@$(_LD) $(_LDFLAGS) $^ $(_LDLIBS) -o $@
+	-@cd -- $(OUTDIR) && [ -e fab ] || ln -s -- fabricate fab
+	@echo Linked $@
+
+clean:
+	@$(call rmdir,$(OBJDIR))
+
+distclean: clean
+	@$(call rm,$(BIN))
+
+.PHONY: build clean distclean




diff --git a/src/errors.h b/src/errors.h
new file mode 100644
index 0000000000000000000000000000000000000000..a04378283a87a378df72ebce542a6aab8543655d
--- /dev/null
+++ b/src/errors.h
@@ -0,0 +1,11 @@
+#ifndef FAB_ERRORS_H
+#define FAB_ERRORS_H
+
+#include <stdio.h>
+
+extern const char* argv0;
+
+#define ERR_INT() fprintf(stderr, "%s: Internal error\n", argv0)
+#define ERR_NOFAB() fprintf(stderr, "%s: No .fab file found\n", argv0)
+
+#endif




diff --git a/src/filesystem.c b/src/filesystem.c
new file mode 100644
index 0000000000000000000000000000000000000000..5966d86bf499febe0331e97b137133e19a18b069
--- /dev/null
+++ b/src/filesystem.c
@@ -0,0 +1,10 @@
+#include "filesystem.h"
+
+FileInfo* Ls(const char* path, size_t* count) {
+	// TODO
+	return NULL;
+}
+void FreeLs(FileInfo* info) {
+	free(info[-1].name);
+	free(info);
+}




diff --git a/src/filesystem.h b/src/filesystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..f11e296748172cad3890fbf65d8ad10303b3cb61
--- /dev/null
+++ b/src/filesystem.h
@@ -0,0 +1,49 @@
+#ifndef FAB_FILESYSTEM_H
+#define FAB_FILESYSTEM_H
+
+#include "vlb.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <dirent.h>
+
+typedef uint8_t FileType;
+enum {
+	FILETYPE_UNKNOWN,
+	FILETYPE_FILE,
+	FILETYPE_DIR,
+	FILETYPE_SPECIAL
+};
+
+typedef struct {
+	char* name;
+	FileType type;
+} FileInfo;
+
+typedef struct {
+	struct VLB(char) path;
+	FileInfo current;
+	#ifndef _WIN32
+		DIR* dir;
+	#else
+		WIN32_FIND_DATA find;
+		HANDLE file;
+		bool first;
+	#endif
+} LsState;
+
+FileType ProbeFileType(const char* name); // Windows already has GetFileType
+bool ProbeFileInfo(const char* name, FileInfo*);
+
+bool BeginLs(const char*, LsState*);
+const FileInfo* ReadLs(LsState*);
+void EndLs(LsState*);
+
+FileInfo* Ls(const char*, size_t* count);
+void FreeLs(FileInfo*);
+
+bool Rm(const char*);
+bool RmDir(const char*);
+
+#endif




diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..40a8de452041be3badd9f634d15b44e3a6049c74
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,56 @@
+#include "errors.h"
+#include "filesystem.h"
+#include "string.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+
+const char* argv0;
+
+static char* filename;
+
+static int ParseOptions(int argc, char** argv) {
+	for (int i = 1; i < argc; ++i) {
+		if (argv[i][0] != '-') {
+			
+		} else {
+			
+		}
+	}
+	return 0;
+}
+
+static int UseFirstFabFile_Cmp(const void* a, const void* b) {
+	return strcmp(((const FileInfo*)a)->name, ((const FileInfo*)b)->name);
+}
+static int UseFirstFabFile(void) {
+	size_t count;
+	FileInfo* ls = Ls(".", &count);
+	if (!ls) {ERR_INT(); return 2;}
+
+	qsort(ls, count, sizeof(*ls), UseFirstFabFile_Cmp);
+
+	for (size_t i = 0; i < count; ++i) {
+		if (ls[i].type != FILETYPE_DIR && MatchWildcard("*.fab", ls[i].name)) {
+			filename = DupStr(ls[i].name);
+			if (!filename) {ERR_INT(); return 2;}
+			FreeLs(ls);
+			return 0;
+		}
+	}
+
+	FreeLs(ls);
+	ERR_NOFAB();
+	return 1;
+}
+
+int main(int argc, char** argv) {
+	argv0 = argv[0];
+	int ret;
+	if ((ret = ParseOptions(argc + 1, argv - 1))) return ret;
+	if (!filename && (ret = UseFirstFabFile())) return ret;
+	// TODO
+	return 0;
+}




diff --git a/src/string.c b/src/string.c
new file mode 100644
index 0000000000000000000000000000000000000000..ae8cff32f6c730b1841a428a82e5dbebc2ec4ee2
--- /dev/null
+++ b/src/string.c
@@ -0,0 +1,17 @@
+#include "string.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+char* DupStr(const char* str) {
+	size_t len = strlen(str) + 1;
+	char* buf = malloc(len);
+	if (!buf) return NULL;
+	memcpy(buf, str, len);
+	return buf;
+}
+
+bool MatchWildcard(const char* pat, const char* text) {
+	// TODO
+	return false;
+}




diff --git a/src/string.h b/src/string.h
new file mode 100644
index 0000000000000000000000000000000000000000..247d9ac101a9b6ce2b606203bb2092317cef87a4
--- /dev/null
+++ b/src/string.h
@@ -0,0 +1,10 @@
+#ifndef FAB_STRING_H
+#define FAB_STRING_H
+
+#include <stdbool.h>
+
+char* DupStr(const char* str);
+
+bool MatchWildcard(const char* pat, const char* text);
+
+#endif




diff --git a/src/vlb.h b/src/vlb.h
new file mode 100644
index 0000000000000000000000000000000000000000..4229577581b09c200930b52e3f4551956e49a96e
--- /dev/null
+++ b/src/vlb.h
@@ -0,0 +1,81 @@
+#ifndef FAB_VLB_H
+#define FAB_VLB_H
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#define VLB(T) {\
+    T* data;\
+    size_t len;\
+    size_t size;\
+}
+
+#define VLB_OOM_NOP
+
+#define VLB__EXP(VLB__b, VLB__en, VLB__ed, VLB__do, ...) do {\
+    if ((VLB__b).len != (VLB__b).size) {\
+        VLB__do;\
+    } else {\
+        register size_t VLB__tmp = (VLB__b).size;\
+        VLB__tmp = VLB__tmp * (VLB__en) / (VLB__ed);\
+        if (VLB__tmp <= (VLB__b).size) VLB__tmp = (VLB__b).size + 1;\
+        void* VLB__ptr = realloc((VLB__b).data, VLB__tmp * sizeof(*(VLB__b).data));\
+        if (VLB__ptr) {(VLB__b).data = VLB__ptr; VLB__do; (VLB__b).size = VLB__tmp;}\
+        else {__VA_ARGS__}\
+    }\
+} while (0)
+#define VLB__EXP_MULTI(VLB__b, VLB__l, VLB__en, VLB__ed, ...) do {\
+    if ((VLB__l) > (VLB__b).size) {\
+        register size_t VLB__tmp = (VLB__b).size;\
+        do {\
+            register size_t VLB__old = VLB__tmp;\
+            VLB__tmp = VLB__tmp * (VLB__en) / (VLB__ed);\
+            if (VLB__tmp <= VLB__old) VLB__tmp = VLB__old + 1;\
+        } while (VLB__tmp < (VLB__l));\
+        void* VLB__ptr = realloc((VLB__b).data, VLB__tmp * sizeof(*(VLB__b).data));\
+        if (VLB__ptr) {(VLB__b).data = VLB__ptr; (VLB__b).len = (VLB__l); (VLB__b).size = VLB__tmp;}\
+        else {__VA_ARGS__}\
+    } else if ((VLB__l) > (VLB__b).len) {\
+        (VLB__b).len = (VLB__l);\
+    }\
+} while (0)
+
+#define VLB_INIT(VLB__b, VLB__sz, ...) do {\
+    (VLB__b).data = malloc((VLB__sz) * sizeof(*(VLB__b).data));\
+    if ((VLB__b).data || !(VLB__sz)) {\
+        (VLB__b).len = 0;\
+        (VLB__b).size = (VLB__sz);\
+    } else {\
+        __VA_ARGS__\
+    }\
+} while (0)
+#define VLB_ZINIT(VLB__b) do {\
+    (VLB__b).data = NULL;\
+    (VLB__b).len = 0;\
+    (VLB__b).size = 0;\
+} while (0)
+#define VLB_FREE(b) free((b).data)
+
+#define VLB_ADD(VLB__b, VLB__d, VLB__en, VLB__ed, ...) do {\
+    VLB__EXP((VLB__b), (VLB__en), (VLB__ed), (VLB__b).data[(VLB__b).len++] = (VLB__d), __VA_ARGS__);\
+} while (0)
+#define VLB_NEXTPTR(VLB__b, VLB__o, VLB__en, VLB__ed, ...) do {\
+    VLB__EXP((VLB__b), (VLB__en), (VLB__ed), (VLB__o) = &(VLB__b).data[(VLB__b).len++], __VA_ARGS__);\
+} while (0)
+
+#define VLB_EXPANDBY(VLB__b, VLB__a, VLB__en, VLB__ed, ...) do {\
+    register size_t VLB__l = (VLB__b).len + (VLB__a);\
+    VLB__EXP_MULTI((VLB__b), (VLB__l), (VLB__en), (VLB__ed), __VA_ARGS__);\
+} while (0)
+#define VLB_EXPANDTO(VLB__b, VLB__l, VLB__en, VLB__ed, ...) do {\
+    VLB__EXP_MULTI((VLB__b), (VLB__l), (VLB__en), (VLB__ed), __VA_ARGS__);\
+} while (0)
+#define VLB_SHRINK(VLB__b, ...) do {\
+    if ((VLB__b).len != (VLB__b).size) {\
+        void* VLB__ptr = realloc((VLB__b).data, (VLB__b).len * sizeof(*(VLB__b).data));\
+        if (VLB__ptr || !(VLB__b).len) {(VLB__b).data = VLB__ptr; (VLB__b).size = (VLB__b).len;}\
+        else {__VA_ARGS__}\
+    }\
+} while (0)
+
+#endif