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:
| M | main.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);