diary

Text-based journaling program
git clone https://git.in0rdr.ch/diary.git
Log | Files | Refs | README | LICENSE

commit ea39be827a4e1bd01af650ab3b838fbbd83eeaee
parent 56b37e4a3bbfe675f8b32c31e8197583c25305f7
Author: Andreas Gruhler <agruhl@gmx.ch>
Date:   Wed, 11 Nov 2020 08:10:44 +0100

Merge pull request #52 from in0rdr/feature/cmdline-options

Add command line options
Diffstat:
Mdiary.1 | 13+++++++------
Mdiary.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mdiary.h | 2++
3 files changed, 90 insertions(+), 15 deletions(-)

diff --git a/diary.1 b/diary.1 @@ -4,12 +4,12 @@ diary \- Simple text-based diary program .SH SYNOPSIS .B diary -[\fIDIRECTORY\fR] +[\fIOPTION\fR]... [\fIDIRECTORY\fR]... .br .SH DESCRIPTION .B diary -is a simple text-based program for managing diary entries. +is a simple text-based program for managing journal entries. .SH ENVIRONMENT @@ -20,13 +20,14 @@ will use it to store diary files. Diary files are simple text files named after their date, formatted like YYYY-MM-DD. All other files are ignored. .IP EDITOR -The program used to edit diary entries. +The program used to edit journal entries. .SH ARGUMENTS If the argument \fIDIRECTORY\fR is given, diary files are read from and -stored to that directory, ignoring the DIARY_DIR environment variable. +stored to that directory, ignoring the DIARY_DIR environment variable or +any '-d' or '--dir' options. .SH NAVIGATION Navigation is done using the following vim-inspired keyboard shortcuts: @@ -47,8 +48,8 @@ e, enter | edit current entry d, x | delete current entry q | quit the program -N | go to the previous diary entry -n | go to the next diary entry +N | go to the previous journal entry +n | go to the next journal entry g | go to the first date G | go to the last date diff --git a/diary.c b/diary.c @@ -287,6 +287,34 @@ struct tm find_closest_entry(const struct tm current, return current; } +/* Set the diary storage directory. +* Copies the path to the storage directory from character +* string `path` to the destination location `diary_dir` +*/ +bool set_diary_dir(char* path, char* diary_dir) { + if (strlen(path) + 1 > sizeof diary_dir) { + fprintf(stderr, "Diary directory path too long\n"); + return false; + } + strcpy(diary_dir, path); + return true; +} + +void usage() { + printf("Usage : diary [OPTION]... [DIRECTORY]...\n"); + printf("\n"); + printf("Simple CLI diary (v%s)\n", DIARY_VERSION); + printf("Edit journal entries from the command line\n"); + printf("\n"); + printf("Options:\n"); + printf(" -v, --version : Print diary version\n"); + printf(" -h, --help : Show diary help text\n"); + printf(" -d, --dir DIARY_DIR : Diary storage directory (DIARY_DIR)\n"); + printf("\n"); + printf("Full docs and keyboard shortcuts: DIARY(1)\n"); + printf("or online via: <https://github.com/in0rdr/diary>\n"); +} + int main(int argc, char** argv) { setlocale(LC_ALL, ""); char diary_dir[80]; @@ -300,22 +328,66 @@ int main(int argc, char** argv) { // use the environment variable if available env_var = getenv("DIARY_DIR"); if (env_var == NULL) { - fprintf(stderr, "The diary directory must be given as command line " - "argument or in the DIARY_DIR environment variable\n"); + + fprintf(stderr, "The diary directory must be provided as (non-option) arg, `--dir` arg,\n" + "or in the DIARY_DIR environment variable, see `diary --help` or DIARY(1)\n"); return 1; } - if (strlen(env_var) + 1 > sizeof diary_dir) { - fprintf(stderr, "Diary directory path too long\n"); + // set diary directory from environment variable + if ( !set_diary_dir(env_var, diary_dir) ) { return 1; } - strcpy(diary_dir, env_var); } else { - if (strlen(argv[1]) + 1 > sizeof diary_dir) { - fprintf(stderr, "Diary directory path too long\n"); - return 1; + int option_char; + int option_index = 0; + + // define options, see GETOPT(3) + static const struct option long_options[] = { + { "version", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, + { "dir", required_argument, 0, 'd' }, + { 0, 0, 0, 0 } + }; + + // read option characters + while (1) { + option_char = getopt_long(argc, argv, "vhd:", long_options, &option_index); + + if (option_char == -1) { + break; + } + + switch (option_char) { + case 'v': + // show program version + printf("v%s\n", DIARY_VERSION); + return 0; + break; + case 'h': + // show help text + // printf("see man(1) diary\n"); + usage(); + return 0; + break; + case 'd': + // set diary directory from option character + if ( !set_diary_dir(optarg, diary_dir) ) { + return 1; + } + break; + default: + printf("?? getopt returned character code 0%o ??\n", option_char); + } + } + + if (optind < argc) { + // set diary directory from first non-option argv-element, + // required for backwarad compatibility with diary <= 0.4 + if ( !set_diary_dir(argv[optind], diary_dir) ) { + return 1; + } } - strcpy(diary_dir, argv[1]); } // check if that directory exists diff --git a/diary.h b/diary.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <stdlib.h> #include <unistd.h> +#include <getopt.h> #include <string.h> #include <time.h> #include <errno.h> @@ -16,6 +17,7 @@ #include <locale.h> #include <langinfo.h> +#define DIARY_VERSION "0.4" #define YEAR_RANGE 1 #define CAL_WIDTH 21 #define ASIDE_WIDTH 4