Changed all the sscanf calls to use the %n directive. By comparing the
[ctodo.git] / add.c
blob6f4bd335ced375f7d4dec8e5c389978d6f655f4d
1 #include <add.h>
2 #include <stdio.h>
3 #include <readline/readline.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <time.h>
8 void add_help() {
9 printf(" Usage: add [PARENT]\n");
10 printf(" Adds a new task.\n");
11 printf(" If you specify a PARENT, the new task will be a subtask of PARENT.\n");
14 char *escape(char *string) {
15 int length = strlen(string);
16 char *escaped = malloc((length+1)*sizeof(char));
17 int i, j;
19 for (i = 0, j = 0; string[i] != '\0'; i++, j++) {
20 if (string[i] == '\'') {
21 length++;
22 escaped = realloc(escaped, (length+1)*sizeof(char));
23 escaped[j] = '\'';
24 j++;
26 escaped[j] = string[i];
29 escaped[j] = '\0';
31 return escaped;
34 int add(sqlite3 *db, MArray tokens) {
35 int parent = -1;
36 int valid_parent;
37 int parsed;
38 char *description;
39 char *escapedDescription;
40 char *query;
41 char *errmsg;
42 sqlite3_stmt *statement;
44 if (tokens->len == 2 && !strcmp(myarray_get(tokens, char *, 1), "help")) {
45 add_help();
46 return 0;
47 } else if (tokens->len == 2) {
48 if (sscanf(myarray_get(tokens, char *, 1), "%d%n", &parent, &parsed) < 1 || parsed != strlen(myarray_get(tokens, char *, 1)) || parent < 0) {
49 printf("Invalid argument. PARENT must be a positive integer.\n");
50 add_help();
51 return 0;
54 query = sqlite3_mprintf("SELECT COUNT(key) FROM todo WHERE key = %d;", parent);
55 if (sqlite3_prepare_v2(db, query, -1, &statement, NULL) != SQLITE_OK) {
56 printf("Couldn't prepare for the query that checks that a valid parent has been selected.\n");
57 sqlite3_free(query);
58 return 1;
60 while (sqlite3_step(statement) == SQLITE_ROW) {
61 valid_parent = sqlite3_column_int(statement, 0);
63 sqlite3_finalize(statement);
64 sqlite3_free(query);
66 if (!valid_parent) {
67 printf("The parent for which you want to create a subtask does not exist.\n");
68 return 0;
70 } else if (tokens->len > 2) {
71 printf("Invalid amount of arguments.\n");
72 add_help();
73 return 0;
76 description = readline("Please enter a description for the new task:\n");
77 if (!description || strlen(description) <= 0) {
78 printf("Your description must not be an empty string.\n");
79 if (description) free(description);
80 return 0;
83 escapedDescription = escape(description);
84 free(description);
86 if (parent != -1) {
87 query = sqlite3_mprintf("INSERT INTO todo (description, createdDate, parent) VALUES (\'%s\', %d, %d);", escapedDescription, time(NULL), parent);
88 } else {
89 query = sqlite3_mprintf("INSERT INTO todo (description, createdDate) VALUES (\'%s\', %d);", escapedDescription, time(NULL));
92 if (sqlite3_exec(db, query, NULL, NULL, &errmsg) != SQLITE_OK) {
93 printf("An error occurred while trying to add a new task: %s\n", errmsg);
95 sqlite3_free(errmsg);
96 sqlite3_free(query);
98 return 0;