From 0aedfed01cec3fdae2a6dc7b30c9eed929867037 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 15 Sep 2020 11:15:56 -0400 Subject: [PATCH] initial commit with experimental build system --- .gitignore | 1 + README.md | 40 +++++++++ build.sh | 11 +++ inc/dial.h | 0 inc/ffind.h | 0 inc/gui.h | 0 inc/liba.h | 11 +++ inc/rc.h | 0 inc/stdc.h | 205 ++++++++++++++++++++++++++++++++++++++++++ inc/task.h | 0 inc/vte.h | 0 src/dial.c | 6 ++ src/edit.c | 6 ++ src/liba/ecalloc.c | 10 +++ src/liba/efopen.c | 11 +++ src/liba/efreadline.c | 26 ++++++ src/liba/emalloc.c | 10 +++ src/liba/eraise.c | 10 +++ src/liba/erealloc.c | 10 +++ src/liba/esignal.c | 10 +++ src/liba/estrdup.c | 9 ++ src/liba/fatal.c | 17 ++++ src/liba/smprintf.c | 15 ++++ src/liba/warn.c | 12 +++ src/listen.c | 6 ++ src/pick.c | 6 ++ src/screenlock.c | 6 ++ src/winmgr.c | 6 ++ tools/Binary | 5 ++ tools/Library | 11 +++ tools/Object | 4 + 31 files changed, 464 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 build.sh create mode 100644 inc/dial.h create mode 100644 inc/ffind.h create mode 100644 inc/gui.h create mode 100644 inc/liba.h create mode 100644 inc/rc.h create mode 100644 inc/stdc.h create mode 100644 inc/task.h create mode 100644 inc/vte.h create mode 100644 src/dial.c create mode 100644 src/edit.c create mode 100644 src/liba/ecalloc.c create mode 100644 src/liba/efopen.c create mode 100644 src/liba/efreadline.c create mode 100644 src/liba/emalloc.c create mode 100644 src/liba/eraise.c create mode 100644 src/liba/erealloc.c create mode 100644 src/liba/esignal.c create mode 100644 src/liba/estrdup.c create mode 100644 src/liba/fatal.c create mode 100644 src/liba/smprintf.c create mode 100644 src/liba/warn.c create mode 100644 src/listen.c create mode 100644 src/pick.c create mode 100644 src/screenlock.c create mode 100644 src/winmgr.c create mode 100755 tools/Binary create mode 100755 tools/Library create mode 100755 tools/Object diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..96740cd --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Libraries + +* argument parsing lib +* termbox/curses lib +* immediate-mode GUI lib +* dial lib for better networking +* data structure lib +* task management lib built around sockets and poll() +* editor library +* virtual terminal emulator library +* fuzzy find algorithm lib +* memory management lib +* utf8 library + +## Third-party Libs + +* Xlib/XCB +* Cairo +* Pango + +# Binaries + +## Graphical/Text User Interface + +* GUI editor +* terminal editor +* GUI fuzzy picker +* terminal fuzzy picker +* window manager +* display/login manager + +## Networking + +* listen +* dial + +## Command Line Utilities + +* Korn Shell +* New Shell \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..cc7a1aa --- /dev/null +++ b/build.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +export PATH="$PWD/tools:$PATH" + +# Build all of the libraries first +for lib in src/lib*/; do + Library "$lib" +done + +# Now build all of the binaries +parallel --halt now,fail=1 'Binary build/bin/{/.} {}' ::: src/*.c diff --git a/inc/dial.h b/inc/dial.h new file mode 100644 index 0000000..e69de29 diff --git a/inc/ffind.h b/inc/ffind.h new file mode 100644 index 0000000..e69de29 diff --git a/inc/gui.h b/inc/gui.h new file mode 100644 index 0000000..e69de29 diff --git a/inc/liba.h b/inc/liba.h new file mode 100644 index 0000000..8229f01 --- /dev/null +++ b/inc/liba.h @@ -0,0 +1,11 @@ +void fatal(const char* fmt, ...); +void warn(const char* fmt, ...); +void esignal(int sig, void (*func)(int)); +int eraise(int sig); +void* ecalloc(size_t num, size_t size); +void* emalloc(size_t size); +void* erealloc(void* ptr, size_t size); +char* smprintf(const char* fmt, ...); +FILE* efopen(const char* filename, const char* mode); +char* efreadline(FILE* input); +char* estrdup(const char *s); diff --git a/inc/rc.h b/inc/rc.h new file mode 100644 index 0000000..e69de29 diff --git a/inc/stdc.h b/inc/stdc.h new file mode 100644 index 0000000..aec368d --- /dev/null +++ b/inc/stdc.h @@ -0,0 +1,205 @@ +/* + Setup common ANSI C environment with common includes, functions, typedefs, + and macros. + + Copyright 2017, Michael D. Lowis + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA + OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. +*/ + +/* Standard Macros and Types */ +#include +#include +#include +#include +#include +#include + +/* Useful Standard Functions */ +#include +#include +#include +#include +#include + +/* Type and Variable Definitions + ******************************************************************************/ +typedef unsigned short ushort; +typedef unsigned char uchar; +typedef unsigned long ulong; +typedef unsigned int uint; +typedef signed char schar; +typedef long long vlong; +typedef unsigned long long uvlong; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; + +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; + +typedef uintptr_t uintptr; +typedef intptr_t intptr; + +/* This variable contains the value of argv[0] so that it can be referenced + * again once the option parsing is done. This variable must be defined by the + * program. + * + * NOTE: Ensure that you define this variable with external linkage (i.e. not + * static) */ +extern char* ARGV0; + +/* Option Parsing + ******************************************************************************* + * This following macros implement a simple POSIX-style option parsing strategy. + * They are heavily influenced and inspired by the arg.h file from suckless.org + * (http://git.suckless.org/libsl/tree/arg.h). That file is in turn inspired by + * the corresponding macros defined in plan9 libc.h. + * + * The interface assumes that the main function will have the following + * prototype: + * + * int main(int argc, char** argv); + * + * An example usage of the interface would look something like the follwoing: + * + * char* ARGV0; + * int main(int argc, char** argv) { + * OPTBEGIN { + * case 'a': printf("Simple option\n"); break; + * case 'b': printf("Option with arg: %s\n", OPTARG()); break; + * default: printf("Unknown option!\n"); + * } OPTEND; + * return 0; + * } + */ + +/* This is a helper function used by the following macros to parse the next + * option from the command line. */ +static inline char* _getopt_(int* p_argc, char*** p_argv) { + if (!(*p_argv)[0][1] && !(*p_argv)[1]) { + return (char*)0; + } else if ((*p_argv)[0][1]) { + return &(*p_argv)[0][1]; + } else { + *p_argv = *p_argv + 1; + *p_argc = *p_argc - 1; + return (*p_argv)[0]; + } +} + +/* This macro is almost identical to the ARGBEGIN macro from suckless.org. If + * it ain't broke, don't fix it. */ +#define OPTBEGIN \ + for ( \ + ARGV0 = *argv, argc--, argv++; \ + argv[0] && argv[0][1] && argv[0][0] == '-'; \ + argc--, argv++ \ + ) { \ + int brk_; char argc_ , **argv_, *optarg_; \ + if (argv[0][1] == '-' && !argv[0][2]) { \ + argv++, argc--; break; \ + } \ + for (brk_=0, argv[0]++, argv_=argv; argv[0][0] && !brk_; argv[0]++) { \ + if (argv_ != argv) break; \ + argc_ = argv[0][0]; \ + switch (argc_) + +/* Terminate the option parsing. */ +#define OPTEND }} + +/* Get the current option character */ +#define OPTC() (argc_) + +/* Get an argument from the command line and return it as a string. If no + * argument is available, this macro returns NULL */ +#define OPTARG() \ + (optarg_ = _getopt_(&argc,&argv), brk_ = (optarg_!=0), optarg_) + +/* Get an argument from the command line and return it as a string. If no + * argument is available, this macro executes the provided code. If that code + * returns, then abort is called. */ +#define EOPTARG(code) \ + (optarg_ = _getopt_(&argc,&argv), \ + (!optarg_ ? ((code), abort(), (char*)0) : (brk_ = 1, optarg_))) + +/* Helper macro to recognize number options */ +#define OPTNUM \ + case '0': \ + case '1': \ + case '2': \ + case '3': \ + case '4': \ + case '5': \ + case '6': \ + case '7': \ + case '8': \ + case '9' + +/* Helper macro to recognize "long" options ala GNU style. */ +#define OPTLONG \ + case '-' + +/* Error Handling Macros + ******************************************************************************/ +#ifdef NDEBUG + #define debug(msg, ...) \ + ((void)0) +#else + #define debug(msg, ...) \ + fprintf(stderr, "DEBUG %s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__) +#endif + +#define errnostr() \ + (errno == 0 ? "None" : strerror(errno)) + +#define print_error(msg, ...) \ + fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " msg "\n", __FILE__, __LINE__, errnostr(), ##__VA_ARGS__) + +#define check(expr, msg, ...) \ + if(!(expr)) { print_error(msg, ##__VA_ARGS__); errno=0; goto error; } + +#define sentinel(msg, ...) \ + { print_error(msg, ##__VA_ARGS__); errno=0; goto error; } + +/* Miscellaneous Macros + ******************************************************************************/ +#ifndef nelem + #define nelem(x) \ + (sizeof(x)/sizeof((x)[0])) +#endif + +#ifndef container_of + #define container_of(obj, type, member) \ + (type*)((uintptr_t)obj - offsetof(type, member)) +#endif + +#define concat(a,b) \ + a##b + +#define ident(a) \ + concat(id, a) + +#define unique_id \ + ident(__LINE__) + +#ifndef static_assert + #define static_assert(expr) \ + typedef char unique_id[( expr )?1:-1] +#endif diff --git a/inc/task.h b/inc/task.h new file mode 100644 index 0000000..e69de29 diff --git a/inc/vte.h b/inc/vte.h new file mode 100644 index 0000000..e69de29 diff --git a/src/dial.c b/src/dial.c new file mode 100644 index 0000000..cbfdb1c --- /dev/null +++ b/src/dial.c @@ -0,0 +1,6 @@ +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + return 0; +} \ No newline at end of file diff --git a/src/edit.c b/src/edit.c new file mode 100644 index 0000000..cbfdb1c --- /dev/null +++ b/src/edit.c @@ -0,0 +1,6 @@ +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + return 0; +} \ No newline at end of file diff --git a/src/liba/ecalloc.c b/src/liba/ecalloc.c new file mode 100644 index 0000000..af75b3a --- /dev/null +++ b/src/liba/ecalloc.c @@ -0,0 +1,10 @@ +#include +#include + +void* ecalloc(size_t num, size_t size) +{ + void* ret; + if (NULL == (ret = calloc(num,size))) + fatal("calloc(%zu, %zu) failed:", num, size); + return ret; +} diff --git a/src/liba/efopen.c b/src/liba/efopen.c new file mode 100644 index 0000000..1d6e01e --- /dev/null +++ b/src/liba/efopen.c @@ -0,0 +1,11 @@ +#include +#include + +FILE* efopen(const char* filename, const char* mode) +{ + FILE* file; + errno = 0; + if (NULL == (file = fopen(filename, mode)) || errno != 0) + fatal("fopen(%s, %s) failed:", filename, mode); + return file; +} diff --git a/src/liba/efreadline.c b/src/liba/efreadline.c new file mode 100644 index 0000000..0fc3a9f --- /dev/null +++ b/src/liba/efreadline.c @@ -0,0 +1,26 @@ +#include +#include + +char* efreadline(FILE* input) +{ + size_t size = 8; + size_t index = 0; + char* str = (char*)emalloc(size); + memset(str, 0, 8); + if (feof(input)) { + free(str); + return NULL; + } + while (true) { + char ch = fgetc(input); + if (ch == EOF) break; + str[index++] = ch; + str[index] = '\0'; + if (index+1 >= size) { + size = size << 1; + str = erealloc(str, size); + } + if (ch == '\n') break; + } + return str; +} diff --git a/src/liba/emalloc.c b/src/liba/emalloc.c new file mode 100644 index 0000000..c4e61e2 --- /dev/null +++ b/src/liba/emalloc.c @@ -0,0 +1,10 @@ +#include +#include + +void* emalloc(size_t size) +{ + void* ret; + if (NULL == (ret = malloc(size))) + fatal("malloc(%zu) failed:", size); + return ret; +} diff --git a/src/liba/eraise.c b/src/liba/eraise.c new file mode 100644 index 0000000..25c53da --- /dev/null +++ b/src/liba/eraise.c @@ -0,0 +1,10 @@ +#include +#include + +int eraise(int sig) +{ + int ret; + if ((ret = raise(sig)) != 0) + fatal("raise(%d) failed:", sig); + return ret; +} diff --git a/src/liba/erealloc.c b/src/liba/erealloc.c new file mode 100644 index 0000000..929ac01 --- /dev/null +++ b/src/liba/erealloc.c @@ -0,0 +1,10 @@ +#include +#include + +void* erealloc(void* ptr, size_t size) +{ + void* ret; + if (NULL == (ret = realloc(ptr,size))) + fatal("realloc(%p, %zu) failed:", ptr, size); + return ret; +} diff --git a/src/liba/esignal.c b/src/liba/esignal.c new file mode 100644 index 0000000..23f6a20 --- /dev/null +++ b/src/liba/esignal.c @@ -0,0 +1,10 @@ +#include +#include + +void esignal(int sig, void (*func)(int)) +{ + errno = 0; + func = signal(sig, func); + if (func == SIG_ERR || errno > 0) + fatal("signal(%d, %p) failed:", sig, func); +} diff --git a/src/liba/estrdup.c b/src/liba/estrdup.c new file mode 100644 index 0000000..24a5af5 --- /dev/null +++ b/src/liba/estrdup.c @@ -0,0 +1,9 @@ +#include +#include + +char* estrdup(const char *s) +{ + char* ns = (char*)emalloc(strlen(s) + 1); + strcpy(ns,s); + return ns; +} diff --git a/src/liba/fatal.c b/src/liba/fatal.c new file mode 100644 index 0000000..539a90d --- /dev/null +++ b/src/liba/fatal.c @@ -0,0 +1,17 @@ +#include +#include + +void fatal(const char* fmt, ...) +{ + fflush(stdout); + if (ARGV0) fprintf(stderr, "%s: ", ARGV0); + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + if (*fmt && fmt[strlen(fmt)-1] == ':') + fprintf(stderr, " %s", strerror(errno)); + fprintf(stderr, "\n"); + exit(EXIT_FAILURE); +} + diff --git a/src/liba/smprintf.c b/src/liba/smprintf.c new file mode 100644 index 0000000..e6ef302 --- /dev/null +++ b/src/liba/smprintf.c @@ -0,0 +1,15 @@ +#include +#include + +char* smprintf(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + int strsz = vsnprintf(NULL, 0, fmt, args); + va_end(args); + char* str = emalloc(strsz+1); + va_start(args, fmt); + vsnprintf(str, strsz+1, fmt, args); + va_end(args); + return str; +} diff --git a/src/liba/warn.c b/src/liba/warn.c new file mode 100644 index 0000000..5e82a4b --- /dev/null +++ b/src/liba/warn.c @@ -0,0 +1,12 @@ +#include +#include + +void warn(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + fprintf(stderr, "warning: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); +} diff --git a/src/listen.c b/src/listen.c new file mode 100644 index 0000000..cbfdb1c --- /dev/null +++ b/src/listen.c @@ -0,0 +1,6 @@ +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + return 0; +} \ No newline at end of file diff --git a/src/pick.c b/src/pick.c new file mode 100644 index 0000000..cbfdb1c --- /dev/null +++ b/src/pick.c @@ -0,0 +1,6 @@ +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + return 0; +} \ No newline at end of file diff --git a/src/screenlock.c b/src/screenlock.c new file mode 100644 index 0000000..cbfdb1c --- /dev/null +++ b/src/screenlock.c @@ -0,0 +1,6 @@ +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + return 0; +} \ No newline at end of file diff --git a/src/winmgr.c b/src/winmgr.c new file mode 100644 index 0000000..cbfdb1c --- /dev/null +++ b/src/winmgr.c @@ -0,0 +1,6 @@ +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + return 0; +} \ No newline at end of file diff --git a/tools/Binary b/tools/Binary new file mode 100755 index 0000000..74863a3 --- /dev/null +++ b/tools/Binary @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "Binary $1" +mkdir -p build/bin +cc -Iinc/ --std=c99 -Wall -Wextra -Werror -o "$@" \ No newline at end of file diff --git a/tools/Library b/tools/Library new file mode 100755 index 0000000..2aca2b0 --- /dev/null +++ b/tools/Library @@ -0,0 +1,11 @@ +#!/bin/sh + +srcdir="${1:?No library directory specified}" +srcdir="${srcdir%/}" +lib="${srcdir##*/}" +mkdir -p "build/obj/$lib" +parallel --halt now,fail=1 "Object build/obj/$lib/{/.}.o {}" ::: $srcdir/*.c +mkdir -p "build/lib" + +echo Library "build/lib/$lib.a" +ar rcs "build/lib/$lib.a" "build/obj/$lib"/*.o \ No newline at end of file diff --git a/tools/Object b/tools/Object new file mode 100755 index 0000000..95c0580 --- /dev/null +++ b/tools/Object @@ -0,0 +1,4 @@ +#!/bin/sh + +echo "Object $1" +cc -Iinc/ --std=c99 -Wall -Wextra -Werror -c -o "$@" \ No newline at end of file -- 2.54.0