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:
M | diary.1 | | | 13 | +++++++------ |
M | diary.c | | | 90 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
M | diary.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