diary

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

commit 5745f5b200e8d1c879435cc0d14c0d8f0742fe3b
parent e9ff47ac454ef93f91fcf6baafd573b8a20d2124
Author: Andreas Gruhler <agruhl@gmx.ch>
Date:   Sat,  7 Nov 2020 14:37:24 +0100

add command line options

This adds command line options, among others, the help and version
options to display expected information on the version and usage of the
currently installed program.

The options could be extended to receive EDITOR and CONFIG_FILE at a
later point in time.

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