From d7d0f8f5d00aaaee8cf880047920b6ce74776982 Mon Sep 17 00:00:00 2001 From: katherine Date: Wed, 11 Dec 2019 13:31:15 -0700 Subject: implement edit command --- src/calendar.c | 1 + src/calendar.h | 13 +++++++ src/main.c | 111 +++++++++++++++++++++++++++++++++++++++------------------ src/opt.c | 68 +++++++++++++++++++++++++---------- src/opt.h | 11 +++--- 5 files changed, 147 insertions(+), 57 deletions(-) (limited to 'src') 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