From d7d0f8f5d00aaaee8cf880047920b6ce74776982 Mon Sep 17 00:00:00 2001 From: katherine Date: Wed, 11 Dec 2019 13:31:15 -0700 Subject: implement edit command --- Makefile | 60 ------------------------------- configure | 89 +++++++++++++++++++++++++++++++++++++++++++++ src/calendar.c | 1 + src/calendar.h | 13 +++++++ src/main.c | 111 +++++++++++++++++++++++++++++++++++++++------------------ src/opt.c | 68 +++++++++++++++++++++++++---------- src/opt.h | 11 +++--- 7 files changed, 236 insertions(+), 117 deletions(-) delete mode 100644 Makefile create mode 100755 configure diff --git a/Makefile b/Makefile deleted file mode 100644 index 69ad4ef..0000000 --- a/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -.POSIX: -.SUFFIXES: - -CC = cc -CFLAGS = -Wall -O2 -CFLAGSDEBUG = -std=c99 -Wall -pedantic -ggdb3 -O0 -DDEBUG -PREFIX = /usr/local - -all: every - -debug: dbg_every - -install: all - mkdir -p $(DESTDIR)$(PREFIX)/bin - mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1 - cp -f every $(DESTDIR)$(PREFIX)/bin - gzip < every.1 > $(DESTDIR)$(PREFIX)/share/man/man1/every.1.gz - -every: build/release build/release/calendar.o build/release/opt.o build/release/main.o - $(CC) $(LDFLAGS) -o every build/release/calendar.o build/release/opt.o build/release/main.o $(LDLIBS) - -dbg_every: build/debug build/debug/calendar.o build/debug/opt.o build/debug/main.o - $(CC) $(LDFLAGS) -o dbg_every build/debug/calendar.o build/debug/opt.o build/debug/main.o $(LDLIBS) - -build/release: - mkdir -p build/release - -build/debug: - mkdir -p build/debug - -src/version.h: - printf "%s\n%s\n\n%s%s%s\n\n%s\n" \ - "#ifndef EVERY_VERSION_H" \ - "#define EVERY_VERSION_H" \ - "#define VERSION \"every-" "47b6e46" "\"" \ - "#endif" > src/version.h - -build/release/calendar.o: src/calendar.c - $(CC) -c $(CFLAGS) -o build/release/calendar.o src/calendar.c -build/release/opt.o: src/opt.c src/version.h src/opt.h \ - src/../reqs/simple-opt/simple-opt.h - $(CC) -c $(CFLAGS) -o build/release/opt.o src/opt.c -build/release/main.o: src/main.c src/opt.h \ - src/../reqs/simple-xdg-bdirs/simple-xdg-bdirs.h - $(CC) -c $(CFLAGS) -o build/release/main.o src/main.c - -build/debug/calendar.o: src/calendar.c - $(CC) -c $(CFLAGSDEBUG) -o build/debug/calendar.o src/calendar.c -build/debug/opt.o: src/opt.c src/version.h src/opt.h \ - src/../reqs/simple-opt/simple-opt.h - $(CC) -c $(CFLAGSDEBUG) -o build/debug/opt.o src/opt.c -build/debug/main.o: src/main.c src/opt.h \ - src/../reqs/simple-xdg-bdirs/simple-xdg-bdirs.h - $(CC) -c $(CFLAGSDEBUG) -o build/debug/main.o src/main.c - -clean: - rm -f src/version.h - rm -f every - rm -f dbg_every - rm -rf build diff --git a/configure b/configure new file mode 100755 index 0000000..6a73fa4 --- /dev/null +++ b/configure @@ -0,0 +1,89 @@ +#!/bin/sh + +# kinda brittle, this, but mostly works +# just don't use names with whitespaces + +target='every' +srcdir='src' +sources=`find $srcdir -type f -name '*.c' | sed -e "s/$srcdir\/\(.*\).c/\1.c/"` +objdir='build' +objects=`find $srcdir -type f -name '*.c' | sed -e "s/$srcdir\/\(.*\).c/\1.o/"` + +cc='cc' +cflags='-Wall -O2' +cflagsdebug='-std=c99 -Wall -pedantic -ggdb3 -O0 -DDEBUG' +prefix='/usr/local' + + + +rls_objects=`printf %s "$objects" | sed -e "s/^/$objdir\/release\//" | tr '\n' ' '` +dbg_objects=`printf %s "$objects" | sed -e "s/^/$objdir\/debug\//" | tr '\n' ' '` + +dgen='gcc' +if [ ! `2>/dev/null which gcc` ]; then + if [ ! `2>/dev/null which clang` ]; then + echo 'err: could not find a suitable ' \ + 'compiler for calculating dependencies' + return 1 + fi + dgen='clang' +fi + +if [ -f 'Makefile' ]; then + make clean +fi + +{ + printf %s\\n '.POSIX:' + printf %s\\n '.SUFFIXES:' + printf %s\\n '' + printf %s\\n "CC = $cc" + printf %s\\n "CFLAGS = $cflags" + printf %s\\n "CFLAGSDEBUG = $cflagsdebug" + printf %s\\n "PREFIX = $prefix" + printf %s\\n '' + printf %s\\n "all: $target" + printf %s\\n '' + printf %s\\n "debug: dbg_$target" + printf %s\\n '' + printf %s\\n "install: all" + printf %s\\n ' mkdir -p $(DESTDIR)$(PREFIX)/bin' + printf %s\\n ' mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1' + printf %s\\n " cp -f $target \$(DESTDIR)\$(PREFIX)/bin" + printf %s\\n " gzip < ${target}.1 > \$(DESTDIR)\$(PREFIX)/share/man/man1/${target}.1.gz" + printf %s\\n '' + printf %s\\n "$target: ${objdir}/release $rls_objects" + printf %s\\n " \$(CC) \$(LDFLAGS) -o $target $rls_objects \$(LDLIBS)" + printf %s\\n '' + printf %s\\n "dbg_$target: ${objdir}/debug $dbg_objects" + printf %s\\n " \$(CC) \$(LDFLAGS) -o dbg_$target $dbg_objects \$(LDLIBS)" + printf %s\\n '' + printf %s\\n "${objdir}/release:" + printf %s\\n " mkdir -p ${objdir}/release" + printf %s\\n '' + printf %s\\n "${objdir}/debug:" + printf %s\\n " mkdir -p ${objdir}/debug" + printf %s\\n '' + printf %s\\n 'src/version.h:' + printf %s\\n ' printf "%s\n%s\n\n%s%s%s\n\n%s\n" \' + printf %s\\n ' "#ifndef EVERY_VERSION_H" \' + printf %s\\n ' "#define EVERY_VERSION_H" \' + printf %s\\n " \"#define VERSION \\\"$target-\" \"`git describe --always --tags`\" \"\\\"\" \\" + printf %s\\n ' "#endif" > src/version.h' + printf %s\\n '' + printf %s\\n "$sources" | (while IFS= read -r s; do + $dgen $CFLAGS -MM -MG -MT ${objdir}/release/`printf %s $s | sed -e 's/\.c$/\.o/'` "$srcdir/$s" | sed -e "s/version.h/$srcdir\/version.h/" + printf %s\\n " \$(CC) -c \$(CFLAGS) -o ${objdir}/release/`printf %s $s | sed -e 's/\.c$/\.o/'` ${srcdir}/$s" + done) + printf %s\\n '' + printf %s\\n "$sources" | (while IFS= read -r s; do + $dgen $CFLAGS -MM -MG -MT ${objdir}/debug/`printf %s $s | sed -e 's/\.c$/\.o/'` "$srcdir/$s" | sed -e "s/version.h/$srcdir\/version.h/" + printf %s\\n " \$(CC) -c \$(CFLAGSDEBUG) -o ${objdir}/debug/`printf %s $s | sed -e 's/\.c$/\.o/'` ${srcdir}/$s" + done) + printf %s\\n '' + printf %s\\n 'clean:' + printf %s\\n ' rm -f src/version.h' + printf %s\\n " rm -f $target" + printf %s\\n " rm -f dbg_$target" + printf %s\\n " rm -rf $objdir" +} > Makefile diff --git a/src/calendar.c b/src/calendar.c index e69de29..46fd68c 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -0,0 +1 @@ +#include "calendar.h" diff --git a/src/calendar.h b/src/calendar.h index ebfe64a..ed54c4f 100644 --- a/src/calendar.h +++ b/src/calendar.h @@ -1,4 +1,17 @@ #ifndef EVERY_CALENDAR_H #define EVERY_CALENDAR_H +enum every_calendar_entry_type { + EVERY_CALENDAR_ENTRY_TYPE_ON, + EVERY_CALENDAR_ENTRY_TYPE_EVERY, +}; + +struct every_calendar_entry { + enum every_calendar_entry_type type; +}; + +struct every_calendar { + struct every_calendar_entry *entries; +}; + #endif diff --git a/src/main.c b/src/main.c index 625e860..86369d2 100644 --- a/src/main.c +++ b/src/main.c @@ -1,65 +1,108 @@ #include "opt.h" +#include "err.h" #include "../reqs/simple-xdg-bdirs/simple-xdg-bdirs.h" +#include + +#include +#include +#include + int main(int argc, char **argv) { - enum every_opt_outputmode omode; - FILE *calendar; + enum every_opt_command cmd; + + char *calpath; + FILE *cal; - char **rdirs, **cur, *s; + char *ed; + pid_t pid; + int wstatus; + + char **rdirs, **cur; + bool calpath_alloced = false; opt_parse(argc, argv); - omode = opt_outputmode(); + cmd = opt_command(); if (opt_calpath() != NULL) { - s = opt_calpath(); - - calendar = fopen(s, "r"); - if (calendar == NULL) { - printf("err: could not read calendar at `%s`\n", s); - exit(EXIT_FAILURE); - } + calpath = opt_calpath(); } else { rdirs = simple_xdg_bdirs_read_dirs(SIMPLE_XDG_BDIRS_CONFIG); - if (rdirs == NULL) { - printf( - "err: no calendar specified, and default was not found or " - "readable\n" - ); - exit(EXIT_FAILURE); - } + if (rdirs == NULL) + ERR("no calendar specified, and default was not found or readable"); - s = simple_xdg_bdirs_fullpath_read("every/calendar", rdirs); + calpath = simple_xdg_bdirs_fullpath_read("every/calendar", rdirs); for (cur = rdirs; *cur != NULL; cur++) free(*cur); free(rdirs); - if (s == NULL) { - printf( - "err: no calendar specified, and default was not found or " - "readable\n" - ); - exit(EXIT_FAILURE); + if (calpath == NULL) + ERR("no calendar specified, and default was not found or readable"); + } + + /* edit command */ + if (cmd == OPT_COMMAND_EDIT) { + ed = opt_editor(); + + if (ed == NULL) { + ERR("no editor specified, and $EDITOR was not found"); } - calendar = fopen(s, "r"); + pid = fork(); + + if (pid == 0) { + if (execlp(ed, ed, calpath, (char*)NULL) == -1) + exit(EXIT_FAILURE); + } else if (pid == -1) { + if (calpath_alloced) + free(calpath); - free(s); + ERR("editor failed to spawn"); + } else { + if (waitpid(pid, &wstatus, 0) == -1) { + if (calpath_alloced) + free(calpath); - if (calendar == NULL) { - printf( - "err: no calendar specified, and default was not found or " - "readable\n" - ); - exit(EXIT_FAILURE); + ERR("editor failed to spawn"); + } + + if (calpath_alloced) + free(calpath); + + if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) + ERR("editor failed to spawn or exited abnormally"); + + exit(EXIT_SUCCESS); } + + if (calpath_alloced) + free(calpath); + + exit(EXIT_SUCCESS); } - fclose(calendar); + /* output commands */ + cal = fopen(calpath, "r"); + if (cal == NULL) { + fprintf(stderr, "err: could not read calendar at `%s`\n", calpath); + + if (calpath_alloced) + free(calpath); + + exit(EXIT_FAILURE); + } + + if (calpath_alloced) + free(calpath); + + if (cmd == OPT_COMMAND_CONSOLE) + + fclose(cal); return 0; } diff --git a/src/opt.c b/src/opt.c index eb796e7..c051388 100644 --- a/src/opt.c +++ b/src/opt.c @@ -1,15 +1,12 @@ -#include "version.h" #include "opt.h" +#include "version.h" +#include "err.h" + #include "../reqs/simple-opt/simple-opt.h" #include - -const char *set[] = { - [EVERY_OPT_OUTPUTMODE_CONSOLE] = "console", - [EVERY_OPT_OUTPUTMODE_SCRIPT] = "script", - NULL, -}; +#include static struct simple_opt options[] = { { SIMPLE_OPT_FLAG, 'h', "help", false, @@ -18,16 +15,15 @@ static struct simple_opt options[] = { "print the version of every in use and exit" }, { SIMPLE_OPT_STRING, 'c', "calendar", true, "path to calendar", "" }, - { SIMPLE_OPT_STRING_SET, 'm', "output-mode", true, - "output mode (default is console)", - "(console|script)", set }, + { SIMPLE_OPT_STRING, 'e', "editor", true, + "text editor for editing calendars", "" }, { SIMPLE_OPT_END } }; +static struct simple_opt_result result; + void opt_parse(int argc, char **argv) { - struct simple_opt_result result; - result = simple_opt_parse(argc, argv, options); /* parse err */ @@ -51,11 +47,27 @@ void opt_parse(int argc, char **argv) exit(EXIT_SUCCESS); } - /* bad calendar path*/ - if (options[2].was_seen && options[2].val.v_string[0] == '\0') { - printf("err: could not read calendar at ``\n"); - exit(EXIT_FAILURE); + /* bad command */ + if (result.argc > 0) { + if (result.argc > 1) + ERR("too many commands"); + + if (strlen(result.argv[0]) > 1) + ERR("unrecognised command `%s`", result.argv[0]); + + switch (result.argv[0][0]) { + case 'c': + case 's': + case 'e': + break; + default: + ERR("unrecognised command `%s`", result.argv[0]); + } } + + /* bad calendar path */ + if (options[2].was_seen && options[2].val.v_string[0] == '\0') + ERR("err: could not read calendar at ``"); } char* opt_calpath(void) @@ -66,10 +78,28 @@ char* opt_calpath(void) return NULL; } -enum every_opt_outputmode opt_outputmode(void) +char* opt_editor(void) { if (options[3].was_seen) - return options[3].val.v_string_set_idx; + return options[3].val.v_string; + + return getenv("EDITOR"); +} + +enum every_opt_command opt_command(void) +{ + if (result.argc > 0) { + switch (result.argv[0][0]) { + case 'c': + return OPT_COMMAND_CONSOLE; + case 's': + return OPT_COMMAND_SCRIPT; + case 'e': + return OPT_COMMAND_EDIT; + default: + break; + } + } - return EVERY_OPT_OUTPUTMODE_CONSOLE; + return OPT_COMMAND_CONSOLE; } diff --git a/src/opt.h b/src/opt.h index f751232..4e8921a 100644 --- a/src/opt.h +++ b/src/opt.h @@ -1,14 +1,17 @@ #ifndef EVERY_OPT_H #define EVERY_OPT_H -enum every_opt_outputmode { - EVERY_OPT_OUTPUTMODE_CONSOLE = 0, - EVERY_OPT_OUTPUTMODE_SCRIPT = 1, +enum every_opt_command { + OPT_COMMAND_CONSOLE = 0, + OPT_COMMAND_SCRIPT = 1, + OPT_COMMAND_EDIT = 1, }; void opt_parse(int argc, char **argv); char* opt_calpath(void); -enum every_opt_outputmode opt_outputmode(void); +char* opt_editor(void); + +enum every_opt_command opt_command(void); #endif -- cgit v1.2.3