diff options
| author | El-BG-1970 <elouan.gros.fr@gmail.com> | 2021-10-13 11:58:17 +0200 |
|---|---|---|
| committer | El-BG-1970 <elouan.gros.fr@gmail.com> | 2021-10-13 11:58:17 +0200 |
| commit | 8140d75aeb50e45aaa2d4ce34bfc84509fd2e91d (patch) | |
| tree | d8101114f28661364135f73ad72595c258b33d60 | |
| download | org-to-conky-8140d75aeb50e45aaa2d4ce34bfc84509fd2e91d.tar.gz | |
first commit
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | Makefile | 26 | ||||
| -rw-r--r-- | agenda_entry.c | 109 | ||||
| -rw-r--r-- | agenda_entry.h | 29 | ||||
| -rw-r--r-- | date.c | 77 | ||||
| -rw-r--r-- | date.h | 25 | ||||
| -rw-r--r-- | main.c | 122 |
7 files changed, 393 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d3622f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +otc +valgrind* +massif* +*.org diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fa24083 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +TARGET=otc + +CC=clang #--std=c99 +CXX=clang #--std=c++11 +CFLAGS=-Wall -Wextra -Werror -g +LIBS= +BLDFLAGS=-O2 -g + +DEPS=main.c agenda_entry.c date.c +HEAD=agenda_entry.h date.h +OBJ=${DEPS:.c=.o} + +.PHONY: all clean $(TARGET) + +all: $(TARGET) + +$(OBJ): $(HEAD) + +%.o: %.c + $(CC) -o $@ -c $< $(CFLAGS) + +$(TARGET): $(OBJ) + $(CC) -o $@ $(OBJ) $(LIBS) $(BLDFLAGS) + +clean: + rm -f *.o *~ *.core $(OBJ) $(TARGET) diff --git a/agenda_entry.c b/agenda_entry.c new file mode 100644 index 0000000..fa933c6 --- /dev/null +++ b/agenda_entry.c @@ -0,0 +1,109 @@ +#include "agenda_entry.h" + +char *next_word(char *str) { return strstr(str, " ")+1; } +char *next_line(char *str) { return strstr(str, "\n")+1; } +char *next_entry(char *str) { + char *tmp = strstr(str, "\n*"); + if (tmp) tmp += 1; + return tmp; } + +entry read_agenda_entry(char *agenda) { + entry agenda_entry; + char *cursor = agenda; + char *lookahead, *tmp; + char *nextentry = next_entry(cursor); + if (nextentry == NULL) + nextentry = agenda + strlen(agenda) - 1; + + while ((*cursor == '\n') || + (*cursor == '\t') || + (*cursor == ' ')) + cursor++; + while (*(cursor++) == '*'); // trim the * out + + //find out if there is a tag, and extract it + lookahead = strstr(cursor, ":\n"); + if (lookahead && (lookahead < nextentry)) { + tmp = strstr(cursor, ":"); + agenda_entry.tag = (char *)malloc(lookahead - tmp); + strncpy(agenda_entry.tag, tmp+1, lookahead - tmp - 1); + agenda_entry.tag[lookahead - tmp - 1] = '\0'; // here we're actually modifying lookahead-tmp cause the array is zero indexed + lookahead = tmp; + } else { + lookahead = strstr(cursor, "\n"); + agenda_entry.tag = NULL; + } + agenda_entry.title = (char *)malloc(lookahead - cursor + 1); + strncpy(agenda_entry.title, cursor, lookahead - cursor); + agenda_entry.title[lookahead - cursor] = '\0'; // here we're actually modifying lookahead-cursor cause the array is zero indexed + + //find out if there is a deadline and extract it + cursor = next_line(cursor); + if (((lookahead = strstr(cursor, "DEADLINE:")) && + (lookahead < nextentry)) || + ((lookahead = strstr(cursor, "SCHEDULED:")) && + (lookahead < nextentry))) { + //there is a deadline or event is scheduled + tmp = strstr(lookahead, ">"); + lookahead = strstr(lookahead, "<"); + char *date = (char *)malloc(tmp - lookahead + 1); + strncpy(date, lookahead+1, tmp - lookahead - 1); + agenda_entry.date = extract_date(date); + free(date); + } else { + agenda_entry.date = (Date){ 0, 0, 0 }; + } + + return agenda_entry; +} + +char *format_entry(entry e) { + char *ret = calloc(125, 1); + if (e.tag) + snprintf(ret, 124, " * %s \t:%s:", e.title, e.tag); + else + snprintf(ret, 124, " * %s", e.title); + return ret; +} + +void sort_entry_array(entry *arr, int n) { + if (n == 1) return; + + int halfway = n/2; + sort_entry_array(arr, halfway); + sort_entry_array(arr+halfway, n - halfway); + + int i = 0, + j = halfway; + entry *tmp; + entry sw; + while ((i < j) && (j < n)) { + if (smaller(arr[i].date, arr[j].date)) + i++; + else { + tmp = arr + j - 1; + while (tmp >= arr + i) { + sw = tmp[1]; + tmp[1] = tmp[0]; + tmp[0] = sw; + tmp--; + } + i++; + j++; + } + } +} + +void print_entry(entry e) { + char *tmp = print_date_to_string(e.date); + printf("%s\n%s\n>%s\n", + e.title, + e.tag, + tmp); + free(tmp); +} + +void destroy_entry(entry e) { + free(e.tag); + free(e.title); +} diff --git a/agenda_entry.h b/agenda_entry.h new file mode 100644 index 0000000..49a141b --- /dev/null +++ b/agenda_entry.h @@ -0,0 +1,29 @@ +#ifndef __AGENDA_ENTRY_H__ +#include <stdlib.h> +#include <string.h> +#include "date.h" + +typedef struct entry { + //struct entry *parent; + //struct entry *children; + //int8_t level;// nesting level of the entry + //char *todo; // TODO keyword + char *tag; // tag keyword + char *title; // the actual entry + //char *text; // description (if there is one) + Date date; // scheduled or deadline date +} entry; + +char *next_word(char *str); +char *next_line(char *str); +char *next_entry(char *str); + +entry read_agenda_entry(char *agenda); +char *format_entry(entry e); + +void sort_entry_array(entry *arr, int n); +void print_entry(entry e); +void destroy_entry(entry e); + +#define __AGENDA_ENTRY_H__ +#endif @@ -0,0 +1,77 @@ +#include "date.h" +#define _BSD_SOURCE + +enum month {JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC} month; + +Date extract_date(char *str) { + Date ret; + sscanf(str, "%d-%d-%d", + &ret.year, + &ret.month, + &ret.day); + return ret; +} + +bool smaller(Date a, Date b) { + if (zero(b)) return true; + if (zero(a)) return false; + return ((a.year < b.year) || + ((a.year == b.year) && (a.month < b.month)) || + ((a.year == b.year) && (a.month == b.month) && (a.day <= b.day))); +} + +bool eql(Date a, Date b) { + return (a.day == b.day) && + (a.month == b.month) && + (a.year == b.year); +} + +bool zero(Date a) { + return ((a.year == 0) || + (a.month == 0) || + (a.day == 0)); +} + +void print_date(Date date) { + printf("%i/%i/%i\n", date.month, date.day, date.year); +} + +char *print_date_to_string(Date date) { + char *ret = (char *)calloc(16, 1); + sprintf(ret, "%i/%i/%i", date.month, date.day, date.year); + return ret; +} + +Date today() { + FILE *pipe = popen("date \"+%Y-%m-%d\"", "r"); + char *td = (char *)malloc(12); + td = fgets(td, 12, pipe); + Date ret = extract_date(td); + + pclose(pipe); + free(td); + return ret; +} + +Date nextweek(Date td) { + Date nw = { td.day+7, td.month, td.year }; + if (nw.month == FEB && nw.day > 28) { + if (nw.year % 4 == 0 && nw.day > 29) { + nw.day -= 29; nw.month++; + } else { + nw.day -= 28; nw.month++; + } + } else if (nw.month == JAN || nw.month == MAR || nw.month == MAY || nw.month == JUL || + nw.month == AUG || nw.month == OCT || nw.month == DEC) { + if (nw.day > 31 && nw.month == DEC) { + nw.day -= 31; nw.month = 1; + } else if (nw.day > 31) { + nw.day -= 31; nw.month++; + } + } else if (nw.month == APR || nw.month == JUN || nw.month == SEP || nw.month == NOV) { + if (nw.day > 30) { + nw.day -= 30; nw.month++; + } + } + return nw; +} @@ -0,0 +1,25 @@ +#ifndef __DATE_H__ +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +typedef struct Date { + int day; + int month; + int year; +} Date; + +Date extract_date(char *str); +bool smaller(Date a, Date b); +bool eql(Date a, Date b); +bool zero(Date a); + +void print_date(Date date); +char *print_date_to_string(Date date); + +Date today(); +Date nextweek(Date td); + +#define __DATE_H__ +#endif @@ -0,0 +1,122 @@ +#include <stdio.h> +#include <unistd.h> +#include "agenda_entry.h" +#define BS 100 //blocksize for buffers + +void destroy_entry_array(entry *array, int elements) { + for (int i = 0; i < elements; i++) + destroy_entry(array[i]); + free(array); +} + +char *read_file_to_buffer(char *filename) { + FILE *fd = fopen(filename, "r"); + int bufsize = BS, + bufread = 0; + char *buf = (char *)malloc(bufsize); + char *newbuf; + + while (fread(buf + bufread, 1, 100, fd) == BS) { + newbuf = (char *)malloc(bufsize + BS); + strncpy(newbuf, buf, bufsize); + free(buf); + buf = newbuf; + bufsize += BS; + bufread += BS; + } + fclose(fd); + return buf; +} + +// this function does not work... to debug! +entry *read_entries_to_array(char *buffer, int *entries) { + int numentries = 5, + idx = 0; + entry *ret = (entry *)malloc(numentries * sizeof(entry)); + char *cursor = buffer; + while (cursor) { + if (idx == numentries) { + entry *newret = (entry *)malloc((numentries + 5) * sizeof(entry)); + memcpy(newret, ret, (idx)*sizeof(entry)); + free(ret); + ret = newret; + numentries += 5; + } + ret[idx++] = read_agenda_entry(cursor); + cursor = next_entry(cursor); + } + *entries = idx; + return ret; +} + +int main(int argc, char **argv) { + // unbuffering stdout in order to prevent leaks + // has the added benefit of reducing memory usage too + setvbuf(stdout, NULL, _IONBF, 0); + if (argc <= 1) { + printf("no agenda file supplied!\nUsage: otc <agendafile>\n"); + return -1; + } + + // read file into buf + char *buf = read_file_to_buffer(argv[1]); + if (strlen(buf) == 0) return -1; // don't do empty buffers + + // read entries into array + int idx = 0; + entry *agenda = read_entries_to_array(buf, &idx); + free(buf); + /*char *tmp = buf; + entry *agenda; + int numentries = 10, + idx = 0, + buflen = strlen(buf); + agenda = (entry *)malloc(numentries * sizeof(entry)); + while (buf) { + agenda[idx++] = read_agenda_entry(buf); + tmp = next_entry(buf); + if (tmp == NULL) buflen = 0; + else buflen -= (tmp - buf); + buf = tmp; + }*/ + + // sort entries + sort_entry_array(agenda, idx); + + // format nicely + char *e; + Date td = today(); + Date nw = nextweek(td); + Date last_date = agenda[0].date; + if (!zero(last_date)) { + e = print_date_to_string(last_date); + if (smaller(last_date, td)) + printf("\n%s [OUTATIME]:\n", e); + else if (smaller(last_date, nw)) + printf("\n%s:\n", e); + free(e); + } + for (int i = 0; i < idx; i++) { + if (!eql(agenda[i].date, last_date)) { + last_date = agenda[i].date; + if (!zero(last_date)) { + e = print_date_to_string(last_date); + if (smaller(last_date, td)) + printf("\n%s [OUTATIME]:\n", e); + else if (smaller(last_date, nw)) + printf("\n%s:\n", e); + free(e); + } else { + printf("\nUnscheduled:\n"); + } + } + e = format_entry(agenda[i]); + if (zero(agenda[i].date) || smaller(agenda[i].date, nw)) puts(e); + free(e); + } + + // free up the memory + fclose(stdout); + destroy_entry_array(agenda, idx); + return 0; +} |
