summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAriadna Vigo <arivigodr@gmail.com>2020-07-21 14:29:47 +0200
committerAriadna Vigo <arivigodr@gmail.com>2020-07-24 18:59:14 +0200
commitf4b3177bbd0e9b46eb078f199d57fcf120c2f88e (patch)
treec3dd37437233eec5605d888db52dbea542bd5f09
parent8c50fbcab556ec7f254b8e7b10c28945ca84ef15 (diff)
New way to add tasks to an already existing task file.
-rw-r--r--README.md5
-rw-r--r--cras.116
-rw-r--r--cras.c55
-rw-r--r--tasklst.c25
-rw-r--r--tasklst.h1
5 files changed, 65 insertions, 37 deletions
diff --git a/README.md b/README.md
index 2d279c0..b62c23c 100644
--- a/README.md
+++ b/README.md
@@ -35,9 +35,10 @@ Tasks due for: Sat Jun 20 15:57:28 2020
3/0/3 to do/done/total
```
-To set a task list, pass the -s option and the name of the file that will hold
+To set a task list, pass the -n option and the name of the file that will hold
the list. The tasks will be read from standard input, each line being a new
-task. Cras stops reading when it reaches EOF.
+task. Cras stops reading when it reaches EOF. The same -n flag allows for
+adding new tasks if the file already exists.
The -t and -T, followed by the task number, mark the task as done or pending,
respectively.
diff --git a/cras.1 b/cras.1
index b866730..a12ca60 100644
--- a/cras.1
+++ b/cras.1
@@ -5,7 +5,7 @@ Cras - The Anti-Procrastination Tool
.SH SYNOPSIS
.PP
.B cras
-.RB [ \-osv ]
+.RB [ \-nov ]
.RB [ \-tT
.IR num ]
.I file
@@ -17,13 +17,14 @@ default) and doesn't allow you to edit the task list after set up, except for
marking a task as done.
.SH OPTIONS
.TP
+.B \-n
+Add new tasks to
+.I file,
+creating it if it doesn't exist.
+.TP
.B \-o
Switch to short-form output.
.TP
-.B \-s
-Save from standard input into
-.I file.
-.TP
.BI \-t " num"
Mark task
.I num
@@ -38,8 +39,9 @@ as pending.
Show version information and exit.
.SH USAGE
.PP
-To set up a new task list, call Cras using the -s option. Cras will read each
-new line from standard input as a new task, until EOF is reached.
+To set up a new task list, call Cras using the -n option. Cras will read each
+new line from standard input as a new task, until EOF is reached. Add new tasks
+to an already existing file using -n as well.
.PP
The newly created task list will be readable by Cras only up to the expiry
date, which under the default configuration is 24 hours after originally saving
diff --git a/cras.c b/cras.c
index 9a9a8ac..69b51aa 100644
--- a/cras.c
+++ b/cras.c
@@ -22,7 +22,7 @@ enum {
enum {
DEF_MODE,
- SET_MODE,
+ NEW_MODE,
OUT_MODE,
MARK_MODE
};
@@ -32,12 +32,12 @@ static void printf_color(const char *ansi_color, const char *fmt, ...);
static void print_task(TaskLst tasks, int i);
static void print_short_output(TaskLst tasks);
static void print_output(TaskLst tasks);
-static void read_crasfile(TaskLst *tasks, const char *crasfile);
+static int read_crasfile(TaskLst *tasks, const char *crasfile);
static void write_crasfile(const char *crasfile, TaskLst tasks);
-static void read_user_input(TaskLst *tasks, FILE *fp);
+static int store_input(TaskLst *tasks, FILE *fp);
static void usage(void);
-static void set_tasks_mode(const char *crasfile);
+static void new_mode(const char *crasfile);
static void output_mode(const char *crasfile, int mode);
static void mark_tasks_mode(const char *crasfile, const char *id, int value);
@@ -121,13 +121,17 @@ print_output(TaskLst tasks)
printf(" to do/done/total");
}
-static void
+static int
read_crasfile(TaskLst *tasks, const char *crasfile)
{
int read_stat;
FILE *fp;
- if ((fp = fopen(crasfile, "r")) == NULL)
+ fp = fopen(crasfile, "r");
+ if (errno == ENOENT)
+ return -1; /* We give the chance to create the file later. */
+
+ if (fp == NULL)
die("Could not read from %s: %s", crasfile, strerror(errno));
read_stat = tasklst_read_from_file(tasks, fp);
@@ -139,6 +143,8 @@ read_crasfile(TaskLst *tasks, const char *crasfile)
if (tasklst_expired(*tasks) > 0)
die("Due date passed (%d tasks overdue).",
tasklst_tasks_todo(*tasks));
+
+ return 0;
}
static void
@@ -153,8 +159,8 @@ write_crasfile(const char *crasfile, TaskLst tasks)
fclose(fp);
}
-static void
-read_user_input(TaskLst *tasks, FILE *fp)
+static int
+store_input(TaskLst *tasks, FILE *fp)
{
char linebuf[TASK_LST_DESC_MAX_SIZE];
int i;
@@ -162,29 +168,36 @@ read_user_input(TaskLst *tasks, FILE *fp)
for (i = 0; i < TASK_LST_MAX_NUM; ++i) {
fgets(linebuf, TASK_LST_DESC_MAX_SIZE, fp);
if (feof(fp) != 0)
- break;
-
- linebuf[strlen(linebuf) - 1] = '\0';
- strncpy(tasks->tdesc[i], linebuf, TASK_LST_DESC_MAX_SIZE);
- tasks->status[i] = TASK_TODO;
+ return 0;
+
+ linebuf[strlen(linebuf) - 1] = '\0'; /* Chomp '\n' */
+ if (tasklst_add_task(tasks, TASK_TODO, linebuf) < 0)
+ return -1;
}
+
+ return 0;
}
static void
usage(void)
{
- die("usage: cras [-osv] [-tT num] file");
+ die("usage: cras [-nov] [-tT num] file");
}
static void
-set_tasks_mode(const char *crasfile)
+new_mode(const char *crasfile)
{
+ int file_exists;
TaskLst tasks;
tasklst_init(&tasks);
- read_user_input(&tasks, stdin); /* Only stdin for now */
+ file_exists = read_crasfile(&tasks, crasfile);
+
+ if (store_input(&tasks, stdin) < 0)
+ fprintf(stderr, "Warning: Task file already full.\n");
- tasklst_set_expiration(&tasks, crasfile_expiry);
+ if (file_exists < 0) /* Only set if this is a new file */
+ tasklst_set_expiration(&tasks, crasfile_expiry);
write_crasfile(crasfile, tasks);
}
@@ -239,10 +252,10 @@ main(int argc, char *argv[])
mode = DEF_MODE;
ARGBEGIN {
- case 's':
+ case 'n':
if (mode != DEF_MODE)
usage();
- mode = SET_MODE;
+ mode = NEW_MODE;
break;
case 'o':
if (mode != DEF_MODE)
@@ -275,8 +288,8 @@ main(int argc, char *argv[])
usage();
switch (mode) {
- case SET_MODE:
- set_tasks_mode(argv[0]);
+ case NEW_MODE:
+ new_mode(argv[0]);
return 0;
case OUT_MODE:
output_mode(argv[0], SHORT_OUTPUT);
diff --git a/tasklst.c b/tasklst.c
index 51d26ef..09c6b6d 100644
--- a/tasklst.c
+++ b/tasklst.c
@@ -65,7 +65,23 @@ tasklst_tasks_done(TaskLst tasks)
{
return tasklst_tasks_status(tasks, TASK_DONE);
}
-
+
+int
+tasklst_add_task(TaskLst *tasks, int status, const char *str)
+{
+ int i;
+
+ for (i = 0; i < TASK_LST_MAX_NUM; ++i) {
+ if (tasks->status[i] == TASK_VOID) {
+ strncpy(tasks->tdesc[i], str, TASK_LST_DESC_MAX_SIZE);
+ tasks->status[i] = status;
+ return i;
+ }
+ }
+
+ return -1; /* We couldn't add any new task, because tasks is full */
+}
+
int
tasklst_read_from_file(TaskLst *tasks, FILE *fp)
{
@@ -88,16 +104,11 @@ tasklst_read_from_file(TaskLst *tasks, FILE *fp)
if (endptr[0] != '\0')
return -1;
- if (stat_buf == TASK_VOID)
- break;
- else
- tasks->status[i] = stat_buf;
-
ptr = strtok(NULL, "\n");
if (ptr == NULL)
return -1;
- strncpy(tasks->tdesc[i], ptr, TASK_LST_DESC_MAX_SIZE);
+ tasklst_add_task(tasks, stat_buf, ptr);
}
return 0;
diff --git a/tasklst.h b/tasklst.h
index c555413..c4be946 100644
--- a/tasklst.h
+++ b/tasklst.h
@@ -21,6 +21,7 @@ int tasklst_expired(TaskLst tasks);
int tasklst_tasks_total(TaskLst tasks);
int tasklst_tasks_todo(TaskLst tasks);
int tasklst_tasks_done(TaskLst tasks);
+int tasklst_add_task(TaskLst *tasks, int status, const char *str);
int tasklst_read_from_file(TaskLst *tasks, FILE *fp);
void tasklst_write_to_file(FILE *fp, TaskLst tasks);