task

creates a plain-text task file in the current directory
git clone git://brookjeynes.dev/bjeynes/task.git
Log | Files | Refs | README | LICENSE

commit ae9352218f2d7d9ed2b9dc59be4096957c087577
parent b60c0f6cbf8446b2c3d1710adb3fce8caa53ef6b
Author: brookjeynes <me@brookjeynes.dev>
Date:   Mon, 15 Jun 2026 09:10:44 +1000

feat: add --contexts and --projects flags

Signed-off-by: brookjeynes <me@brookjeynes.dev>

Diffstat:
Mmain.c | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+), 0 deletions(-)

diff --git a/main.c b/main.c @@ -1,3 +1,6 @@ +#define _DEFAULT_SOURCE + +#include <dirent.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -17,6 +20,156 @@ static void print_help(const char *program) { printf("options:\n"); printf(" -h, --help show this help\n"); printf(" -p, --priority A set priority A-Z\n"); + printf(" --context list all known contexts\n"); + printf(" --projects list all known projects\n"); +} + +int has_txt_extension(const char *name) { + size_t len = strlen(name); + return len >= 4 && strcmp(name + len - 4, ".txt") == 0; +} + +static void print_properties(char identifier) { + struct dirent *dp; + FILE *fd = NULL; + int rc = 1; + + char *properties[1024]; + size_t properties_len = 0; + + DIR *dirp = opendir("."); + if (dirp == NULL) { + fprintf(stderr, "err: failed to open directory: %s\n", strerror(errno)); + goto cleanup; + } + + for (;;) { + errno = 0; + dp = readdir(dirp); + if (dp == NULL) { + if (errno == 0) { + break; + } + fprintf(stderr, "err: failed to iterate directory: %s\n", + strerror(errno)); + goto cleanup; + } + + if (dp->d_type != DT_REG) { + continue; + } + + if (has_txt_extension(dp->d_name) == 0) { + continue; + } + + fd = fopen(dp->d_name, "r"); + if (fd == NULL) { + fprintf(stderr, "err: failed to open file: %s\n", strerror(errno)); + goto cleanup; + } + + char line[1024]; + if (fgets(line, sizeof line, fd) == NULL) { + if (ferror(fd)) { + fprintf(stderr, "err: failed to read file: %s\n", strerror(errno)); + goto cleanup; + } + + // empty file + if (fclose(fd) != 0) { + fprintf(stderr, "err: failed to close file: %s\n", strerror(errno)); + goto cleanup; + } + + fd = NULL; + continue; + } + + size_t byte = 0; + while (line[byte] != '\0') { + char c = line[byte]; + + if (c == identifier) { + char property[1024]; + size_t property_len = 0; + + while (line[byte] != ' ' && line[byte] != '\n' && line[byte] != '\0' && + property_len < sizeof(property) - 1) { + property[property_len] = line[byte]; + property_len++; + byte++; + } + property[property_len] = '\0'; + property_len++; + + char *property_ptr = malloc(sizeof(char) * property_len); + if (property_ptr == NULL) { + fprintf(stderr, "err: failed to alloc space for read property: %s\n", + strerror(errno)); + goto cleanup; + } + + if (property_len < sizeof(property)) { + memcpy(property_ptr, property, property_len); + } + + if (properties_len == sizeof(properties) / sizeof(properties[0])) { + fprintf(stderr, "err: too many properties\n"); + free(property_ptr); + goto cleanup; + } + + properties[properties_len] = property_ptr; + properties_len++; + } else { + byte++; + } + } + + if (fclose(fd) != 0) { + fd = NULL; + fprintf(stderr, "err: failed to close file: %s\n", strerror(errno)); + goto cleanup; + } + fd = NULL; + } + + rc = 0; + + for (size_t i = 0; i < properties_len; i++) { + int is_duplicate = 0; + for (size_t j = i; j > 0; j--) { + if (strcmp(properties[i], properties[j - 1]) == 0) { + is_duplicate = 1; + break; + } + } + + if (is_duplicate == 1) { + continue; + } + + printf("%s\n", properties[i]); + } + +cleanup: + if (fd != NULL) { + fclose(fd); + } + + for (size_t i = 0; i < properties_len; i++) { + free(properties[i]); + } + + if (dirp != NULL && closedir(dirp) != 0 && rc == 0) { + fprintf(stderr, "err: failed to close directory: %s\n", strerror(errno)); + rc = 1; + } + + if (rc != 0) { + exit(1); + } } int main(int argc, char *argv[]) { @@ -29,6 +182,16 @@ int main(int argc, char *argv[]) { return 0; } + if (argc > 1 && (strcmp(argv[1], "--contexts") == 0)) { + print_properties('@'); + return 0; + } + + if (argc > 1 && (strcmp(argv[1], "--projects") == 0)) { + print_properties('+'); + return 0; + } + if (argc == 1) { fprintf(stderr, "err: title required\n"); exit(1);