Compare commits

..

No commits in common. "3bf6fea43dd1cf0bb4470298b848e0fe51a7b125" and "750d450b7500c7e6645259b3df67b8428757786d" have entirely different histories.

10 changed files with 136 additions and 180 deletions

View File

@ -49,5 +49,6 @@ This will run ctags on every commit.
#### TODO #### TODO
- improve and automate unit testing - real and automated unit testing
- fix stack smashing bug (test file: failed_cal.ics)
- add cli argument that will not show ongoing events, only upcoming events - add cli argument that will not show ongoing events, only upcoming events

42
src/Makefile Normal file
View File

@ -0,0 +1,42 @@
CC = gcc
CFLAGS = -Wall -g -O0
LDFLAGS = -luuid
# List of all source files (assuming they're all in the same directory)
SRC_FILES = $(wildcard *.c)
# Generate a list of object files by replacing the .c extension with .o
OBJ_FILES = $(SRC_FILES:.c=.o)
EXECUTABLE = "icscli"
# linking
$(EXECUTABLE): $(OBJ_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(EXECUTABLE) $(LDFLAGS)
main.o: main.c
$(CC) $(CFLAGS) -c $<
# use implicit rule to compile C source files to object files
%.o: %.c %.h
$(CC) $(CFLAGS) -c $<
.PHONY:install
install: $(EXECUTABLE)
cp $(EXECUTABLE) /usr/local/bin/$(EXECUTABLE)
.PHONY:clean
clean:
-rm -vf $(EXECUTABLE) *.o
.PHONY:uninstall
uninstall:
-rm /usr/local/bin/$(EXECUTABLE)
.PHONY:test
test:
./$(EXECUTABLE)
@echo
./$(EXECUTABLE) -h
@echo
../tests/run_tests.sh

View File

@ -5,7 +5,6 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <assert.h>
// buffer needs to contain a string with a strlen of 15 (format: "xxxxxxxxTxxxxxx") // buffer needs to contain a string with a strlen of 15 (format: "xxxxxxxxTxxxxxx")
// or a strlen of 16 (format: "YYYYmmddTHHMMSSZ") // or a strlen of 16 (format: "YYYYmmddTHHMMSSZ")
@ -16,61 +15,35 @@ void get_date (char buffer[]) {
struct tm* my_tm_local = localtime(&my_unix_ts); struct tm* my_tm_local = localtime(&my_unix_ts);
if (strlen(buffer) == 15) { if (strlen(buffer) == 15) {
strftime(buffer, buffer_size, "%Y%m%dT%H%M%S", my_tm_local); strftime(buffer, buffer_size, "%Y%m%dT%H%M%S", my_tm_local);
} } else if (strlen(buffer) == 16) {
else if (strlen (buffer) == 16) {
strftime(buffer, buffer_size, "%Y%m%dT%H%M%SZ", my_tm_local); strftime(buffer, buffer_size, "%Y%m%dT%H%M%SZ", my_tm_local);
} }
} }
// 20230823T194138 -> 2023-08-23 19:41:38 // 20230823T194138 -> 2023-08-23 19:41:38
// 20230823T194138Z -> 2023-08-23 19:41:38
// 20241209 -> 2024-12-09
// caller has to free() the returned char array
char* pretty_date_time (char date_time[]) {
// need one more char in the char pointer for null-termination
int pdt_len = 20;
if (!strchr (date_time, 'T')) {
pdt_len = 11;
}
char* pretty_dt = malloc (pdt_len);
memset(pretty_dt, '\0', pdt_len);
int dt_counter = 0;
if (!strcmp(date_time, "")) {
return pretty_dt;
}
for (int i = 0; i < (pdt_len-1); i++) {
if (i == 4 || i == 7) {
pretty_dt[i] = '-';
continue;
}
if (i == 13 || i == 16) {
pretty_dt[i] = ':';
continue;
}
if (date_time[dt_counter] == 'T') {
pretty_dt[i] = ' ';
} else {
pretty_dt[i] = date_time[dt_counter];
}
dt_counter++;
}
// null-terminate string
pretty_dt[strlen(pretty_dt)] = '\0';
return pretty_dt;
}
void pretty_print_date_time(char date_time[]) { void pretty_print_date_time(char date_time[]) {
char* pdt = pretty_date_time(date_time); // copy date_time because strtok will destroy it
char date_time_copy[15] = "";
strcpy(date_time_copy, date_time);
printf("%s", pdt); char *date = strtok(date_time, "T");
char *time = strtok(NULL, "T");
if (date == NULL) {
printf ("\nError: date points to NULL!\n");
exit(1);
}
printf ("%c%c%c%c-", date[0], date[1], date[2], date[3]);
printf ("%c%c-", date[4], date[5]);
printf ("%c%c", date[6], date[7]);
free(pdt); if (time != NULL) {
printf (" %c%c:", time[0], time[1]);
printf ("%c%c:", time[2], time[3]);
printf ("%c%c", time[4], time[5]);
}
// put variable date_time back together
strcpy(date_time, date_time_copy);
} }
void marshall_date_time(char date_time[]) { void marshall_date_time(char date_time[]) {
@ -81,8 +54,7 @@ void marshall_date_time (char date_time[]) {
if (date_time[i] != ':' && date_time[i] != '-') { if (date_time[i] != ':' && date_time[i] != '-') {
if (date_time[i] == ' ') { if (date_time[i] == ' ') {
transformed_string[j] = 'T'; transformed_string[j] = 'T';
} } else {
else {
transformed_string[j] = date_time[i]; transformed_string[j] = date_time[i];
} }
@ -103,18 +75,15 @@ void print_end_date (char end_date[], char start_date[]) {
if (strlen(end_date) == 8) { if (strlen(end_date) == 8) {
if (time_difference == 86400) { if (time_difference == 86400) {
return; return;
} } else {
else {
printf (" - "); printf (" - ");
end_uts -= 86400; end_uts -= 86400;
char* end_date_minus_one = char *end_date_minus_one = transform_unix_ts_to_date(end_uts);
transform_unix_ts_to_date (end_uts);
pretty_print_date_time(end_date_minus_one); pretty_print_date_time(end_date_minus_one);
free(end_date_minus_one); free(end_date_minus_one);
return; return;
} }
} } else {
else {
// end_date is not an all day event // end_date is not an all day event
char *end_date_chunk = strtok(end_date, "T"); char *end_date_chunk = strtok(end_date, "T");
@ -125,13 +94,10 @@ void print_end_date (char end_date[], char start_date[]) {
// only print the end date if it is not the same as the start date // only print the end date if it is not the same as the start date
if (strcmp(start_date_chunk, end_date_chunk) != 0) { if (strcmp(start_date_chunk, end_date_chunk) != 0) {
printf ("%c%c%c%c-", end_date_chunk[0], printf("%c%c%c%c-", end_date_chunk[0], end_date_chunk[1], \
end_date_chunk[1], end_date_chunk[2], end_date_chunk[2], end_date_chunk[3]);
end_date_chunk[3]); printf("%c%c-", end_date_chunk[4], end_date_chunk[5]);
printf ("%c%c-", end_date_chunk[4], printf("%c%c ", end_date_chunk[6], end_date_chunk[7]);
end_date_chunk[5]);
printf ("%c%c ", end_date_chunk[6],
end_date_chunk[7]);
} }
printf ("%c%c:", end_time_chunk[0], end_time_chunk[1]); printf ("%c%c:", end_time_chunk[0], end_time_chunk[1]);
@ -172,8 +138,7 @@ char* get_tz () {
if (bytes_read != -1) { if (bytes_read != -1) {
// Null-terminate the string // Null-terminate the string
timezone_path[bytes_read] = '\0'; timezone_path[bytes_read] = '\0';
} } else {
else {
perror("readlink"); perror("readlink");
exit(1); exit(1);
} }

View File

@ -5,7 +5,6 @@
void get_date(char buffer[]); void get_date(char buffer[]);
char *get_tz(); char *get_tz();
char* pretty_date_time(char date_time[]);
void pretty_print_date_time(char date_time[]); void pretty_print_date_time(char date_time[]);
void marshall_date_time(char date_time[]); void marshall_date_time(char date_time[]);
void print_end_date(char end_date[], char start_date[]); void print_end_date(char end_date[], char start_date[]);

View File

@ -1,5 +0,0 @@
project('ics_cli', 'c')
executable('icscli', 'main.c', 'cli_arg_parsing.c', 'date_time_handling.c', 'insert_event.c', \
'list_handling.c', 'parse_ics.c', 'read_until_nl.c', 'read_until_string.c', 'seek_string_a.c', \
'string_handling.c', link_args : '-luuid', install: true, install_dir: '/usr/local/bin')

16
unit-tests/Makefile Normal file
View File

@ -0,0 +1,16 @@
CC = gcc
CFLAGS = -Wall -g -O0
test_parse_ics_file:
$(CC) $(CFLAGS) test_parse_ics_file.c ../src/parse_ics.c ../src/string_handling.c ../src/list_handling.c ../src/date_time_handling.c ../src/read_until_string.c ../src/read_until_nl.c -o test_parse_ics_file.out
./test_parse_ics_file.out
test_print_upcoming:
$(CC) $(CFLAGS) test_print_upcoming.c ../src/parse_ics.c ../src/string_handling.c ../src/list_handling.c ../src/date_time_handling.c ../src/read_until_string.c ../src/read_until_nl.c -o test_print_upcoming.out
test_pretty_print_date_time:
$(CC) $(CFLAGS) test_pretty_print_date_time.c ../src/string_handling.c ../src/date_time_handling.c ../src/read_until_string.c ../src/read_until_nl.c -o test_pretty_print_date_time.out
.PHONY:clean
clean:
-rm -vf *.out

View File

@ -1,16 +0,0 @@
project('ics_cli', 'c')
t1e = executable('test_print_upcoming', 'test_print_upcoming.c', '../src/parse_ics.c', '../src/string_handling.c', \
'../src/list_handling.c', '../src/date_time_handling.c', '../src/read_until_string.c', '../src/read_until_nl.c')
test('test print_upcoming', t1e)
t2e = executable('test_pretty_print_date_time', 'test_pretty_print_date_time.c', '../src/string_handling.c', \
'../src/date_time_handling.c', '../src/read_until_string.c', '../src/read_until_nl.c')
test('test pretty_print_date_time', t2e)
t3e = executable('test_parse_ics_file', 'test_parse_ics_file.c', '../src/parse_ics.c', '../src/string_handling.c', '../src/list_handling.c', \
'../src/date_time_handling.c', '../src/read_until_string.c', '../src/read_until_nl.c')
test('test parse_ics_file', t3e)

View File

@ -6,9 +6,7 @@ int main() {
// initialize empty list // initialize empty list
struct event *head = NULL; struct event *head = NULL;
parse_ics_file("../../tests/calendar.ics", &head); parse_ics_file("../tests/calendar.ics", &head);
parse_ics_file("../../tests/failed_cal.ics", &head); print_list(head);
return 0;
} }

View File

@ -1,38 +1,7 @@
#include "../src/date_time_handling.h" #include "../src/date_time_handling.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main() { int main() {
// 1
char* pdt = pretty_date_time("20251215T080000Z");
assert(!strcmp(pdt, "2025-12-15 08:00:00"));
free(pdt);
// 2
char* pdt2 = pretty_date_time("20251215T080000");
assert(!strcmp(pdt2, "2025-12-15 08:00:00"));
free(pdt2);
// 3
char* pdt3 = pretty_date_time("");
assert(!strcmp(pdt3, ""));
free(pdt3);
// 4
char* pdt4 = pretty_date_time("20251215");
assert(!strcmp(pdt4, "2025-12-15"));
free(pdt4);
// 5
char current_date[] = "20240710T103000"; char current_date[] = "20240710T103000";
printf("current_date: %s\n", current_date); printf("current_date: %s\n", current_date);
@ -42,9 +11,4 @@ int main() {
printf("\n\ncurrent_date: %s\n", current_date); printf("\n\ncurrent_date: %s\n", current_date);
printf("strlen(current_date): %ld\n", strlen(current_date)); printf("strlen(current_date): %ld\n", strlen(current_date));
pretty_print_date_time("20251215T080000Z");
printf("\n");
return 0;
} }

View File

@ -6,19 +6,11 @@ int main() {
// initialize empty list // initialize empty list
struct event *head = NULL; struct event *head = NULL;
// 1
printf("\nTesting tests/failed_cal.ics:\n\n");
char *current_date = "20240710T113000"; char *current_date = "20240710T113000";
printf("DEBUG - current_date: %s\n\n", current_date); printf("DEBUG - current_date: %s\n\n", current_date);
parse_ics_file("../../tests/failed_cal.ics", &head); parse_ics_file("/home/bf/.local/share/evolution/calendar/system/calendar.ics", &head);
print_upcoming(head, current_date, 0);
// 2
printf("\nTesting tests/calendar.ics:\n\n");
parse_ics_file("../../tests/calendar.ics", &head);
print_upcoming(head, current_date, 0); print_upcoming(head, current_date, 0);
} }