]> git.huck.website - odot.git/commitdiff
working database
authorHuck Boles <huck@huck.website>
Fri, 23 Dec 2022 21:09:56 +0000 (15:09 -0600)
committerHuck Boles <huck@huck.website>
Fri, 23 Dec 2022 21:09:56 +0000 (15:09 -0600)
.gitignore [new file with mode: 0644]
Makefile
database.c
odot.c
odot.h
sqlite3.o [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..583b95b
--- /dev/null
@@ -0,0 +1,9 @@
+*
+!.gitignore
+!LICENSE
+!README.md
+!Makefile
+!*.c
+!*.h
+!*.o
+sqlite3.c
index 0340115ac8f6ef705130368bc52ef448a3825a74..ec5faf19cb9e7679b1d1fc646bc59d979537f44b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,31 +4,36 @@ DESTDIR = $(PREFIX)/bin
 
 PROG = odot
 
+CC = gcc
 CFILE = $(PROG).c database.c
 HEADER = $(PROG).h sqlite3.h
 OBJECTS = $(PROG).o database.o task.o sqlite3.o
-CFLAGS = -Wall -lpthread
+LDFLAGS = -L .
+LDLIBS = -lpthread
+CFLAGS = -Wall -Wextra -O2
+CPPFLAGS = -I . 
+ALL_CFLAGS = $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS)
 
 sql: sqlite3.c
-       gcc sqlite3.c $(CFLAGS) -c
+       $(CC) sqlite3.c $(CFLAGS) -c
 
 header: $(HEADER)
-       gcc $(HEADER) $(CFLAGS) -c
+       $(CC) $(HEADER) $(CFLAGS) -c
 
 compile: $(CFILE)
-       gcc $(CFILE) $(CFLAGS) -c
+       $(CC) $(CFILE) $(CFLAGS) -c
 
 link: $(OBJECTS)
-       gcc $(OBJECTS) $(CFLAGS) -o $(PROG)
+       $(CC) $(OBJECTS) $(CFLAGS) -o $(PROG)
 
-build: $(CFILE) $(HEADER) sqlite3.c
-       gcc $(CFILE) $(HEADER) sqlite3.c $(CFLAGS) -o $(PROG)
+build: $(CFILE) $(HEADER) sqlite3.o
+       $(CC) $(CFILE) sqlite3.o $(CFLAGS) -o $(PROG)
 
-install: $(CFILE) $(HEADER) $(SQLFILE)
-       gcc $(CFILE) $(HEADER) $(SQLFILE) $(CFLAGS) -o $(DESTDIR)/$(PROG)
+install: $(CFILE) $(HEADER) sqlite3.o
+       $(CC) $(CFILE) sqlite3.o $(CFLAGS) -o $(DESTDIR)/$(PROG)
 
 debug: $(CFILE)
-       gcc $(CFILE) sqlite3.o $(CFLAGS) -g -o $(PROG)
+       $(CC) $(CFILE) sqlite3.o $(CFLAGS) -ggdb3 -Og -o $(PROG)
 
 clean: 
        rm *.gch *.o
index 3e94c78ff1cfca491cd609568b844cdcad2b9305..76ba218427a77ed2719a018b0b871af862fe04f4 100644 (file)
 #include "odot.h"
 
+extern char *group,
+            *task;
+
+
 sqlite3 *accessdb(char *file){
     sqlite3 *db;
 
     int err = sqlite3_open(file, &db);
-    if (err) {
-        fprintf(stderr, "Could not open database: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
+    if (err) sqlerror(db); 
 
     return db;
 }
 
-void buildtables(sqlite3 *db){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
-
-    sprintf(cmd,"CREATE TABLE IF NOT EXISTS Tasks (Task varchar(1000) NOT NULL PRIMARY KEY, Type varchar(100) NOT NULL, Done int NOT NULL DEFAULT 0);");
-    int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not create table: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
-
-    free(cmd);
-    return;
-}
-
-
-void addtask(sqlite3 *db, struct task task){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
-
-    sprintf(cmd,"INSERT INTO Tasks VALUES ( '%s', '%s', 0);",task.task,task.group);
-    int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not add task: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
-    
-    free(cmd);
+void sqlcmd(sqlite3 *db, char *cmd){
+    int err = sqlite3_exec(db,cmd,NULL,NULL,NULL);
+    if (err) sqlerror(db); 
     return;
-}
-
-void removetask(sqlite3 *db, struct task task){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
 
-    sprintf(cmd,"DELETE FROM Tasks WHERE Task = '%s';",task.task);
-    int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not remove task: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
-
-    free(cmd);
-    return;
 }
 
-void donetask(sqlite3 *db, struct task task){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
-
-    sprintf(cmd,"UPDATE Tasks SET Done = 1 WHERE Task = '%s';",task.task);
-    int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not modify task in db: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
-
-    free(cmd);
+void sqlprint(sqlite3 *db, char *cmd){
+    int err = sqlite3_exec(db,cmd,printcallback,0,NULL);
+    if (err) sqlerror(db); 
     return;
-}
 
-int printcallback(void *unused,int argc, char **argv, char **name){
-    printf("\t[%s] - ", (strcmp(argv[0],"1") == 0) ? "X" : " ");
-    for (int i = 1; i < argc; i++){
-        printf("%s\t",argv[i]);
-    }
-    printf("\n");
-    return 0;
 }
 
-void print(sqlite3 *db){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
-
-    sprintf(cmd,"SELECT Done, Type, Task FROM Tasks WHERE Done = 0 ORDER BY Type;");
-    printf("TODO:");
-    int err = sqlite3_exec(db,cmd,printcallback,0,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
-
-    free(cmd);
+void sqlgroup(sqlite3 *db, char *cmd){
+    int err = sqlite3_exec(db,cmd,groupcallback,0,NULL);
+    if (err) sqlerror(db); 
     return;
+
 }
 
-void printdone(sqlite3 *db){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
-
-    sprintf(cmd,"SELECT Done, Type, Task FROM Tasks ORDER BY Type;");
-    printf("TODO:");
-    int err = sqlite3_exec(db,cmd,printcallback,0,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
 
-    free(cmd);
-    return;
+void sqlerror(sqlite3 *db) {
+    fprintf(stderr, "%s\n", sqlite3_errmsg(db));
+    sqlite3_close(db);
+    error(1);
 }
 
-void printgroup(sqlite3 *db, struct task t){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
-
-    sprintf(cmd,"SELECT Done, Type, Task FROM Tasks WHERE (Type = '%s' AND Done = 0) OR Task = '%s' ORDER BY Type;",t.group,t.task);
-    printf("TODO:");
-    int err = sqlite3_exec(db,cmd,printcallback,0,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
+int printcallback(void *unused,int argc, char **argv, char **name){
+    int i = 1;
+
+    if (argv[2]){
+        char *g = malloc(strlen(argv[1])*sizeof(char));
+        sprintf(g,"%s",argv[1]);
+        if (strcmp(g,group) != 0) {
+            sprintf(group,"%s",argv[1]);
+            printf("\n\t\033[34m%s\033[0m\n",argv[1]);
+        }
+        i = 2;
     }
 
-    free(cmd);
-    return;
+    printf("\t\033[32m[\033[0m%s\033[32m]\033[0m - ", (strcmp(argv[0],"1") == 0) ? "\033[31;1mX\033[0m" : " ");
+    printf("%s\n",argv[i]);
+    return 0;
 }
 
-void printgroupdone(sqlite3 *db, struct task t){
-    char *cmd = malloc(MAXLINE * sizeof(char));
-    char **errmsg = 0;
-
-    sprintf(cmd,"SELECT Done, Type, Task FROM Tasks WHERE Type = '%s' OR Task = '%s' ORDER BY Type;",t.group, t.task);
-    printf("TODO:");
-    int err = sqlite3_exec(db,cmd,printcallback,0,errmsg);
-    if (err) {
-        fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db));
-        sqlite3_close(db);
-        exit(1);
-    }
-
-    free(cmd);
-    return;
+int groupcallback(void *unused,int argc, char **argv, char **name){
+    strcpy(group,argv[0]);
+    return 0;
 }
diff --git a/odot.c b/odot.c
index 67d47eb7aad15981a1d3cb7b5d7e863bddb23471..37a1397c4418af08a682053fe41ba6d9bb24004e 100644 (file)
--- a/odot.c
+++ b/odot.c
@@ -3,34 +3,26 @@
 /* global variables */ 
 int showdone = 0,
     showall  = 0;
+
 char    *group,
-        *task;
+        *task,
+        *action;
 
 int main(int argc, char *argv[]){
+    if (argc == 1) help();
+
     sqlite3 *db;
-    db = accessdb("odot.db");
-    buildtables(db);
+    db = accessdb(filepath());
+    sqlcmd(db,BUILDTABLE);
 
-    /* print all todo tasks if called alone */ 
-    if (argc == 1) {
-        print(db);
-        return 0;
-    }
 
     group = malloc(MAXLINE * sizeof(char));
     task = malloc(MAXLINE * sizeof(char));
+    action = malloc(MAXLINE * sizeof(char));
     
-    char *action = malloc(100*sizeof(char));
-    
-    strcpy(action,argv[1]);
     parseopt(argc,argv);
-    struct task t = maketask(task,group);
 
-    free(task);
-    free(group);
-
-
-    operate(action,t,db);
+    operate(db);
 
     sqlite3_close(db);
     return 0;
@@ -38,8 +30,11 @@ int main(int argc, char *argv[]){
 
 void parseopt(int n, char **args){
     char c;
-    while ((c = getopt(n,args,"g:ad")) != -1){
+    while ((c = getopt(n,args,"g:adh")) != -1){
         switch (c) {
+            case 'h':
+                help();
+                break;
             case 'a':
                 showall = 1;
                 break;
@@ -47,56 +42,114 @@ void parseopt(int n, char **args){
                 showdone = 1;
                 break;
             case 'g':
-                strcpy(group,optarg);
+                sprintf(group,"%s",optarg);
                 break;
             case '?':
                 printf("Unknown Option: %c\n", optopt);
         }
     }
 
-    if (strcmp(group, "") == 0) strcpy(group,"all");
+    sprintf(group,"%s",(strcmp(group,"") == 0) ? "" : group);
+    sprintf(action,"%s",args[optind]);
 
-    for (; optind < n; optind++){
-        if (optind > 1) {
-            strcat(task,args[optind]);
-            strcat(task,(optind != n -1) ? " " : "");
-        }  
+    for (int j = optind + 1; j < n; j++){
+            strcat(task,args[j]);
+            strcat(task,(j != n-1) ? " " : "");
     }
 }
 
-struct task maketask(char *task, char *group){
-    struct task tmp;
+void operate(sqlite3 *db){
+    char *cmd = malloc(MAXLINE*sizeof(char));
 
-    tmp.task = malloc(strlen(task)*sizeof(char));
-    strcpy(tmp.task,task);
-
-    tmp.group = malloc(strlen(group)*sizeof(char));
-    strcpy(tmp.group,group);
-
-    return tmp;
-}
-
-void operate(char *action, struct task t, sqlite3 *db){
     if (strcmp(action,"new") == 0){
-        addtask(db, t);
+        sprintf(cmd,"%s%s' ,'%s', 0);",INSERT,task,group);
+        sqlcmd(db,cmd);
     } else if (strcmp(action,"done") == 0){
-        donetask(db, t);
+        sprintf(cmd,"%s%s';",DONE,task);
+        sqlcmd(db,cmd);
+        sprintf(cmd,"%s%s';", GETGROUP,task);
+        sqlgroup(db,cmd);
+        sprintf(cmd,"SELECT Done, Task FROM Tasks WHERE Task = '%s'",task);
+        printf("\n");
+        sqlprint(db,cmd);
     } else if (strcmp(action,"remove") == 0){
-        removetask(db,t);
+        sprintf(cmd,"%s%s';",DELETE,task);
+        sqlcmd(db,cmd);
     } else if (strcmp(action,"show") != 0) {
-        printf("Unknown subcommand: %s\n",action);
+        fprintf(stderr,"\033[33;1mUnknown subcommand\033[0m: %s\n",action);
     }
+    printf("\n\t\033[35;1mTODO\033[0m: \033[36m%s\033[0m\n\n",group);
     if (showall == 1) {
         if (showdone == 1) {
-            printdone(db);
+            sqlprint(db,PRINTALL);
         } else {
-            print(db);
+            sqlprint(db,PRINT);
         }
     } else {
         if (showdone == 1) {
-            printgroupdone(db,t); 
+            sprintf(cmd,"%s%s' ORDER BY Done;",PRINTGROUPALL,group);
+            sqlprint(db,cmd);
+        } else if (strcmp(group,"\t") != 0) {
+            sprintf(cmd,"%s%s';",PRINTGROUP,group);
+            sqlprint(db,cmd);
         } else {
-            printgroup(db,t);
+            sqlprint(db,PRINT);
         }
     }
 }
+
+char *filepath(void){
+    char *dir = getenv("XDG_DATA_HOME");
+    char *db = malloc(MAXLINE * sizeof(char));
+
+    if (!dir) {
+        dir = getenv("HOME");    
+        if (!dir) error(3);
+        strcat(dir,"/.local/share");
+    }
+    strcat(dir,"/odot");
+
+    DIR *test = opendir(dir);
+
+    if (test) {
+        closedir(test);
+    } else {
+        int err = mkdir(dir, 0777);
+        if (err) error(2);
+    }
+
+    sprintf(db,"%s/odot.db",dir);
+
+    return db;
+}
+
+void error(int err){
+    switch (err) {
+        case 1:
+            fprintf(stderr,"^^ SQL error ^^\n");
+            break;
+        case 2:
+            fprintf(stderr,"Could not create odot directory\n\t$XDG_DATA_HOME/odot\n");
+            break;
+        case 3:
+            fprintf(stderr,"Could not determine $HOME\n");
+            break;
+    }
+    exit(err);
+}
+
+void help(){
+    printf("Usage: odot [subcommand] (task)\n");
+    printf("\tSubcommands:\n");
+    printf("\tnew\tadd new task to database\n");
+    printf("\tdone\tmark task as done in database\n");
+    printf("\tshow\tshow tasks in database\n");
+    printf("\tremove\tremove task from database\t\n");
+    printf("\tOptions:\n");
+    printf("\t-a\tshow all groups\n");
+    printf("\t-d\talso show completed tasks\n");
+    printf("\t-g\tset group for task\n");
+    printf("\t-h\tshow this help\n");
+
+    exit(0);
+}
diff --git a/odot.h b/odot.h
index 2123d265c1229464480d860eebc5e93aeea17bad..754a7830529a5e55ceef9a9acb16aa7d8e1068c0 100644 (file)
--- a/odot.h
+++ b/odot.h
@@ -4,29 +4,35 @@
 #include <unistd.h>
 #include <time.h>
 #include <math.h>
+#include <sys/stat.h>
+#include <dirent.h>
 
 #include "sqlite3.h"
 
 #define MAXLINE 10000
 
-struct task {
-    char        *task;
-    char        *group;
-};
+#define BUILDTABLE "CREATE TABLE IF NOT EXISTS Tasks (Task varchar(1000) NOT NULL PRIMARY KEY, Type varchar(8), Done int NOT NULL DEFAULT 0);"
 
+#define INSERT "INSERT INTO Tasks VALUES ( '"
+#define DELETE "DELETE FROM Tasks WHERE Task = '"
+#define DONE "UPDATE Tasks SET Done = 1 WHERE Task = '"
+#define GETGROUP "SELECT Type FROM Tasks WHERE Task = '"
+#define PRINT "SELECT Done, Type, Task FROM Tasks WHERE Done = 0 ORDER BY Type;"
+#define PRINTALL "SELECT Done, Type, Task FROM Tasks ORDER BY Type;"
+#define PRINTGROUP "SELECT Done, Task FROM Tasks WHERE Done = 0 AND Type = '"
+#define PRINTGROUPALL "SELECT Done, Task FROM Tasks WHERE Type = '"
 
+char *filepath(void);
+void error(int);
+void help(void);
 void parseopt(int, char**);
-void operate(char *, struct task, sqlite3 *);
-struct task maketask(char *, char *);
+void operate(sqlite3 *);
 
 /* functions for interfacing with database: database.c */
 sqlite3 *accessdb(char *);
-void buildtables(sqlite3 *);
-void addtask(sqlite3 *, struct task);
-void removetask(sqlite3 *, struct task);
-void donetask(sqlite3 *, struct task);
+void sqlcmd(sqlite3 *,char *);
+void sqlprint(sqlite3 *,char *);
+void sqlgroup(sqlite3 *,char *);
+void sqlerror(sqlite3 *);
 int printcallback(void *,int,char **,char **);
-void print(sqlite3 *);
-void printdone(sqlite3 *);
-void printgroup(sqlite3 *, struct task);
-void printgroupdone(sqlite3 *, struct task);
+int groupcallback(void *,int,char **,char **);
diff --git a/sqlite3.o b/sqlite3.o
new file mode 100644 (file)
index 0000000..fa25a93
Binary files /dev/null and b/sqlite3.o differ