More features

This commit is contained in:
Mike Dvorkin
2010-08-01 11:47:48 -07:00
parent 0da661e4ea
commit f84c7ea8f1
14 changed files with 264 additions and 168 deletions

39
src/action.c Normal file
View File

@@ -0,0 +1,39 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pit.h"
static void action_list()
{
PAction pa;
PPager ppager;
pit_db_load();
if (actions->number_of_records > 0) {
ppager = pit_pager_initialize(PAGER_ACTION, actions->number_of_records);
for_each_action(pa) {
pit_pager_print(ppager, (uchar *)pa);
}
pit_pager_flush(ppager);
}
}
uchar *pit_action(ulong id, char *subject, char *message)
{
static Action action;
memset(&action, 0, sizeof(action));
action.subject_id = id;
strncpy(action.subject, subject, sizeof(action.subject) - 1);
strncpy(action.username, current_user(), sizeof(action.username) - 1);
strncpy(action.message, message, sizeof(action.message) - 1);
return pit_table_insert(actions, (uchar *)&action);
}
int pit_log(char *argv[])
{
action_list();
return 1;
}

View File

@@ -1,24 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pit.h"
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? */
PActivity pit_add_activity(ulong id, char *subject, char *message, ulong user_id) {
static Activity activity;
memset(&activity, 0, sizeof(activity));
activity.subject_id = id;
activity.created_by = user_id;
activity.created_at = time(NULL);
strncpy(activity.subject, subject, sizeof(activity.subject) - 1);
strncpy(activity.message, message, sizeof(activity.message) - 1);
return &activity;
}

View File

@@ -46,7 +46,7 @@ ulong pit_arg_number(char **arg, char *required)
// 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 pit_arg_date(char **arg, char *required)
{
time_t seconds = (time_t)-1;
struct tm tm;
@@ -100,4 +100,31 @@ time_t pit_arg_time(char **arg, char *required)
}
return seconds;
}
}
time_t pit_arg_time(char **arg, char *required)
{
time_t seconds = (time_t)-1;
char *format;
struct tm tm;
if (required && (!*arg || pit_arg_is_option(arg))) {
die("missing %s", required);
} else {
memset(&tm, 0, sizeof(tm)); /* Suppored time formats are HH, HH:MM, and :MM */
if (**arg == ':') {
format = ":%M"; /* Minutes only */
} else if (strchr(*arg, ':')) {
format = "%H:%M"; /* Hours and minutes */
} else {
format = "%H"; /* Hours only */
}
if (strptime(*arg, format, &tm)) {
seconds = mktime(&tm);
} else {
die("invalid time format: %s", *arg);
}
}
return seconds;
}

View File

@@ -18,6 +18,35 @@ static char *pit_file_name()
return file_name;
}
static void read_header(FILE *file)
{
Header hd;
if (fread(&hd, sizeof(hd), 1, file)) {
if (hd.signature[0] != 0x50 || hd.signature[1] != 0x49 || hd.signature[2] != 0x54) {
die("invalid pit file");
}
if (hd.schema_version != 0x01) {
die("invalid pit file version");
}
} else {
die("couldn't read header");
}
}
static void write_header(FILE *file)
{
Header hd;
hd.signature[0] = 0x50; hd.signature[1] = 0x49; hd.signature[2] = 0x54;
hd.schema_version = 0x01;
memset(&hd.reserved, 0, sizeof(hd.reserved));
if (!fwrite(&hd, sizeof(hd), 1, file)) {
die("couldn't write header");
}
}
int pit_init(char *argv[]) {
char **arg = &argv[1];
char *file_name = pit_file_name();
@@ -44,24 +73,22 @@ void pit_db_load() {
if (!file) {
perish(file_name);
} else {
projects = pit_table_load(file);
tasks = pit_table_load(file);
notes = pit_table_load(file);
activities = pit_table_load(file);
users = pit_table_load(file);
read_header(file);
projects = pit_table_load(file);
tasks = pit_table_load(file);
notes = pit_table_load(file);
actions = pit_table_load(file);
fclose(file);
}
}
void pit_db_initialize() {
projects = pit_table_initialize(sizeof(Project), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
tasks = pit_table_initialize(sizeof(Task), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
notes = pit_table_initialize(sizeof(Note), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
activities = pit_table_initialize(sizeof(Activity), TABLE_HAS_CREATED_AT);
users = pit_table_initialize(sizeof(User), TABLE_HAS_ID);
projects = pit_table_initialize(sizeof(Project), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
tasks = pit_table_initialize(sizeof(Task), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
notes = pit_table_initialize(sizeof(Note), TABLE_HAS_ID | TABLE_HAS_TIMESTAMPS);
actions = pit_table_initialize(sizeof(Action), TABLE_HAS_CREATED_AT);
pit_table_insert(users, (uchar *)pit_current_user());
pit_table_insert(activities, (uchar *)pit_add_activity(0, "", "Initialized pit", 1));
pit_action(0, "pit", "Initialized pit");
pit_db_save();
}
@@ -73,11 +100,11 @@ void pit_db_save() {
if (!file) {
perish(file_name);
} else {
write_header(file);
pit_table_save(file, projects);
pit_table_save(file, tasks);
pit_table_save(file, notes);
pit_table_save(file, activities);
pit_table_save(file, users);
pit_table_save(file, actions);
fclose(file);
}
}

View File

@@ -1,16 +1,20 @@
#if !defined(__MODELS_H__)
#define __MODELS_H__
typedef struct _Header {
char signature[3];
char schema_version;
char reserved[16];
} Header, *PHeader;
typedef struct _Project {
ulong id;
char username[32]; /* User the project belongs to. */
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 number_of_tasks; /* Number of tasks for 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;
@@ -18,15 +22,13 @@ typedef struct _Project {
typedef struct _Task {
ulong id;
ulong project_id; /* Which project the task belongs to? */
char username[32]; /* User 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 date; /* Generic date/time, ex: task deadline. */
time_t time; /* Generic time, ex: time spent on the task. */
ulong number_of_notes; /* Number of notes for the task. */
time_t created_at; /* When the task was created? */
time_t updated_at; /* When the task was last updated? */
} Task, *PTask;
@@ -34,25 +36,18 @@ typedef struct _Task {
typedef struct _Note {
ulong id;
ulong task_id; /* Task the note belongs to. */
char username[32]; /* User 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 {
typedef struct _Action {
ulong subject_id; /* Reference to the specific Project, Task, or Note. */
char subject[16]; /* Project, Task, or Note. */
char username[32]; /* Who added the log message? */
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;
} Action, *PAction;
#endif

View File

@@ -27,6 +27,7 @@ void pit_pager_print(PPager ppager, uchar *entry)
case PAGER_TASK:
sprintf(str, "%lu", ((PTask)*pentry)->id);
ppager->max.task.id = max(ppager->max.task.id, strlen(str));
ppager->max.task.username = max(ppager->max.task.username, strlen(((PTask)*pentry)->username));
ppager->max.task.name = max(ppager->max.task.name, strlen(((PTask)*pentry)->name));
ppager->max.task.status = max(ppager->max.task.status, strlen(((PTask)*pentry)->status));
ppager->max.task.priority = max(ppager->max.task.priority, strlen(((PTask)*pentry)->priority));
@@ -34,9 +35,14 @@ void pit_pager_print(PPager ppager, uchar *entry)
case PAGER_PROJECT:
sprintf(str, "%lu", ((PProject)*pentry)->id);
ppager->max.project.id = max(ppager->max.project.id, strlen(str));
ppager->max.project.username = max(ppager->max.project.username, strlen(((PProject)*pentry)->username));
ppager->max.project.name = max(ppager->max.project.name, strlen(((PProject)*pentry)->name));
ppager->max.project.status = max(ppager->max.project.status, strlen(((PProject)*pentry)->status));
break;
case PAGER_ACTION:
ppager->max.action.username = max(ppager->max.action.username, strlen(((PAction)*pentry)->username));
ppager->max.action.subject = max(ppager->max.action.subject, strlen(((PAction)*pentry)->subject));
break;
default:
die("invalid pager type: %d\n", ppager->type);
}
@@ -46,17 +52,18 @@ void pit_pager_print(PPager ppager, uchar *entry)
void pit_pager_flush(PPager ppager)
{
uchar **pentry;
char format[64];
char format[64], timestamp[32];
switch(ppager->type) {
case PAGER_TASK:
sprintf(format, "%%c %%%dlu: %%-%ds %%-%ds %%-%ds (%%lu note%%s)\n",
ppager->max.task.id, ppager->max.task.status, ppager->max.task.priority, ppager->max.task.name
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] [%%-%ds] %%-%ds (%%lu note%%s)\n",
ppager->max.task.id, ppager->max.task.username, ppager->max.task.status, ppager->max.task.priority, ppager->max.task.name
);
for_each_entry(ppager, pentry) {
printf(format,
(((PTask)*pentry)->id == tasks->current ? '*' : ' '),
((PTask)*pentry)->id,
((PTask)*pentry)->username,
((PTask)*pentry)->status,
((PTask)*pentry)->priority,
((PTask)*pentry)->name,
@@ -66,21 +73,32 @@ void pit_pager_flush(PPager ppager)
}
break;
case PAGER_PROJECT:
sprintf(format, "%%c %%%dlu: %%-%ds %%-%ds (%%lu open, %%lu closed task%%s)\n",
ppager->max.project.id, ppager->max.project.status, ppager->max.project.name
sprintf(format, "%%c %%%dlu: (%%-%ds) [%%-%ds] %%-%ds (%%lu task%%s)\n",
ppager->max.project.id, ppager->max.project.username, ppager->max.project.status, ppager->max.project.name
);
for_each_entry(ppager, pentry) {
printf(format,
(((PProject)*pentry)->id == projects->current ? '*' : ' '),
((PProject)*pentry)->id,
((PProject)*pentry)->username,
((PProject)*pentry)->status,
((PProject)*pentry)->name,
((PProject)*pentry)->number_of_open_tasks,
((PProject)*pentry)->number_of_closed_tasks,
((PProject)*pentry)->number_of_tasks,
(projects->number_of_records != 1 ? "s" : "")
);
}
break;
case PAGER_ACTION:
sprintf(format, "%%s (%%-%ds): %%s\n", ppager->max.action.username);
for_each_entry(ppager, pentry) {
strftime(timestamp, sizeof(timestamp), "%b %d, %Y %H:%M", localtime(&((PAction)*pentry)->created_at));
printf(format,
timestamp,
((PAction)*pentry)->username,
((PAction)*pentry)->message
);
}
break;
default:
pit_pager_free(ppager);
die("invalid pager type: %d\n", ppager->type);

View File

@@ -1,11 +1,10 @@
#if !defined(__PAGER_H__)
#define __PAGER_H__
#define PAGER_ACTIVITY 1
#define PAGER_PROJECT 2
#define PAGER_TASK 4
#define PAGER_NOTE 8
#define PAGER_USER 16
#define PAGER_ACTION 1
#define PAGER_PROJECT 2
#define PAGER_TASK 4
#define PAGER_NOTE 8
typedef struct _Pager {
ulong type;
@@ -14,16 +13,23 @@ typedef struct _Pager {
union {
struct {
int id;
int username;
int name;
int status;
} project;
struct {
int id;
int username;
int name;
int status;
int priority;
int deadline;
int date;
int time;
} task;
struct {
int username;
int subject;
} action;
} max;
} Pager, *PPager;

View File

@@ -7,8 +7,7 @@
PTable projects;
PTable tasks;
PTable notes;
PTable activities;
PTable users;
PTable actions;
static int usage() {
printf("usage...\n");
@@ -62,7 +61,7 @@ int main(int argc, char *argv[]) {
} else if (strstr(commands[2], argv[1]) == commands[2]) {
return 1; /* pit_note(&argv[1]); */
} else if (strstr(commands[3], argv[1]) == commands[3]) {
return 1; /* pit_log(&argv[1]); */
return pit_log(&argv[1]);
} else if (strstr(commands[4], argv[1]) == commands[4]) {
return pit_init(&argv[1]);
}

View File

@@ -28,24 +28,23 @@ typedef int bool;
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#define for_each_activity(ptr) for (ptr = (PActivity)activities->slots; (ptr - (PActivity)activities->slots) < activities->number_of_records; ptr++)
#define for_each_project(ptr) for (ptr = (PProject)projects->slots; (ptr - (PProject)projects->slots) < projects->number_of_records; ptr++)
#define for_each_note(ptr) for (ptr = (PNote)notes->slots; (ptr - (PNote)notes->slots) < notes->number_of_records; ptr++)
#define for_each_task(ptr) for (ptr = (PTask)tasks->slots; (ptr - (PTask)tasks->slots) < tasks->number_of_records; ptr++)
#define for_each_user(ptr) for (ptr = (PUser)users->slots; (ptr - (PUser)users->slots) < users->number_of_records; ptr++)
#define for_each_project(ptr) for (ptr = (PProject)projects->slots; (ptr - (PProject)projects->slots) < projects->number_of_records; ptr++)
#define for_each_task(ptr) for (ptr = (PTask)tasks->slots; (ptr - (PTask)tasks->slots) < tasks->number_of_records; ptr++)
#define for_each_note(ptr) for (ptr = (PNote)notes->slots; (ptr - (PNote)notes->slots) < notes->number_of_records; ptr++)
#define for_each_action(ptr) for (ptr = (PAction)actions->slots; (ptr - (PAction)actions->slots) < actions->number_of_records; ptr++)
/* Externals. */
extern PTable activities;
extern PTable actions;
extern PTable notes;
extern PTable projects;
extern PTable tasks;
extern PTable users;
/* args.c */
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_date(char **arg, char *required);
time_t pit_arg_time(char **arg, char *required);
/* db.c */
@@ -54,18 +53,19 @@ void pit_db_load();
void pit_db_save();
void pit_db_initialize();
/* activity.c project.c task.c user.c */
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);
/* log.c project.c task.c user.c */
int pit_project(char *argv[]);
int pit_task(char *argv[]);
int pit_log(char *argv[]);
char *pit_current_user();
uchar *pit_action(ulong id, char *subject, char *message);
/* util.c */
void die(char *msg, ...);
void perish(char *prefix);
void die(char *msg, ...);
void perish(char *prefix);
char *mem2str(char *mem, int len);
char *current_user();
char *home_dir(char *username, int len);
char *expand_path(char *path, char *expanded);
#endif

View File

@@ -42,19 +42,13 @@ static void create_project(char *name, char *status)
memset(&p, 0, sizeof(p));
if (!status) {
status = "active";
}
if (!status) status = "active";
printf("creating project [%s], status [%s]\n", name, status);
strncpy(p.name, name, sizeof(p.name) - 1);
strncpy(p.status, status, sizeof(p.status) - 1);
p.number_of_open_tasks = 0;
p.number_of_closed_tasks = 0;
p.closed_by = 0;
p.created_by = p.updated_by = 1; // TODO
p.closed_at = 0;
p.created_at = p.updated_at = time(NULL);
strncpy(p.username, current_user(), sizeof(p.username) - 1);
pp = (PProject)pit_table_insert(projects, (uchar *)&p);
pit_table_mark(projects, pp->id);
pit_db_save();
@@ -68,18 +62,13 @@ static int show_project(ulong number)
pit_db_load();
pp = (PProject)pit_table_find(projects, number);
if (pp) {
printf("%lu: %s (%s, %lu open task%s, %lu closed task%s)\n",
pp->id, pp->name, pp->status,
pp->number_of_open_tasks, (pp->number_of_open_tasks != 1 ? "s" : ""),
pp->number_of_closed_tasks, (pp->number_of_closed_tasks != 1 ? "s" : ""));
if (pp->number_of_open_tasks > 0) {
printf("%lu: %s (%s, %lu task%s)\n",
pp->id, pp->name, pp->status, pp->number_of_tasks, (pp->number_of_tasks != 1 ? "s" : ""));
if (pp->number_of_tasks > 0) {
PTask pt = (PTask)tasks->slots;
puts("Open tasks:");
puts("Tasks:");
for_each_task(pt) {
if (pt->closed_at) {
continue;
}
printf(" %c %lu: %s (%lu notes)\n", (pt->id == tasks->current ? '*' : ' '), pt->id, pt->name, pt->number_of_notes);
}
}

View File

@@ -1,21 +1,23 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include "pit.h"
static void task_list(char *name, char *status, char *priority, time_t deadline);
static void task_create(char *name, char *status, char *priority, time_t deadline);
static void task_list(char *name, char *status, char *priority, time_t date, time_t time);
static void task_create(char *name, char *status, char *priority, time_t date, time_t time);
static void task_show(ulong number);
static void task_delete(ulong number);
static void task_update(ulong number, char *name, char *status, char *priority, time_t deadline);
static void task_parse_options(char **arg, char **name, char **status, char **priority, time_t *deadline);
static void task_update(ulong number, char *name, char *status, char *priority, time_t date, time_t time);
static void task_log(char *message, ulong id, ...);
static void task_parse_options(char **arg, char **name, char **status, char **priority, time_t *date, time_t *time);
/*
** CREATING TASKS:
** pit task -c name [-s status] [-d deadline] [-p priority]
** pit task -c name [-s status] [-p priority] [-d date] [-t time]
**
** UPDATING TASKS:
** pit task -u [number] [-n name] [-s status] [-d deadline] [-p priority]
** pit task -u [number] [-n name] [-s status] [-p priority] [-d date] [-t time]
**
** DELETING TASKS:
** pit task -d [number]
@@ -24,10 +26,10 @@ static void task_parse_options(char **arg, char **name, char **status, char **pr
** pit task [[-q] number]
**
** LISTING TASKS:
** pit task -q [-s status] [-d deadline] [-p priority]
** pit task -q [-s status] [-p priority] [-d date] [-t time]
*/
static void task_list(char *name, char *status, char *priority, time_t deadline)
static void task_list(char *name, char *status, char *priority, time_t date, time_t time)
{
PProject pp;
PTask pt;
@@ -47,7 +49,7 @@ static void task_list(char *name, char *status, char *priority, time_t deadline)
}
}
static void task_create(char *name, char *status, char *priority, time_t deadline)
static void task_create(char *name, char *status, char *priority, time_t date, time_t time)
{
pit_db_load();
@@ -60,29 +62,24 @@ static void task_create(char *name, char *status, char *priority, time_t deadlin
memset(&t, 0, sizeof(t));
if (!status) {
status = "open";
}
if (!priority) {
priority = "normal";
}
if (!status) status = "open";
if (!priority) priority = "normal";
printf("creating task: %s, status: %s, priority: %s, deadline: %s", name, status, priority, ctime(&deadline));
printf("creating task: %s, status: %s, priority: %s, date: %s", name, status, priority, ctime(&date));
strncpy(t.name, name, sizeof(t.name) - 1);
strncpy(t.status, status, sizeof(t.status) - 1);
strncpy(t.priority, priority, sizeof(t.priority) - 1);
strncpy(t.username, current_user(), sizeof(t.username) - 1);
t.project_id = pp->id;
t.deadline = deadline;
t.number_of_notes = 0;
t.closed_by = 0;
t.created_by = t.updated_by = 1; // TODO
t.closed_at = 0;
t.created_at = t.updated_at = time(NULL);
t.date = date;
t.time = 0; /* TODO */
pt = (PTask)pit_table_insert(tasks, (uchar *)&t);
pit_table_mark(tasks, pt->id);
pp->number_of_open_tasks++;
pp->number_of_tasks++;
// pit_action(pit->id, "task", "created task #%d: %s (status: %s, priority: %s, date: %s)", pt->id, name, status, priority, (date ? ctime(&date) : "n/a"));
task_log("created task #%d: %s (status: %s, priority: %s, date: %s)", pt->id, name, status, priority, (date ? ctime(&date) : "n/a"));
pit_db_save();
}
}
@@ -97,12 +94,23 @@ static void task_delete(ulong number)
printf("task_delete(%lu)\n", number);
}
static void task_update(ulong number, char *name, char *status, char *priority, time_t deadline)
static void task_update(ulong number, char *name, char *status, char *priority, time_t date, time_t time)
{
printf("task_update: #%lu, name: %s, status: %s, priority: %s, deadline: %s", number, name, status, priority, ctime(&deadline));
printf("task_update: #%lu, name: %s, status: %s, priority: %s, date: %s", number, name, status, priority, ctime(&date));
}
static void task_parse_options(char **arg, char **name, char **status, char **priority, time_t *deadline)
static void task_log(char *message, ulong id, ...)
{
char str[128];
va_list params;
va_start(params, id);
vsnprintf(str, sizeof(str), (char *)&id, params);
pit_action(id, "task", str);
va_end(params);
}
static void task_parse_options(char **arg, char **name, char **status, char **priority, time_t *date, time_t *time)
{
while(*++arg) {
switch(pit_arg_option(arg)) {
@@ -113,7 +121,10 @@ static void task_parse_options(char **arg, char **name, char **status, char **pr
*priority = pit_arg_string(++arg, "task priority");
break;
case 'd':
*deadline = pit_arg_time(++arg, "task deadline");
*date = pit_arg_date(++arg, "task date");
break;
case 't':
*time = pit_arg_time(++arg, "task time");
break;
case 'n':
if (name) {
@@ -130,46 +141,47 @@ int pit_task(char *argv[])
{
char **arg = &argv[1];
char *name = NULL, *status = NULL, *priority = NULL;
time_t deadline = (time_t)0;
time_t date = (time_t)0;
time_t time = (time_t)0;
ulong number = 0L;
if (!*arg) {
task_list(NULL, NULL, NULL, 0); /* List all tasks (with default paramaters). */
task_list(NULL, NULL, NULL, 0, 0); /* List all tasks (with default paramaters). */
} else { /* pit task [number] */
number = pit_arg_number(arg, NULL);
if (number) {
task_show(number);
} else {
switch(pit_arg_option(arg)) {
case 'c': /* pit task -c name [-s status] [-p priority] [-d deadline] */
case 'c': /* pit task -c name [-s status] [-p priority] [-d date] [-t time] */
name = pit_arg_string(++arg, "task name");
task_parse_options(arg, NULL, &status, &priority, &deadline);
task_create(name, status, priority, deadline);
task_parse_options(arg, NULL, &status, &priority, &date, &time);
task_create(name, status, priority, date, time);
break;
case 'u': /* pit task -u [number] [-n name] [-s status] [-d deadline] [-p priority] */
case 'u': /* pit task -u [number] [-n name] [-s status] [-p priority] [-d date] [-t time]*/
number = pit_arg_number(++arg, NULL);
if (!number) --arg;
task_parse_options(arg, &name, &status, &priority, &deadline);
if (!name && !status && !priority && !deadline) {
task_parse_options(arg, &name, &status, &priority, &date, &time);
if (!name && !status && !priority && !date && !time) {
die("nothing to update");
} else {
task_update(number, name, status, priority, deadline);
task_update(number, name, status, priority, date, time);
}
break;
case 'd': /* pit task -d [number] */
number = pit_arg_number(++arg, NULL);
task_delete(number);
break;
case 'q': /* pit task -q [number | [-n name] [-s status] [-d deadline] [-p priority]] */
case 'q': /* pit task -q [number | [-n name] [-s status] [-p priority] [-d date] [-t time]] */
number = pit_arg_number(++arg, NULL);
if (number) {
task_show(number);
} else {
task_parse_options(--arg, &name, &status, &priority, &deadline);
if (!name && !status && !priority && !deadline) {
task_parse_options(--arg, &name, &status, &priority, &date, &time);
if (!name && !status && !priority && !date && !time) {
task_show(0);
} else {
task_list(name, status, priority, deadline);
task_list(name, status, priority, date, time);
}
}
break;

View File

@@ -1,9 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "pit.h"
char *pit_current_user() {
return getlogin();
}

View File

@@ -14,6 +14,20 @@ char *mem2str(char *mem, int len) {
return str;
}
char *current_user() {
static char *username = NULL;
if (!username) {
struct passwd *pws = getpwuid(geteuid());
if (!pws) {
perish("no username?!");
} else {
username = pws->pw_name;
}
}
return username;
}
char *home_dir(char *username, int len) {
char *str = mem2str(username, len);
struct passwd *pw = getpwnam(str);
@@ -47,3 +61,11 @@ char *expand_path(char *path, char *expanded) {
return expanded;
}
#ifdef TEST
int main(int argc, char *argv[]) {
printf("your username: %s\n", current_user());
printf("your (cached) username: %s\n", current_user());
return 1;
}
#endif