Streamlined .h files, added command line parsing routines

This commit is contained in:
Mike Dvorkin
2010-07-22 23:33:03 -07:00
parent 774424fa02
commit f02ffff989
17 changed files with 299 additions and 139 deletions

View File

@@ -15,6 +15,7 @@ CC = gcc -g -Os -Wall
SRC = \
$(SRCDIR)/activity.c \
$(SRCDIR)/args.c \
$(SRCDIR)/db.c \
$(SRCDIR)/pit.c \
$(SRCDIR)/project.c \
@@ -24,6 +25,7 @@ SRC = \
OBJ = \
$(OBJDIR)/activity.o \
$(OBJDIR)/args.o \
$(OBJDIR)/db.o \
$(OBJDIR)/pit.o \
$(OBJDIR)/project.o \
@@ -42,25 +44,28 @@ $(OBJDIR):
$(APP): $(OBJ)
$(CC) -o $(BINDIR)/$(APP) $(OBJ)
$(OBJDIR)/activity.o: $(SRCDIR)/activity.c $(SRCDIR)/activity.h
$(OBJDIR)/activity.o: $(SRCDIR)/activity.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/activity.o -c $(SRCDIR)/activity.c
$(OBJDIR)/db.o: $(SRCDIR)/db.c $(SRCDIR)/db.h
$(OBJDIR)/args.o: $(SRCDIR)/args.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/args.o -c $(SRCDIR)/args.c
$(OBJDIR)/db.o: $(SRCDIR)/db.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/db.o -c $(SRCDIR)/db.c
$(OBJDIR)/pit.o: $(SRCDIR)/pit.c $(SRCDIR)/pit.h
$(OBJDIR)/pit.o: $(SRCDIR)/pit.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/pit.o -c $(SRCDIR)/pit.c
$(OBJDIR)/project.o: $(SRCDIR)/project.c $(SRCDIR)/project.h
$(OBJDIR)/project.o: $(SRCDIR)/project.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/project.o -c $(SRCDIR)/project.c
$(OBJDIR)/table.o: $(SRCDIR)/table.c $(SRCDIR)/table.h
$(OBJDIR)/table.o: $(SRCDIR)/table.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/table.o -c $(SRCDIR)/table.c
$(OBJDIR)/task.o: $(SRCDIR)/task.c $(SRCDIR)/task.h
$(OBJDIR)/task.o: $(SRCDIR)/task.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/task.o -c $(SRCDIR)/task.c
$(OBJDIR)/user.o: $(SRCDIR)/user.c $(SRCDIR)/user.h
$(OBJDIR)/user.o: $(SRCDIR)/user.c $(SRCDIR)/pit.h $(SRCDIR)/models.h $(SRCDIR)/table.h
$(CC) -o $(OBJDIR)/user.o -c $(SRCDIR)/user.c
clean:

View File

@@ -1,9 +1,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "activity.h"
ulong subject_id; /* Reference to the specific Project, Task, or Note. */
char subject[16]; /* Project, Task, or Note. */

View File

@@ -1 +0,0 @@
PActivity pit_add_activity(ulong id, char *subject, char *message, ulong user_id);

102
src/args.c Normal file
View File

@@ -0,0 +1,102 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pit.h"
int pit_arg_is_option(char **arg)
{
return *arg && (**arg == '-' || **arg == '/') && strlen(*arg) == 2;
}
int pit_arg_option(char **arg)
{
if (pit_arg_is_option(arg)) {
return *(*arg + 1);
} else {
die("invalid option");
return 0;
}
}
char *pit_arg_string(char **arg, char *required)
{
if (required && (!*arg || pit_arg_is_option(arg))) {
die("missing %s", required);
}
return *arg;
}
ulong pit_arg_number(char **arg, char *required)
{
ulong number = 0L;
if (required && (!*arg || pit_arg_is_option(arg))) {
die("missing %s", required);
} else if (*arg) {
number = atol(*arg);
if (number == 0 && **arg != '0' && required) {
die("invalid %s value: %s", required, *arg);
}
}
return number;
}
// char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tm);
// time_t mktime ( struct tm * timeptr );
time_t pit_arg_time(char **arg, char *required)
{
time_t seconds = (time_t)-1;
struct tm tm;
if (required && (!*arg || pit_arg_is_option(arg))) {
die("missing %s", required);
} else {
memset(&tm, 0, sizeof(tm));
if (strptime(*arg, "%m/%d/%Y", &tm)) {
seconds = mktime(&tm);
}
if (strchr(*arg, ',')) { /* Date present. */
if (strchr(*arg, ':')) { /* Date and HH:MM. */
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* Date and HH:MM am/pm. */
/* Oct 10, 1992 7:30pm */
} else {
/* Oct 10, 1992 19:30 */
}
} else {
if (strlen(*arg) > 12) { /* Date and HH. */
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* Date and HH am/pm. */
/* Oct 10, 1992 7pm */
} else {
/* Oct 10, 1992 19 */ /* HH */
}
} else { /* Date with no time. */
/* Oct 10, 1992 19 */
}
}
} else { /* No date, time only. */
if (strchr(*arg, ':')) { /* HH:MM. */
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* HH:MM am/pm. */
/* 7:30pm */
} else {
/* 19:30 */
}
} else {
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* HH am/pm. */
/* 7pm */
} else {
/* 19 */ /* HH */
}
}
}
if (seconds == (time_t)-1) {
die("invalid %s: %s", required, *arg);
}
}
return seconds;
}

View File

@@ -5,9 +5,6 @@
#include <pwd.h>
#include <sys/types.h>
#include "pit.h"
#include "db.h"
#include "activity.h"
#include "user.h"
#define PITFILE "~/.pit"

View File

@@ -1,8 +0,0 @@
#if !defined(__DB_H__)
#define __DB_H__
int pit_init(char *argv[]);
void pit_db_load();
void pit_db_save();
void pit_db_initialize();
#endif

58
src/models.h Normal file
View File

@@ -0,0 +1,58 @@
#if !defined(__MODELS_H__)
#define __MODELS_H__
typedef struct _Project {
ulong id;
char name[128]; /* Project name. */
char status[16]; /* Project status. */
ulong number_of_open_tasks; /* Number of open tasks. */
ulong number_of_closed_tasks; /* Number of closed tasks. */
ulong closed_by; /* Who closed the project? */
ulong created_by; /* Who created the project? */
ulong updated_by; /* Who last updated the project? */
time_t closed_at; /* When the project was closed? */
time_t created_at; /* When the project was created? */
time_t updated_at; /* When the project was last updated? */
} Project, *PProject;
typedef struct _Task {
ulong id;
ulong project_id; /* Which project the task belongs to? */
char name[128]; /* Task name. */
char status[16]; /* Task status. */
char priority[16]; /* Task priority. */
time_t deadline; /* Task deadline. */
ulong number_of_notes; /* Number of notes. */
ulong closed_by; /* Who closed the task? */
ulong created_by; /* Who created the task? */
ulong updated_by; /* Who last updated the task? */
time_t closed_at; /* When the task was closed? */
time_t created_at; /* When the task was created? */
time_t updated_at; /* When the task was last updated? */
} Task, *PTask;
typedef struct _Note {
ulong id;
ulong task_id; /* Task the note belongs to. */
char message[255]; /* The body of the note. */
ulong created_by; /* Who created the note? */
ulong updated_by; /* Who last updated the note? */
time_t created_at; /* When the note was created? */
time_t updated_at; /* When the note was last updated? */
} Note, *PNote;
typedef struct _Activity {
ulong subject_id; /* Reference to the specific Project, Task, or Note. */
char subject[16]; /* Project, Task, or Note. */
char message[255]; /* Log message. */
ulong created_by; /* Who added log message? */
time_t created_at; /* When log message was added? */
} Activity, *PActivity;
typedef struct _User {
ulong id;
char username[32]; /* Username. */
char email[32]; /* User's email. */
} User, *PUser;
#endif

View File

@@ -1,11 +1,8 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "db.h"
#include "project.h"
#include "task.h"
PTable projects;
PTable tasks;
@@ -21,12 +18,18 @@ static int usage() {
/*
** Suicide.
*/
void die(char *msg)
void die(char *message, ...)
{
fprintf(stderr, "pit: %s\n", msg);
char str[4096];
va_list params;
va_start(params, message);
vsnprintf(str, sizeof(str), message, params);
fprintf(stderr, "pit: %s\n", str);
va_end(params);
exit(0);
}
/*
** Forceful death.
*/

View File

@@ -5,69 +5,38 @@ typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned char uchar;
#include <time.h>
#include "models.h"
#include "table.h"
typedef struct _Project {
ulong id;
char name[128]; /* Project name. */
char status[16]; /* Project status. */
ulong number_of_open_tasks; /* Number of open tasks. */
ulong number_of_closed_tasks; /* Number of closed tasks. */
ulong closed_by; /* Who closed the project? */
ulong created_by; /* Who created the project? */
ulong updated_by; /* Who last updated the project? */
time_t closed_at; /* When the project was closed? */
time_t created_at; /* When the project was created? */
time_t updated_at; /* When the project was last updated? */
} Project, *PProject;
typedef struct _Task {
ulong id;
ulong project_id; /* Which project the task belongs to? */
int priority; /* Task priority. */
char name[128]; /* Task name. */
char status[16]; /* Task status. */
time_t deadline; /* Task deadline. */
ulong number_of_notes; /* Number of notes. */
ulong closed_by; /* Who closed the task? */
ulong created_by; /* Who created the task? */
ulong updated_by; /* Who last updated the task? */
time_t closed_at; /* When the task was closed? */
time_t created_at; /* When the task was created? */
time_t updated_at; /* When the task was last updated? */
} Task, *PTask;
typedef struct _Note {
ulong id;
ulong task_id; /* Task the note belongs to. */
char message[255]; /* The body of the note. */
ulong created_by; /* Who created the note? */
ulong updated_by; /* Who last updated the note? */
time_t created_at; /* When the note was created? */
time_t updated_at; /* When the note was last updated? */
} Note, *PNote;
typedef struct _Activity {
ulong subject_id; /* Reference to the specific Project, Task, or Note. */
char subject[16]; /* Project, Task, or Note. */
char message[255]; /* Log message. */
ulong created_by; /* Who added log message? */
time_t created_at; /* When log message was added? */
} Activity, *PActivity;
typedef struct _User {
ulong id;
char username[32]; /* Username. */
char email[32]; /* User's email. */
} User, *PUser;
/* Externals. */
extern PTable projects;
extern PTable tasks;
extern PTable notes;
extern PTable activities;
extern PTable users;
void die(char *msg);
/* Command line parsing. */
int pit_arg_is_option(char **arg);
int pit_arg_option(char **arg);
char *pit_arg_string(char **arg, char *required);
ulong pit_arg_number(char **arg, char *required);
time_t pit_arg_time(char **arg, char *required);
/* Database. */
int pit_init(char *argv[]);
void pit_db_load();
void pit_db_save();
void pit_db_initialize();
/* Models. */
int pit_project(char *argv[]);
int pit_task(char *argv[]);
char *pit_current_user();
PActivity pit_add_activity(ulong id, char *subject, char *message, ulong user_id);
/* Utilities. */
void die(char *msg, ...);
void perish(char *prefix);
#endif

View File

@@ -1,10 +1,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "db.h"
#include "project.h"
static int already_exist(char *name)
{

View File

@@ -1,6 +0,0 @@
#if !defined(__PROJECT_H__)
#define __PROJECT_H__
int pit_project(char *argv[]);
#endif

View File

@@ -1,7 +1,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "pit.h"
#define TABLE_INCREMENT 10

Binary file not shown.

View File

@@ -1,12 +1,25 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "pit.h"
#include "db.h"
#include "task.h"
static void list_tasks()
/*
** CREATING TASKS:
** pit task -c name [-s status] [-d deadline] [-p priority]
**
** UPDATING TASKS:
** pit task -u [number] [-n name] [-s status] [-d deadline] [-p priority]
**
** DELETING TASKS:
** pit task -d [number]
**
** SHOWING TASK:
** pit task [-s number]
**
** LISTING TASKS:
** pit task -s [all|open|closed] [-s status] [-d deadline] [-p priority]
*/
static void list_tasks(char *mode, char *status, char *deadline, ulong priority)
{
pit_db_load();
@@ -22,7 +35,7 @@ static void list_tasks()
}
}
static void create_task(char *name, char *status)
static void create_task(char *name, char *status, char *priority, time_t deadline)
{
pit_db_load();
@@ -38,13 +51,17 @@ static void create_task(char *name, char *status)
if (!status) {
status = "open";
}
printf("creating task [%s], status [%s]\n", name, status);
if (!priority) {
priority = "normal";
}
printf("creating task: %s, status: %s, priority: %s, deadline: %s", name, status, priority, ctime(&deadline));
strncpy(t.name, name, sizeof(t.name) - 1);
strncpy(t.status, status, sizeof(t.status) - 1);
strncpy(t.priority, priority, sizeof(t.priority) - 1);
t.project_id = pp->id;
t.priority = 1;
t.deadline = time(NULL);
t.deadline = deadline;
t.number_of_notes = 0;
t.closed_by = 0;
t.created_by = t.updated_by = 1; // TODO
@@ -58,49 +75,88 @@ static void create_task(char *name, char *status)
}
}
static int show_task(ulong number)
static void show_task(ulong number)
{
return 1;
printf("show_task(%lu)\n", number);
}
static int delete_task(ulong number)
static void delete_task(ulong number)
{
return 1;
printf("delete_task(%lu)\n", number);
}
static void update_task(ulong number, char *name, char *status, char *priority, time_t deadline)
{
printf("update task: #%lu, name: %s, status: %s, priority: %s, deadline: %s", number, name, status, priority, ctime(&deadline));
}
int pit_task(char *argv[])
{
char **arg = &argv[1];
unsigned long number;
char *name = NULL, *status = NULL, *priority = NULL;
time_t deadline = (time_t)0;
ulong number = 0;
if (!*arg) {
list_tasks();
} else if (!strcmp(*arg, "-c")) {
if (!*++arg) {
die("missing task name");
} else {
create_task(*arg, *(arg + 1));
}
} else if (!strcmp(*arg, "-d")) {
if (!*++arg) {
die("missing task number");
} else {
number = atoi(*arg);
if (!number) {
die("invalid task number");
} else {
delete_task(number);
}
}
/* } else if (!strcmp(*arg, "-e")) { TODO: Edit */
list_tasks(NULL, NULL, NULL, 0); /* ...with default paramaters. */
} else {
number = atoi(*arg);
if (!number) {
die("invalid task parameters");
} else {
switch(pit_arg_option(arg)) {
case 'c': /* pit task -c name [-s status] [-p priority] [-d deadline] */
name = pit_arg_string(++arg, "task name");
while(*++arg) {
switch(pit_arg_option(arg)) {
case 's':
status = pit_arg_string(++arg, "task status");
break;
case 'p':
priority = pit_arg_string(++arg, "task priority");
break;
case 'd':
deadline = pit_arg_time(++arg, "task deadline");
break;
default:
die("invalid task option: %s", *arg);
}
}
create_task(name, status, priority, deadline);
break;
case 'u': /* pit task -u [number] [-n name] [-s status] [-d deadline] [-p priority] */
number = pit_arg_number(++arg, NULL);
if (!number) --arg;
while(*++arg) {
switch(pit_arg_option(arg)) {
case 'n':
name = pit_arg_string(++arg, "task name");
break;
case 's':
status = pit_arg_string(++arg, "task status");
break;
case 'p':
priority = pit_arg_string(++arg, "task priority");
break;
case 'd':
deadline = pit_arg_time(++arg, "task deadline");
break;
default:
die("invalid task option: %s", *arg);
}
}
if (!name && !status && !priority && !deadline) {
die("nothing to update");
} else {
update_task(number, name, status, priority, deadline);
}
break;
case 'd': /* pit task -d [number] */
number = pit_arg_number(++arg, NULL);
delete_task(number);
break;
case 's': /* pit task -s [all|open|closed] [-s status] [-d deadline] [-p priority] */
break;
default: /* pit task [number] */
number = pit_arg_number(++arg, NULL);
show_task(number);
}
}
return 1;
}

View File

@@ -1,6 +0,0 @@
#if !defined(__TASK_H__)
#define __TASK_H__
int pit_task(char *argv[]);
#endif

View File

@@ -1,10 +1,8 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "pit.h"
#include "user.h"
char *pit_current_user() {
return getlogin();

View File

@@ -1 +0,0 @@
char *pit_current_user();