Use tabs instead of spaces for indentation
This completes our switch to the Linux kernel coding style. Note that we still use deeply nested constructs at some places which need to be fixed up later. Converted using the `Lindent` script from the Linux kernel code base, along with some manual fixes. Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
parent
9907069f44
commit
694d28eb78
257
src/apoint.c
257
src/apoint.c
@ -45,31 +45,31 @@ llist_ts_t alist_p;
|
||||
|
||||
void apoint_free(struct apoint *apt)
|
||||
{
|
||||
mem_free(apt->mesg);
|
||||
erase_note(&apt->note);
|
||||
mem_free(apt);
|
||||
mem_free(apt->mesg);
|
||||
erase_note(&apt->note);
|
||||
mem_free(apt);
|
||||
}
|
||||
|
||||
struct apoint *apoint_dup(struct apoint *in)
|
||||
{
|
||||
EXIT_IF(!in, _("null pointer"));
|
||||
EXIT_IF(!in, _("null pointer"));
|
||||
|
||||
struct apoint *apt = mem_malloc(sizeof(struct apoint));
|
||||
apt->start = in->start;
|
||||
apt->dur = in->dur;
|
||||
apt->state = in->state;
|
||||
apt->mesg = mem_strdup(in->mesg);
|
||||
if (in->note)
|
||||
apt->note = mem_strdup(in->note);
|
||||
else
|
||||
apt->note = NULL;
|
||||
struct apoint *apt = mem_malloc(sizeof(struct apoint));
|
||||
apt->start = in->start;
|
||||
apt->dur = in->dur;
|
||||
apt->state = in->state;
|
||||
apt->mesg = mem_strdup(in->mesg);
|
||||
if (in->note)
|
||||
apt->note = mem_strdup(in->note);
|
||||
else
|
||||
apt->note = NULL;
|
||||
|
||||
return apt;
|
||||
return apt;
|
||||
}
|
||||
|
||||
void apoint_llist_init(void)
|
||||
{
|
||||
LLIST_TS_INIT(&alist_p);
|
||||
LLIST_TS_INIT(&alist_p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -79,142 +79,145 @@ void apoint_llist_init(void)
|
||||
*/
|
||||
void apoint_llist_free(void)
|
||||
{
|
||||
LLIST_TS_FREE_INNER(&alist_p, apoint_free);
|
||||
LLIST_TS_FREE(&alist_p);
|
||||
LLIST_TS_FREE_INNER(&alist_p, apoint_free);
|
||||
LLIST_TS_FREE(&alist_p);
|
||||
}
|
||||
|
||||
static int apoint_cmp_start(struct apoint *a, struct apoint *b)
|
||||
{
|
||||
return a->start < b->start ? -1 : (a->start == b->start ? 0 : 1);
|
||||
return a->start < b->start ? -1 : (a->start == b->start ? 0 : 1);
|
||||
}
|
||||
|
||||
struct apoint *apoint_new(char *mesg, char *note, long start, long dur,
|
||||
char state)
|
||||
char state)
|
||||
{
|
||||
struct apoint *apt;
|
||||
struct apoint *apt;
|
||||
|
||||
apt = mem_malloc(sizeof(struct apoint));
|
||||
apt->mesg = mem_strdup(mesg);
|
||||
apt->note = (note != NULL) ? mem_strdup(note) : NULL;
|
||||
apt->state = state;
|
||||
apt->start = start;
|
||||
apt->dur = dur;
|
||||
apt = mem_malloc(sizeof(struct apoint));
|
||||
apt->mesg = mem_strdup(mesg);
|
||||
apt->note = (note != NULL) ? mem_strdup(note) : NULL;
|
||||
apt->state = state;
|
||||
apt->start = start;
|
||||
apt->dur = dur;
|
||||
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_ADD_SORTED(&alist_p, apt, apoint_cmp_start);
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_ADD_SORTED(&alist_p, apt, apoint_cmp_start);
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
|
||||
return apt;
|
||||
return apt;
|
||||
}
|
||||
|
||||
unsigned apoint_inday(struct apoint *i, long *start)
|
||||
{
|
||||
return (i->start <= *start + DAYINSEC && i->start + i->dur > *start);
|
||||
return (i->start <= *start + DAYINSEC
|
||||
&& i->start + i->dur > *start);
|
||||
}
|
||||
|
||||
void apoint_sec2str(struct apoint *o, long day, char *start, char *end)
|
||||
{
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
|
||||
if (o->start < day) {
|
||||
strncpy(start, "..:..", 6);
|
||||
} else {
|
||||
t = o->start;
|
||||
localtime_r(&t, <);
|
||||
snprintf(start, HRMIN_SIZE, "%02u:%02u", lt.tm_hour, lt.tm_min);
|
||||
}
|
||||
if (o->start + o->dur > day + DAYINSEC) {
|
||||
strncpy(end, "..:..", 6);
|
||||
} else {
|
||||
t = o->start + o->dur;
|
||||
localtime_r(&t, <);
|
||||
snprintf(end, HRMIN_SIZE, "%02u:%02u", lt.tm_hour, lt.tm_min);
|
||||
}
|
||||
if (o->start < day) {
|
||||
strncpy(start, "..:..", 6);
|
||||
} else {
|
||||
t = o->start;
|
||||
localtime_r(&t, <);
|
||||
snprintf(start, HRMIN_SIZE, "%02u:%02u", lt.tm_hour,
|
||||
lt.tm_min);
|
||||
}
|
||||
if (o->start + o->dur > day + DAYINSEC) {
|
||||
strncpy(end, "..:..", 6);
|
||||
} else {
|
||||
t = o->start + o->dur;
|
||||
localtime_r(&t, <);
|
||||
snprintf(end, HRMIN_SIZE, "%02u:%02u", lt.tm_hour,
|
||||
lt.tm_min);
|
||||
}
|
||||
}
|
||||
|
||||
void apoint_write(struct apoint *o, FILE * f)
|
||||
{
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
|
||||
t = o->start;
|
||||
localtime_r(&t, <);
|
||||
fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt.tm_mon + 1, lt.tm_mday,
|
||||
1900 + lt.tm_year, lt.tm_hour, lt.tm_min);
|
||||
t = o->start;
|
||||
localtime_r(&t, <);
|
||||
fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt.tm_mon + 1, lt.tm_mday,
|
||||
1900 + lt.tm_year, lt.tm_hour, lt.tm_min);
|
||||
|
||||
t = o->start + o->dur;
|
||||
localtime_r(&t, <);
|
||||
fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u ", lt.tm_mon + 1, lt.tm_mday,
|
||||
1900 + lt.tm_year, lt.tm_hour, lt.tm_min);
|
||||
t = o->start + o->dur;
|
||||
localtime_r(&t, <);
|
||||
fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u ", lt.tm_mon + 1,
|
||||
lt.tm_mday, 1900 + lt.tm_year, lt.tm_hour, lt.tm_min);
|
||||
|
||||
if (o->note != NULL)
|
||||
fprintf(f, ">%s ", o->note);
|
||||
if (o->note != NULL)
|
||||
fprintf(f, ">%s ", o->note);
|
||||
|
||||
if (o->state & APOINT_NOTIFY)
|
||||
fputc('!', f);
|
||||
else
|
||||
fputc('|', f);
|
||||
if (o->state & APOINT_NOTIFY)
|
||||
fputc('!', f);
|
||||
else
|
||||
fputc('|', f);
|
||||
|
||||
fprintf(f, "%s\n", o->mesg);
|
||||
fprintf(f, "%s\n", o->mesg);
|
||||
}
|
||||
|
||||
struct apoint *apoint_scan(FILE * f, struct tm start, struct tm end, char state,
|
||||
char *note)
|
||||
struct apoint *apoint_scan(FILE * f, struct tm start, struct tm end,
|
||||
char state, char *note)
|
||||
{
|
||||
char buf[BUFSIZ], *newline;
|
||||
time_t tstart, tend;
|
||||
char buf[BUFSIZ], *newline;
|
||||
time_t tstart, tend;
|
||||
|
||||
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
|
||||
!check_date(end.tm_year, end.tm_mon, end.tm_mday) ||
|
||||
!check_time(start.tm_hour, start.tm_min) ||
|
||||
!check_time(end.tm_hour, end.tm_min),
|
||||
_("date error in appointment"));
|
||||
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
|
||||
!check_date(end.tm_year, end.tm_mon, end.tm_mday) ||
|
||||
!check_time(start.tm_hour, start.tm_min) ||
|
||||
!check_time(end.tm_hour, end.tm_min),
|
||||
_("date error in appointment"));
|
||||
|
||||
/* Read the appointment description */
|
||||
if (!fgets(buf, sizeof buf, f))
|
||||
return NULL;
|
||||
/* Read the appointment description */
|
||||
if (!fgets(buf, sizeof buf, f))
|
||||
return NULL;
|
||||
|
||||
newline = strchr(buf, '\n');
|
||||
if (newline)
|
||||
*newline = '\0';
|
||||
newline = strchr(buf, '\n');
|
||||
if (newline)
|
||||
*newline = '\0';
|
||||
|
||||
start.tm_sec = end.tm_sec = 0;
|
||||
start.tm_isdst = end.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
end.tm_year -= 1900;
|
||||
end.tm_mon--;
|
||||
start.tm_sec = end.tm_sec = 0;
|
||||
start.tm_isdst = end.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
end.tm_year -= 1900;
|
||||
end.tm_mon--;
|
||||
|
||||
tstart = mktime(&start);
|
||||
tend = mktime(&end);
|
||||
EXIT_IF(tstart == -1 || tend == -1 || tstart > tend,
|
||||
_("date error in appointment"));
|
||||
return apoint_new(buf, note, tstart, tend - tstart, state);
|
||||
tstart = mktime(&start);
|
||||
tend = mktime(&end);
|
||||
EXIT_IF(tstart == -1 || tend == -1 || tstart > tend,
|
||||
_("date error in appointment"));
|
||||
return apoint_new(buf, note, tstart, tend - tstart, state);
|
||||
}
|
||||
|
||||
void apoint_delete(struct apoint *apt)
|
||||
{
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
|
||||
llist_item_t *i = LLIST_TS_FIND_FIRST(&alist_p, apt, NULL);
|
||||
int need_check_notify = 0;
|
||||
llist_item_t *i = LLIST_TS_FIND_FIRST(&alist_p, apt, NULL);
|
||||
int need_check_notify = 0;
|
||||
|
||||
if (!i)
|
||||
EXIT(_("no such appointment"));
|
||||
if (!i)
|
||||
EXIT(_("no such appointment"));
|
||||
|
||||
if (notify_bar())
|
||||
need_check_notify = notify_same_item(apt->start);
|
||||
LLIST_TS_REMOVE(&alist_p, i);
|
||||
if (need_check_notify)
|
||||
notify_check_next_app(0);
|
||||
if (notify_bar())
|
||||
need_check_notify = notify_same_item(apt->start);
|
||||
LLIST_TS_REMOVE(&alist_p, i);
|
||||
if (need_check_notify)
|
||||
notify_check_next_app(0);
|
||||
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
}
|
||||
|
||||
static int apoint_starts_after(struct apoint *apt, long *time)
|
||||
{
|
||||
return apt->start > *time;
|
||||
return apt->start > *time;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -223,25 +226,25 @@ static int apoint_starts_after(struct apoint *apt, long *time)
|
||||
*/
|
||||
struct notify_app *apoint_check_next(struct notify_app *app, long start)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
i = LLIST_TS_FIND_FIRST(&alist_p, &start, apoint_starts_after);
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
i = LLIST_TS_FIND_FIRST(&alist_p, &start, apoint_starts_after);
|
||||
|
||||
if (i) {
|
||||
struct apoint *apt = LLIST_TS_GET_DATA(i);
|
||||
if (i) {
|
||||
struct apoint *apt = LLIST_TS_GET_DATA(i);
|
||||
|
||||
if (apt->start <= app->time) {
|
||||
app->time = apt->start;
|
||||
app->txt = mem_strdup(apt->mesg);
|
||||
app->state = apt->state;
|
||||
app->got_app = 1;
|
||||
}
|
||||
}
|
||||
if (apt->start <= app->time) {
|
||||
app->time = apt->start;
|
||||
app->txt = mem_strdup(apt->mesg);
|
||||
app->state = apt->state;
|
||||
app->got_app = 1;
|
||||
}
|
||||
}
|
||||
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
|
||||
return app;
|
||||
return app;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -249,23 +252,23 @@ struct notify_app *apoint_check_next(struct notify_app *app, long start)
|
||||
*/
|
||||
void apoint_switch_notify(struct apoint *apt)
|
||||
{
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
|
||||
apt->state ^= APOINT_NOTIFY;
|
||||
if (notify_bar())
|
||||
notify_check_added(apt->mesg, apt->start, apt->state);
|
||||
apt->state ^= APOINT_NOTIFY;
|
||||
if (notify_bar())
|
||||
notify_check_added(apt->mesg, apt->start, apt->state);
|
||||
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
}
|
||||
|
||||
void apoint_paste_item(struct apoint *apt, long date)
|
||||
{
|
||||
apt->start = date + get_item_time(apt->start);
|
||||
apt->start = date + get_item_time(apt->start);
|
||||
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_ADD_SORTED(&alist_p, apt, apoint_cmp_start);
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_ADD_SORTED(&alist_p, apt, apoint_cmp_start);
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
|
||||
if (notify_bar())
|
||||
notify_check_added(apt->mesg, apt->start, apt->state);
|
||||
if (notify_bar())
|
||||
notify_check_added(apt->mesg, apt->start, apt->state);
|
||||
}
|
||||
|
1065
src/args.c
1065
src/args.c
File diff suppressed because it is too large
Load Diff
817
src/calcurse.c
817
src/calcurse.c
File diff suppressed because it is too large
Load Diff
445
src/calcurse.h
445
src/calcurse.h
@ -156,9 +156,9 @@
|
||||
#define TAB 9
|
||||
#define SPACE 32
|
||||
|
||||
#define KEYS_KEYLEN 3 /* length of each keybinding */
|
||||
#define KEYS_LABELEN 8 /* length of command description */
|
||||
#define KEYS_CMDS_PER_LINE 6 /* max number of commands per line */
|
||||
#define KEYS_KEYLEN 3 /* length of each keybinding */
|
||||
#define KEYS_LABELEN 8 /* length of command description */
|
||||
#define KEYS_CMDS_PER_LINE 6 /* max number of commands per line */
|
||||
|
||||
/* Register definitions. */
|
||||
#define REG_BLACK_HOLE 37
|
||||
@ -234,45 +234,45 @@
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
|
||||
enum win {
|
||||
CAL,
|
||||
APP,
|
||||
TOD,
|
||||
NOT,
|
||||
STA,
|
||||
KEY,
|
||||
NBWINS
|
||||
CAL,
|
||||
APP,
|
||||
TOD,
|
||||
NOT,
|
||||
STA,
|
||||
KEY,
|
||||
NBWINS
|
||||
};
|
||||
|
||||
/* General configuration variables. */
|
||||
struct conf {
|
||||
unsigned auto_save;
|
||||
unsigned auto_gc;
|
||||
unsigned periodic_save;
|
||||
unsigned confirm_quit;
|
||||
unsigned confirm_delete;
|
||||
enum win default_panel;
|
||||
unsigned compact_panels;
|
||||
unsigned system_dialogs;
|
||||
unsigned progress_bar;
|
||||
const char *editor;
|
||||
const char *pager;
|
||||
char output_datefmt[BUFSIZ]; /* format for displaying date */
|
||||
int input_datefmt; /* format for reading date */
|
||||
unsigned auto_save;
|
||||
unsigned auto_gc;
|
||||
unsigned periodic_save;
|
||||
unsigned confirm_quit;
|
||||
unsigned confirm_delete;
|
||||
enum win default_panel;
|
||||
unsigned compact_panels;
|
||||
unsigned system_dialogs;
|
||||
unsigned progress_bar;
|
||||
const char *editor;
|
||||
const char *pager;
|
||||
char output_datefmt[BUFSIZ]; /* format for displaying date */
|
||||
int input_datefmt; /* format for reading date */
|
||||
};
|
||||
|
||||
/* Daemon-related configuration. */
|
||||
struct dmon_conf {
|
||||
unsigned enable; /* launch daemon automatically when exiting */
|
||||
unsigned log; /* log daemon activity */
|
||||
unsigned enable; /* launch daemon automatically when exiting */
|
||||
unsigned log; /* log daemon activity */
|
||||
};
|
||||
|
||||
/* Input date formats. */
|
||||
enum datefmt {
|
||||
DATEFMT_MMDDYYYY = 1,
|
||||
DATEFMT_DDMMYYYY,
|
||||
DATEFMT_YYYYMMDD,
|
||||
DATEFMT_ISO,
|
||||
DATEFMT_MAX
|
||||
DATEFMT_MMDDYYYY = 1,
|
||||
DATEFMT_DDMMYYYY,
|
||||
DATEFMT_YYYYMMDD,
|
||||
DATEFMT_ISO,
|
||||
DATEFMT_MAX
|
||||
};
|
||||
|
||||
#define DATE_FORMATS (DATEFMT_MAX - 1)
|
||||
@ -286,179 +286,179 @@ enum datefmt {
|
||||
(datefmt == DATEFMT_YYYYMMDD ? _("yyyy/mm/dd") : _("yyyy-mm-dd"))))
|
||||
|
||||
struct date {
|
||||
unsigned dd;
|
||||
unsigned mm;
|
||||
unsigned yyyy;
|
||||
unsigned dd;
|
||||
unsigned mm;
|
||||
unsigned yyyy;
|
||||
};
|
||||
|
||||
/* Appointment definition. */
|
||||
struct apoint {
|
||||
long start; /* seconds since 1 jan 1970 */
|
||||
long dur; /* duration of the appointment in seconds */
|
||||
long start; /* seconds since 1 jan 1970 */
|
||||
long dur; /* duration of the appointment in seconds */
|
||||
|
||||
#define APOINT_NULL 0x0
|
||||
#define APOINT_NOTIFY 0x1 /* Item needs to be notified */
|
||||
#define APOINT_NOTIFIED 0x2 /* Item was already notified */
|
||||
int state;
|
||||
#define APOINT_NOTIFY 0x1 /* Item needs to be notified */
|
||||
#define APOINT_NOTIFIED 0x2 /* Item was already notified */
|
||||
int state;
|
||||
|
||||
char *mesg;
|
||||
char *note;
|
||||
char *mesg;
|
||||
char *note;
|
||||
};
|
||||
|
||||
/* Event definition. */
|
||||
struct event {
|
||||
int id; /* event identifier */
|
||||
long day; /* seconds since 1 jan 1970 */
|
||||
char *mesg;
|
||||
char *note;
|
||||
int id; /* event identifier */
|
||||
long day; /* seconds since 1 jan 1970 */
|
||||
char *mesg;
|
||||
char *note;
|
||||
};
|
||||
|
||||
/* Todo item definition. */
|
||||
struct todo {
|
||||
char *mesg;
|
||||
int id;
|
||||
char *note;
|
||||
char *mesg;
|
||||
int id;
|
||||
char *note;
|
||||
};
|
||||
|
||||
/* Number of items in current day. */
|
||||
struct day_items_nb {
|
||||
unsigned nb_events;
|
||||
unsigned nb_apoints;
|
||||
unsigned nb_events;
|
||||
unsigned nb_apoints;
|
||||
};
|
||||
|
||||
struct excp {
|
||||
long st; /* beggining of the considered day, in seconds */
|
||||
long st; /* beggining of the considered day, in seconds */
|
||||
};
|
||||
|
||||
enum recur_type {
|
||||
RECUR_NO,
|
||||
RECUR_DAILY,
|
||||
RECUR_WEEKLY,
|
||||
RECUR_MONTHLY,
|
||||
RECUR_YEARLY,
|
||||
RECUR_TYPES
|
||||
RECUR_NO,
|
||||
RECUR_DAILY,
|
||||
RECUR_WEEKLY,
|
||||
RECUR_MONTHLY,
|
||||
RECUR_YEARLY,
|
||||
RECUR_TYPES
|
||||
};
|
||||
|
||||
/* To describe an item's repetition. */
|
||||
struct rpt {
|
||||
enum recur_type type; /* repetition type */
|
||||
int freq; /* repetition frequence */
|
||||
long until; /* ending date for repeated event */
|
||||
enum recur_type type; /* repetition type */
|
||||
int freq; /* repetition frequence */
|
||||
long until; /* ending date for repeated event */
|
||||
};
|
||||
|
||||
/* Recurrent appointment definition. */
|
||||
struct recur_apoint {
|
||||
struct rpt *rpt; /* information about repetition */
|
||||
llist_t exc; /* days when the item should not be repeated */
|
||||
long start; /* beggining of the appointment */
|
||||
long dur; /* duration of the appointment */
|
||||
char state; /* 8 bits to store item state */
|
||||
char *mesg; /* appointment description */
|
||||
char *note; /* note attached to appointment */
|
||||
struct rpt *rpt; /* information about repetition */
|
||||
llist_t exc; /* days when the item should not be repeated */
|
||||
long start; /* beggining of the appointment */
|
||||
long dur; /* duration of the appointment */
|
||||
char state; /* 8 bits to store item state */
|
||||
char *mesg; /* appointment description */
|
||||
char *note; /* note attached to appointment */
|
||||
};
|
||||
|
||||
/* Reccurent event definition. */
|
||||
struct recur_event {
|
||||
struct rpt *rpt; /* information about repetition */
|
||||
llist_t exc; /* days when the item should not be repeated */
|
||||
int id; /* event type */
|
||||
long day; /* day at which event occurs */
|
||||
char *mesg; /* event description */
|
||||
char *note; /* note attached to event */
|
||||
struct rpt *rpt; /* information about repetition */
|
||||
llist_t exc; /* days when the item should not be repeated */
|
||||
int id; /* event type */
|
||||
long day; /* day at which event occurs */
|
||||
char *mesg; /* event description */
|
||||
char *note; /* note attached to event */
|
||||
};
|
||||
|
||||
/* Generic pointer data type for appointments and events. */
|
||||
union aptev_ptr {
|
||||
struct apoint *apt;
|
||||
struct event *ev;
|
||||
struct recur_apoint *rapt;
|
||||
struct recur_event *rev;
|
||||
struct apoint *apt;
|
||||
struct event *ev;
|
||||
struct recur_apoint *rapt;
|
||||
struct recur_event *rev;
|
||||
};
|
||||
|
||||
/* Generic item description (to hold appointments, events...). */
|
||||
struct day_item {
|
||||
int type; /* (recursive or normal) event or appointment */
|
||||
long start; /* start time of the repetition occurrence */
|
||||
union aptev_ptr item; /* pointer to the actual item */
|
||||
int type; /* (recursive or normal) event or appointment */
|
||||
long start; /* start time of the repetition occurrence */
|
||||
union aptev_ptr item; /* pointer to the actual item */
|
||||
};
|
||||
|
||||
/* Available view for the calendar panel. */
|
||||
enum {
|
||||
CAL_MONTH_VIEW,
|
||||
CAL_WEEK_VIEW,
|
||||
CAL_VIEWS
|
||||
CAL_MONTH_VIEW,
|
||||
CAL_WEEK_VIEW,
|
||||
CAL_VIEWS
|
||||
};
|
||||
|
||||
struct notify_app {
|
||||
long time;
|
||||
int got_app;
|
||||
char *txt;
|
||||
char state;
|
||||
pthread_mutex_t mutex;
|
||||
long time;
|
||||
int got_app;
|
||||
char *txt;
|
||||
char state;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
struct io_file {
|
||||
FILE *fd;
|
||||
char name[BUFSIZ];
|
||||
FILE *fd;
|
||||
char name[BUFSIZ];
|
||||
};
|
||||
|
||||
/* Available keys. */
|
||||
enum key {
|
||||
KEY_GENERIC_CANCEL,
|
||||
KEY_GENERIC_SELECT,
|
||||
KEY_GENERIC_CREDITS,
|
||||
KEY_GENERIC_HELP,
|
||||
KEY_GENERIC_QUIT,
|
||||
KEY_GENERIC_SAVE,
|
||||
KEY_GENERIC_COPY,
|
||||
KEY_GENERIC_PASTE,
|
||||
KEY_GENERIC_CHANGE_VIEW,
|
||||
KEY_GENERIC_IMPORT,
|
||||
KEY_GENERIC_EXPORT,
|
||||
KEY_GENERIC_GOTO,
|
||||
KEY_GENERIC_OTHER_CMD,
|
||||
KEY_GENERIC_CONFIG_MENU,
|
||||
KEY_GENERIC_REDRAW,
|
||||
KEY_GENERIC_ADD_APPT,
|
||||
KEY_GENERIC_ADD_TODO,
|
||||
KEY_GENERIC_PREV_DAY,
|
||||
KEY_GENERIC_NEXT_DAY,
|
||||
KEY_GENERIC_PREV_WEEK,
|
||||
KEY_GENERIC_NEXT_WEEK,
|
||||
KEY_GENERIC_PREV_MONTH,
|
||||
KEY_GENERIC_NEXT_MONTH,
|
||||
KEY_GENERIC_PREV_YEAR,
|
||||
KEY_GENERIC_NEXT_YEAR,
|
||||
KEY_GENERIC_SCROLL_DOWN,
|
||||
KEY_GENERIC_SCROLL_UP,
|
||||
KEY_GENERIC_GOTO_TODAY,
|
||||
KEY_GENERIC_CANCEL,
|
||||
KEY_GENERIC_SELECT,
|
||||
KEY_GENERIC_CREDITS,
|
||||
KEY_GENERIC_HELP,
|
||||
KEY_GENERIC_QUIT,
|
||||
KEY_GENERIC_SAVE,
|
||||
KEY_GENERIC_COPY,
|
||||
KEY_GENERIC_PASTE,
|
||||
KEY_GENERIC_CHANGE_VIEW,
|
||||
KEY_GENERIC_IMPORT,
|
||||
KEY_GENERIC_EXPORT,
|
||||
KEY_GENERIC_GOTO,
|
||||
KEY_GENERIC_OTHER_CMD,
|
||||
KEY_GENERIC_CONFIG_MENU,
|
||||
KEY_GENERIC_REDRAW,
|
||||
KEY_GENERIC_ADD_APPT,
|
||||
KEY_GENERIC_ADD_TODO,
|
||||
KEY_GENERIC_PREV_DAY,
|
||||
KEY_GENERIC_NEXT_DAY,
|
||||
KEY_GENERIC_PREV_WEEK,
|
||||
KEY_GENERIC_NEXT_WEEK,
|
||||
KEY_GENERIC_PREV_MONTH,
|
||||
KEY_GENERIC_NEXT_MONTH,
|
||||
KEY_GENERIC_PREV_YEAR,
|
||||
KEY_GENERIC_NEXT_YEAR,
|
||||
KEY_GENERIC_SCROLL_DOWN,
|
||||
KEY_GENERIC_SCROLL_UP,
|
||||
KEY_GENERIC_GOTO_TODAY,
|
||||
|
||||
KEY_MOVE_RIGHT,
|
||||
KEY_MOVE_LEFT,
|
||||
KEY_MOVE_DOWN,
|
||||
KEY_MOVE_UP,
|
||||
KEY_START_OF_WEEK,
|
||||
KEY_END_OF_WEEK,
|
||||
KEY_ADD_ITEM,
|
||||
KEY_DEL_ITEM,
|
||||
KEY_EDIT_ITEM,
|
||||
KEY_VIEW_ITEM,
|
||||
KEY_PIPE_ITEM,
|
||||
KEY_FLAG_ITEM,
|
||||
KEY_REPEAT_ITEM,
|
||||
KEY_EDIT_NOTE,
|
||||
KEY_VIEW_NOTE,
|
||||
KEY_RAISE_PRIORITY,
|
||||
KEY_LOWER_PRIORITY,
|
||||
KEY_MOVE_RIGHT,
|
||||
KEY_MOVE_LEFT,
|
||||
KEY_MOVE_DOWN,
|
||||
KEY_MOVE_UP,
|
||||
KEY_START_OF_WEEK,
|
||||
KEY_END_OF_WEEK,
|
||||
KEY_ADD_ITEM,
|
||||
KEY_DEL_ITEM,
|
||||
KEY_EDIT_ITEM,
|
||||
KEY_VIEW_ITEM,
|
||||
KEY_PIPE_ITEM,
|
||||
KEY_FLAG_ITEM,
|
||||
KEY_REPEAT_ITEM,
|
||||
KEY_EDIT_NOTE,
|
||||
KEY_VIEW_NOTE,
|
||||
KEY_RAISE_PRIORITY,
|
||||
KEY_LOWER_PRIORITY,
|
||||
|
||||
NBKEYS,
|
||||
KEY_UNDEF
|
||||
NBKEYS,
|
||||
KEY_UNDEF
|
||||
};
|
||||
|
||||
/* To describe a key binding. */
|
||||
struct binding {
|
||||
char *label;
|
||||
enum key action;
|
||||
char *label;
|
||||
enum key action;
|
||||
};
|
||||
|
||||
#define FLAG_CAL (1 << CAL)
|
||||
@ -485,122 +485,122 @@ struct binding {
|
||||
pthread_cleanup_pop(0);
|
||||
|
||||
enum ui_mode {
|
||||
UI_CURSES,
|
||||
UI_CMDLINE,
|
||||
UI_MODES
|
||||
UI_CURSES,
|
||||
UI_CMDLINE,
|
||||
UI_MODES
|
||||
};
|
||||
|
||||
/* Generic window structure. */
|
||||
struct window {
|
||||
WINDOW *p; /* pointer to window */
|
||||
unsigned w; /* width */
|
||||
unsigned h; /* height */
|
||||
int x; /* x position */
|
||||
int y; /* y position */
|
||||
WINDOW *p; /* pointer to window */
|
||||
unsigned w; /* width */
|
||||
unsigned h; /* height */
|
||||
int x; /* x position */
|
||||
int y; /* y position */
|
||||
};
|
||||
|
||||
/* Generic scrolling window structure. */
|
||||
struct scrollwin {
|
||||
struct window win;
|
||||
struct window pad;
|
||||
unsigned first_visible_line;
|
||||
unsigned total_lines;
|
||||
const char *label;
|
||||
struct window win;
|
||||
struct window pad;
|
||||
unsigned first_visible_line;
|
||||
unsigned total_lines;
|
||||
const char *label;
|
||||
};
|
||||
|
||||
/* Pad structure to handle scrolling. */
|
||||
struct pad {
|
||||
int width;
|
||||
int length;
|
||||
int first_onscreen; /* first line to be displayed inside window */
|
||||
WINDOW *ptrwin; /* pointer to the pad window */
|
||||
int width;
|
||||
int length;
|
||||
int first_onscreen; /* first line to be displayed inside window */
|
||||
WINDOW *ptrwin; /* pointer to the pad window */
|
||||
};
|
||||
|
||||
/* Notification bar definition. */
|
||||
struct nbar {
|
||||
unsigned show; /* display or hide the notify-bar */
|
||||
int cntdwn; /* warn when time left before next app
|
||||
becomes lesser than cntdwn */
|
||||
char datefmt[BUFSIZ]; /* format for displaying date */
|
||||
char timefmt[BUFSIZ]; /* format for displaying time */
|
||||
char cmd[BUFSIZ]; /* notification command */
|
||||
const char *shell; /* user shell to launch notif. cmd */
|
||||
unsigned notify_all; /* notify all appointments */
|
||||
pthread_mutex_t mutex;
|
||||
unsigned show; /* display or hide the notify-bar */
|
||||
int cntdwn; /* warn when time left before next app
|
||||
becomes lesser than cntdwn */
|
||||
char datefmt[BUFSIZ]; /* format for displaying date */
|
||||
char timefmt[BUFSIZ]; /* format for displaying time */
|
||||
char cmd[BUFSIZ]; /* notification command */
|
||||
const char *shell; /* user shell to launch notif. cmd */
|
||||
unsigned notify_all; /* notify all appointments */
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
/* Available types of items. */
|
||||
enum item_type {
|
||||
RECUR_EVNT = 1,
|
||||
EVNT,
|
||||
RECUR_APPT,
|
||||
APPT,
|
||||
MAX_TYPES = APPT
|
||||
RECUR_EVNT = 1,
|
||||
EVNT,
|
||||
RECUR_APPT,
|
||||
APPT,
|
||||
MAX_TYPES = APPT
|
||||
};
|
||||
|
||||
/* Return codes for the getstring() function. */
|
||||
enum getstr {
|
||||
GETSTRING_VALID,
|
||||
GETSTRING_ESC, /* user pressed escape to cancel editing. */
|
||||
GETSTRING_RET /* return was pressed without entering any text. */
|
||||
GETSTRING_VALID,
|
||||
GETSTRING_ESC, /* user pressed escape to cancel editing. */
|
||||
GETSTRING_RET /* return was pressed without entering any text. */
|
||||
};
|
||||
|
||||
/* Week days. */
|
||||
enum wday {
|
||||
SUNDAY,
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY,
|
||||
WDAYS
|
||||
SUNDAY,
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY,
|
||||
WDAYS
|
||||
};
|
||||
|
||||
/* Possible movements inside calendar. */
|
||||
enum move {
|
||||
DAY_PREV,
|
||||
DAY_NEXT,
|
||||
WEEK_PREV,
|
||||
WEEK_NEXT,
|
||||
WEEK_START,
|
||||
WEEK_END,
|
||||
MONTH_PREV,
|
||||
MONTH_NEXT,
|
||||
YEAR_PREV,
|
||||
YEAR_NEXT
|
||||
DAY_PREV,
|
||||
DAY_NEXT,
|
||||
WEEK_PREV,
|
||||
WEEK_NEXT,
|
||||
WEEK_START,
|
||||
WEEK_END,
|
||||
MONTH_PREV,
|
||||
MONTH_NEXT,
|
||||
YEAR_PREV,
|
||||
YEAR_NEXT
|
||||
};
|
||||
|
||||
/* Available color pairs. */
|
||||
enum {
|
||||
COLR_RED = 1,
|
||||
COLR_GREEN,
|
||||
COLR_YELLOW,
|
||||
COLR_BLUE,
|
||||
COLR_MAGENTA,
|
||||
COLR_CYAN,
|
||||
COLR_DEFAULT,
|
||||
COLR_HIGH,
|
||||
COLR_CUSTOM
|
||||
COLR_RED = 1,
|
||||
COLR_GREEN,
|
||||
COLR_YELLOW,
|
||||
COLR_BLUE,
|
||||
COLR_MAGENTA,
|
||||
COLR_CYAN,
|
||||
COLR_DEFAULT,
|
||||
COLR_HIGH,
|
||||
COLR_CUSTOM
|
||||
};
|
||||
|
||||
/* Available import types. */
|
||||
enum import_type {
|
||||
IO_IMPORT_ICAL,
|
||||
IO_IMPORT_NBTYPES
|
||||
IO_IMPORT_ICAL,
|
||||
IO_IMPORT_NBTYPES
|
||||
};
|
||||
|
||||
/* Available export types. */
|
||||
enum export_type {
|
||||
IO_EXPORT_ICAL,
|
||||
IO_EXPORT_PCAL,
|
||||
IO_EXPORT_NBTYPES
|
||||
IO_EXPORT_ICAL,
|
||||
IO_EXPORT_PCAL,
|
||||
IO_EXPORT_NBTYPES
|
||||
};
|
||||
|
||||
/* To customize the display when saving data. */
|
||||
enum save_display {
|
||||
IO_SAVE_DISPLAY_BAR,
|
||||
IO_SAVE_DISPLAY_NONE
|
||||
IO_SAVE_DISPLAY_BAR,
|
||||
IO_SAVE_DISPLAY_NONE
|
||||
};
|
||||
|
||||
/* apoint.c */
|
||||
@ -687,7 +687,7 @@ int day_store_items(long, unsigned *, unsigned *, regex_t *);
|
||||
struct day_items_nb day_process_storage(struct date *, unsigned);
|
||||
void day_write_pad(long, int, int, int);
|
||||
void day_write_stdout(long, const char *, const char *, const char *,
|
||||
const char *);
|
||||
const char *);
|
||||
void day_popup_item(struct day_item *);
|
||||
int day_check_if_item(struct date);
|
||||
unsigned day_chk_busy_slices(struct date, int, int *);
|
||||
@ -726,7 +726,7 @@ int updatestring(WINDOW *, char **, int, int);
|
||||
|
||||
/* ical.c */
|
||||
void ical_import_data(FILE *, FILE *, unsigned *, unsigned *, unsigned *,
|
||||
unsigned *, unsigned *);
|
||||
unsigned *, unsigned *);
|
||||
void ical_export_data(FILE *);
|
||||
|
||||
/* interaction.c */
|
||||
@ -789,7 +789,7 @@ const char *keys_action_firstkey(enum key);
|
||||
const char *keys_action_nkey(enum key, int);
|
||||
char *keys_action_allkeys(enum key);
|
||||
void keys_display_bindings_bar(WINDOW *, struct binding *[], int, int,
|
||||
int, struct binding *);
|
||||
int, struct binding *);
|
||||
void keys_popup_info(enum key);
|
||||
void keys_save_bindings(FILE *);
|
||||
int keys_check_missing_bindings(void);
|
||||
@ -875,23 +875,25 @@ void recur_apoint_llist_init(void);
|
||||
void recur_apoint_llist_free(void);
|
||||
void recur_event_llist_free(void);
|
||||
struct recur_apoint *recur_apoint_new(char *, char *, long, long, char,
|
||||
int, int, long, llist_t *);
|
||||
int, int, long, llist_t *);
|
||||
struct recur_event *recur_event_new(char *, char *, long, int, int, int,
|
||||
long, llist_t *);
|
||||
long, llist_t *);
|
||||
char recur_def2char(enum recur_type);
|
||||
int recur_char2def(char);
|
||||
struct recur_apoint *recur_apoint_scan(FILE *, struct tm, struct tm,
|
||||
char, int, struct tm, char *,
|
||||
llist_t *, char);
|
||||
char, int, struct tm, char *,
|
||||
llist_t *, char);
|
||||
struct recur_event *recur_event_scan(FILE *, struct tm, int, char,
|
||||
int, struct tm, char *, llist_t *);
|
||||
int, struct tm, char *, llist_t *);
|
||||
void recur_apoint_write(struct recur_apoint *, FILE *);
|
||||
void recur_event_write(struct recur_event *, FILE *);
|
||||
void recur_save_data(FILE *);
|
||||
unsigned recur_item_find_occurrence(long, long, llist_t *, int,
|
||||
int, long, long, unsigned *);
|
||||
unsigned recur_apoint_find_occurrence(struct recur_apoint *, long, unsigned *);
|
||||
unsigned recur_event_find_occurrence(struct recur_event *, long, unsigned *);
|
||||
int, long, long, unsigned *);
|
||||
unsigned recur_apoint_find_occurrence(struct recur_apoint *, long,
|
||||
unsigned *);
|
||||
unsigned recur_event_find_occurrence(struct recur_event *, long,
|
||||
unsigned *);
|
||||
unsigned recur_item_inday(long, long, llist_t *, int, int, long, long);
|
||||
unsigned recur_apoint_inday(struct recur_apoint *, long *);
|
||||
unsigned recur_event_inday(struct recur_event *, long *);
|
||||
@ -900,7 +902,8 @@ void recur_apoint_add_exc(struct recur_apoint *, long);
|
||||
void recur_event_erase(struct recur_event *);
|
||||
void recur_apoint_erase(struct recur_apoint *);
|
||||
void recur_exc_scan(llist_t *, FILE *);
|
||||
struct notify_app *recur_apoint_check_next(struct notify_app *, long, long);
|
||||
struct notify_app *recur_apoint_check_next(struct notify_app *, long,
|
||||
long);
|
||||
void recur_apoint_switch_notify(struct recur_apoint *);
|
||||
void recur_event_paste_item(struct recur_event *, long);
|
||||
void recur_apoint_paste_item(struct recur_apoint *, long);
|
||||
@ -975,7 +978,8 @@ void print_bool_option_incolor(WINDOW *, unsigned, int, int);
|
||||
const char *get_tempdir(void);
|
||||
char *new_tempfile(const char *, int);
|
||||
int check_date(unsigned, unsigned, unsigned);
|
||||
int parse_date(const char *, enum datefmt, int *, int *, int *, struct date *);
|
||||
int parse_date(const char *, enum datefmt, int *, int *, int *,
|
||||
struct date *);
|
||||
int check_time(unsigned, unsigned);
|
||||
int parse_time(const char *, unsigned *, unsigned *);
|
||||
int parse_duration(const char *, unsigned *);
|
||||
@ -987,7 +991,8 @@ int child_wait(int *, int *, int);
|
||||
void press_any_key(void);
|
||||
void print_apoint(const char *, long, struct apoint *);
|
||||
void print_event(const char *, long, struct event *);
|
||||
void print_recur_apoint(const char *, long, unsigned, struct recur_apoint *);
|
||||
void print_recur_apoint(const char *, long, unsigned,
|
||||
struct recur_apoint *);
|
||||
void print_recur_event(const char *, long, struct recur_event *);
|
||||
void print_todo(const char *, struct todo *);
|
||||
|
||||
|
678
src/config.c
678
src/config.c
@ -43,10 +43,10 @@ typedef int (*config_fn_parse_t) (void *, const char *);
|
||||
typedef int (*config_fn_serialize_t) (char *, void *);
|
||||
|
||||
struct confvar {
|
||||
const char *key;
|
||||
config_fn_parse_t fn_parse;
|
||||
config_fn_serialize_t fn_serialize;
|
||||
void *target;
|
||||
const char *key;
|
||||
config_fn_parse_t fn_parse;
|
||||
config_fn_serialize_t fn_serialize;
|
||||
void *target;
|
||||
};
|
||||
|
||||
static int config_parse_bool(unsigned *, const char *);
|
||||
@ -84,42 +84,35 @@ static int config_serialize_input_datefmt(char *, void *);
|
||||
(config_fn_serialize_t) config_serialize_str, &(var)
|
||||
|
||||
static const struct confvar confmap[] = {
|
||||
{"appearance.calendarview", config_parse_calendar_view,
|
||||
config_serialize_calendar_view, NULL},
|
||||
{"appearance.compactpanels", CONFIG_HANDLER_BOOL(conf.compact_panels)},
|
||||
{"appearance.defaultpanel", config_parse_default_panel,
|
||||
config_serialize_default_panel, NULL},
|
||||
{"appearance.layout", config_parse_layout, config_serialize_layout, NULL},
|
||||
{"appearance.notifybar", CONFIG_HANDLER_BOOL(nbar.show)},
|
||||
{"appearance.sidebarwidth", config_parse_sidebar_width,
|
||||
config_serialize_sidebar_width, NULL},
|
||||
{"appearance.theme", config_parse_color_theme, config_serialize_color_theme,
|
||||
NULL},
|
||||
{"daemon.enable", CONFIG_HANDLER_BOOL(dmon.enable)},
|
||||
{"daemon.log", CONFIG_HANDLER_BOOL(dmon.log)},
|
||||
{"format.inputdate", config_parse_input_datefmt,
|
||||
config_serialize_input_datefmt, NULL},
|
||||
{"format.notifydate", CONFIG_HANDLER_STR(nbar.datefmt)},
|
||||
{"format.notifytime", CONFIG_HANDLER_STR(nbar.timefmt)},
|
||||
{"format.outputdate", config_parse_output_datefmt,
|
||||
config_serialize_output_datefmt, NULL},
|
||||
{"general.autogc", CONFIG_HANDLER_BOOL(conf.auto_gc)},
|
||||
{"general.autosave", CONFIG_HANDLER_BOOL(conf.auto_save)},
|
||||
{"general.confirmdelete", CONFIG_HANDLER_BOOL(conf.confirm_delete)},
|
||||
{"general.confirmquit", CONFIG_HANDLER_BOOL(conf.confirm_quit)},
|
||||
{"general.firstdayofweek", config_parse_first_day_of_week,
|
||||
config_serialize_first_day_of_week, NULL},
|
||||
{"general.periodicsave", CONFIG_HANDLER_UNSIGNED(conf.periodic_save)},
|
||||
{"general.progressbar", CONFIG_HANDLER_BOOL(conf.progress_bar)},
|
||||
{"general.systemdialogs", CONFIG_HANDLER_BOOL(conf.system_dialogs)},
|
||||
{"notification.command", CONFIG_HANDLER_STR(nbar.cmd)},
|
||||
{"notification.notifyall", CONFIG_HANDLER_BOOL(nbar.notify_all)},
|
||||
{"notification.warning", CONFIG_HANDLER_INT(nbar.cntdwn)}
|
||||
{"appearance.calendarview", config_parse_calendar_view, config_serialize_calendar_view, NULL},
|
||||
{"appearance.compactpanels", CONFIG_HANDLER_BOOL(conf.compact_panels)},
|
||||
{"appearance.defaultpanel", config_parse_default_panel, config_serialize_default_panel, NULL},
|
||||
{"appearance.layout", config_parse_layout, config_serialize_layout, NULL},
|
||||
{"appearance.notifybar", CONFIG_HANDLER_BOOL(nbar.show)},
|
||||
{"appearance.sidebarwidth", config_parse_sidebar_width, config_serialize_sidebar_width, NULL},
|
||||
{"appearance.theme", config_parse_color_theme, config_serialize_color_theme, NULL},
|
||||
{"daemon.enable", CONFIG_HANDLER_BOOL(dmon.enable)},
|
||||
{"daemon.log", CONFIG_HANDLER_BOOL(dmon.log)},
|
||||
{"format.inputdate", config_parse_input_datefmt, config_serialize_input_datefmt, NULL},
|
||||
{"format.notifydate", CONFIG_HANDLER_STR(nbar.datefmt)},
|
||||
{"format.notifytime", CONFIG_HANDLER_STR(nbar.timefmt)},
|
||||
{"format.outputdate", config_parse_output_datefmt, config_serialize_output_datefmt, NULL},
|
||||
{"general.autogc", CONFIG_HANDLER_BOOL(conf.auto_gc)},
|
||||
{"general.autosave", CONFIG_HANDLER_BOOL(conf.auto_save)},
|
||||
{"general.confirmdelete", CONFIG_HANDLER_BOOL(conf.confirm_delete)},
|
||||
{"general.confirmquit", CONFIG_HANDLER_BOOL(conf.confirm_quit)},
|
||||
{"general.firstdayofweek", config_parse_first_day_of_week, config_serialize_first_day_of_week, NULL},
|
||||
{"general.periodicsave", CONFIG_HANDLER_UNSIGNED(conf.periodic_save)},
|
||||
{"general.progressbar", CONFIG_HANDLER_BOOL(conf.progress_bar)},
|
||||
{"general.systemdialogs", CONFIG_HANDLER_BOOL(conf.system_dialogs)},
|
||||
{"notification.command", CONFIG_HANDLER_STR(nbar.cmd)},
|
||||
{"notification.notifyall", CONFIG_HANDLER_BOOL(nbar.notify_all)},
|
||||
{"notification.warning", CONFIG_HANDLER_INT(nbar.cntdwn)}
|
||||
};
|
||||
|
||||
struct config_save_status {
|
||||
FILE *fp;
|
||||
int done[sizeof(confmap) / sizeof(confmap[0])];
|
||||
FILE *fp;
|
||||
int done[sizeof(confmap) / sizeof(confmap[0])];
|
||||
};
|
||||
|
||||
typedef int (*config_fn_walk_cb_t) (const char *, const char *, void *);
|
||||
@ -127,207 +120,211 @@ typedef int (*config_fn_walk_junk_cb_t) (const char *, void *);
|
||||
|
||||
static int config_parse_bool(unsigned *dest, const char *val)
|
||||
{
|
||||
if (strcmp(val, "yes") == 0)
|
||||
*dest = 1;
|
||||
else if (strcmp(val, "no") == 0)
|
||||
*dest = 0;
|
||||
else
|
||||
return 0;
|
||||
if (strcmp(val, "yes") == 0)
|
||||
*dest = 1;
|
||||
else if (strcmp(val, "no") == 0)
|
||||
*dest = 0;
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_unsigned(unsigned *dest, const char *val)
|
||||
{
|
||||
if (is_all_digit(val))
|
||||
*dest = atoi(val);
|
||||
else
|
||||
return 0;
|
||||
if (is_all_digit(val))
|
||||
*dest = atoi(val);
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_int(int *dest, const char *val)
|
||||
{
|
||||
if ((*val == '+' || *val == '-' || isdigit(*val)) && is_all_digit(val + 1))
|
||||
*dest = atoi(val);
|
||||
else
|
||||
return 0;
|
||||
if ((*val == '+' || *val == '-' || isdigit(*val))
|
||||
&& is_all_digit(val + 1))
|
||||
*dest = atoi(val);
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_str(char *dest, const char *val)
|
||||
{
|
||||
strncpy(dest, val, BUFSIZ);
|
||||
return 1;
|
||||
strncpy(dest, val, BUFSIZ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_color(int *dest, const char *val)
|
||||
{
|
||||
if (!strcmp(val, "black"))
|
||||
*dest = COLOR_BLACK;
|
||||
else if (!strcmp(val, "red"))
|
||||
*dest = COLOR_RED;
|
||||
else if (!strcmp(val, "green"))
|
||||
*dest = COLOR_GREEN;
|
||||
else if (!strcmp(val, "yellow"))
|
||||
*dest = COLOR_YELLOW;
|
||||
else if (!strcmp(val, "blue"))
|
||||
*dest = COLOR_BLUE;
|
||||
else if (!strcmp(val, "magenta"))
|
||||
*dest = COLOR_MAGENTA;
|
||||
else if (!strcmp(val, "cyan"))
|
||||
*dest = COLOR_CYAN;
|
||||
else if (!strcmp(val, "white"))
|
||||
*dest = COLOR_WHITE;
|
||||
else if (!strcmp(val, "default"))
|
||||
*dest = background;
|
||||
else
|
||||
return 0;
|
||||
if (!strcmp(val, "black"))
|
||||
*dest = COLOR_BLACK;
|
||||
else if (!strcmp(val, "red"))
|
||||
*dest = COLOR_RED;
|
||||
else if (!strcmp(val, "green"))
|
||||
*dest = COLOR_GREEN;
|
||||
else if (!strcmp(val, "yellow"))
|
||||
*dest = COLOR_YELLOW;
|
||||
else if (!strcmp(val, "blue"))
|
||||
*dest = COLOR_BLUE;
|
||||
else if (!strcmp(val, "magenta"))
|
||||
*dest = COLOR_MAGENTA;
|
||||
else if (!strcmp(val, "cyan"))
|
||||
*dest = COLOR_CYAN;
|
||||
else if (!strcmp(val, "white"))
|
||||
*dest = COLOR_WHITE;
|
||||
else if (!strcmp(val, "default"))
|
||||
*dest = background;
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_color_pair(int *dest1, int *dest2, const char *val)
|
||||
{
|
||||
char s1[BUFSIZ], s2[BUFSIZ];
|
||||
char s1[BUFSIZ], s2[BUFSIZ];
|
||||
|
||||
if (sscanf(val, "%s on %s", s1, s2) != 2)
|
||||
return 0;
|
||||
if (sscanf(val, "%s on %s", s1, s2) != 2)
|
||||
return 0;
|
||||
|
||||
return (config_parse_color(dest1, s1) && config_parse_color(dest2, s2));
|
||||
return (config_parse_color(dest1, s1)
|
||||
&& config_parse_color(dest2, s2));
|
||||
}
|
||||
|
||||
static int config_parse_calendar_view(void *dummy, const char *val)
|
||||
{
|
||||
if (!strcmp(val, "monthly"))
|
||||
ui_calendar_set_view(CAL_MONTH_VIEW);
|
||||
else if (!strcmp(val, "weekly"))
|
||||
ui_calendar_set_view(CAL_WEEK_VIEW);
|
||||
else
|
||||
return 0;
|
||||
if (!strcmp(val, "monthly"))
|
||||
ui_calendar_set_view(CAL_MONTH_VIEW);
|
||||
else if (!strcmp(val, "weekly"))
|
||||
ui_calendar_set_view(CAL_WEEK_VIEW);
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_default_panel(void *dummy, const char *val)
|
||||
{
|
||||
if (!strcmp(val, "calendar"))
|
||||
conf.default_panel = CAL;
|
||||
else if (!strcmp(val, "appointments"))
|
||||
conf.default_panel = APP;
|
||||
else if (!strcmp(val, "todo"))
|
||||
conf.default_panel = TOD;
|
||||
else
|
||||
return 0;
|
||||
if (!strcmp(val, "calendar"))
|
||||
conf.default_panel = CAL;
|
||||
else if (!strcmp(val, "appointments"))
|
||||
conf.default_panel = APP;
|
||||
else if (!strcmp(val, "todo"))
|
||||
conf.default_panel = TOD;
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_first_day_of_week(void *dummy, const char *val)
|
||||
{
|
||||
if (!strcmp(val, "monday"))
|
||||
ui_calendar_set_first_day_of_week(MONDAY);
|
||||
else if (!strcmp(val, "sunday"))
|
||||
ui_calendar_set_first_day_of_week(SUNDAY);
|
||||
else
|
||||
return 0;
|
||||
if (!strcmp(val, "monday"))
|
||||
ui_calendar_set_first_day_of_week(MONDAY);
|
||||
else if (!strcmp(val, "sunday"))
|
||||
ui_calendar_set_first_day_of_week(SUNDAY);
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_color_theme(void *dummy, const char *val)
|
||||
{
|
||||
int color1, color2;
|
||||
if (!strcmp(val, "0") || !strcmp(val, "none")) {
|
||||
colorize = 0;
|
||||
return 1;
|
||||
}
|
||||
if (!config_parse_color_pair(&color1, &color2, val))
|
||||
return 0;
|
||||
init_pair(COLR_CUSTOM, color1, color2);
|
||||
return 1;
|
||||
int color1, color2;
|
||||
if (!strcmp(val, "0") || !strcmp(val, "none")) {
|
||||
colorize = 0;
|
||||
return 1;
|
||||
}
|
||||
if (!config_parse_color_pair(&color1, &color2, val))
|
||||
return 0;
|
||||
init_pair(COLR_CUSTOM, color1, color2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_layout(void *dummy, const char *val)
|
||||
{
|
||||
wins_set_layout(atoi(val));
|
||||
return 1;
|
||||
wins_set_layout(atoi(val));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_sidebar_width(void *dummy, const char *val)
|
||||
{
|
||||
wins_set_sbar_width(atoi(val));
|
||||
return 1;
|
||||
wins_set_sbar_width(atoi(val));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_output_datefmt(void *dummy, const char *val)
|
||||
{
|
||||
if (val[0] != '\0')
|
||||
return config_parse_str(conf.output_datefmt, val);
|
||||
return 1;
|
||||
if (val[0] != '\0')
|
||||
return config_parse_str(conf.output_datefmt, val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_input_datefmt(void *dummy, const char *val)
|
||||
{
|
||||
if (config_parse_int(&conf.input_datefmt, val)) {
|
||||
if (conf.input_datefmt <= 0 || conf.input_datefmt > DATE_FORMATS)
|
||||
conf.input_datefmt = 1;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
if (config_parse_int(&conf.input_datefmt, val)) {
|
||||
if (conf.input_datefmt <= 0
|
||||
|| conf.input_datefmt > DATE_FORMATS)
|
||||
conf.input_datefmt = 1;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set a configuration variable. */
|
||||
static int config_set_conf(const char *key, const char *value)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (!key)
|
||||
return -1;
|
||||
if (!key)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
|
||||
if (!strcmp(confmap[i].key, key))
|
||||
return confmap[i].fn_parse(confmap[i].target, value);
|
||||
}
|
||||
for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
|
||||
if (!strcmp(confmap[i].key, key))
|
||||
return confmap[i].fn_parse(confmap[i].target,
|
||||
value);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int config_serialize_bool(char *dest, unsigned *val)
|
||||
{
|
||||
if (*val) {
|
||||
dest[0] = 'y';
|
||||
dest[1] = 'e';
|
||||
dest[2] = 's';
|
||||
dest[3] = '\0';
|
||||
} else {
|
||||
dest[0] = 'n';
|
||||
dest[1] = 'o';
|
||||
dest[2] = '\0';
|
||||
}
|
||||
if (*val) {
|
||||
dest[0] = 'y';
|
||||
dest[1] = 'e';
|
||||
dest[2] = 's';
|
||||
dest[3] = '\0';
|
||||
} else {
|
||||
dest[0] = 'n';
|
||||
dest[1] = 'o';
|
||||
dest[2] = '\0';
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_serialize_unsigned(char *dest, unsigned *val)
|
||||
{
|
||||
snprintf(dest, BUFSIZ, "%u", *val);
|
||||
return 1;
|
||||
snprintf(dest, BUFSIZ, "%u", *val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_serialize_int(char *dest, int *val)
|
||||
{
|
||||
snprintf(dest, BUFSIZ, "%d", *val);
|
||||
return 1;
|
||||
snprintf(dest, BUFSIZ, "%d", *val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_serialize_str(char *dest, const char *val)
|
||||
{
|
||||
strncpy(dest, val, BUFSIZ);
|
||||
return 1;
|
||||
strncpy(dest, val, BUFSIZ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -345,281 +342,290 @@ static void config_color_theme_name(char *theme_name)
|
||||
#define DEFAULTCOLOR 255
|
||||
#define DEFAULTCOLOR_EXT -1
|
||||
|
||||
int i;
|
||||
short color[NBCOLORS];
|
||||
const char *color_name[NBCOLORS];
|
||||
const char *default_color = "default";
|
||||
const char *name[MAXCOLORS] = {
|
||||
"black",
|
||||
"red",
|
||||
"green",
|
||||
"yellow",
|
||||
"blue",
|
||||
"magenta",
|
||||
"cyan",
|
||||
"white"
|
||||
};
|
||||
int i;
|
||||
short color[NBCOLORS];
|
||||
const char *color_name[NBCOLORS];
|
||||
const char *default_color = "default";
|
||||
const char *name[MAXCOLORS] = {
|
||||
"black",
|
||||
"red",
|
||||
"green",
|
||||
"yellow",
|
||||
"blue",
|
||||
"magenta",
|
||||
"cyan",
|
||||
"white"
|
||||
};
|
||||
|
||||
if (!colorize) {
|
||||
strncpy(theme_name, "none", BUFSIZ);
|
||||
} else {
|
||||
pair_content(COLR_CUSTOM, &color[0], &color[1]);
|
||||
for (i = 0; i < NBCOLORS; i++) {
|
||||
if ((color[i] == DEFAULTCOLOR) || (color[i] == DEFAULTCOLOR_EXT)) {
|
||||
color_name[i] = default_color;
|
||||
} else if (color[i] >= 0 && color[i] <= MAXCOLORS) {
|
||||
color_name[i] = name[color[i]];
|
||||
} else {
|
||||
EXIT(_("unknown color"));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
snprintf(theme_name, BUFSIZ, "%s on %s", color_name[0], color_name[1]);
|
||||
}
|
||||
if (!colorize) {
|
||||
strncpy(theme_name, "none", BUFSIZ);
|
||||
} else {
|
||||
pair_content(COLR_CUSTOM, &color[0], &color[1]);
|
||||
for (i = 0; i < NBCOLORS; i++) {
|
||||
if ((color[i] == DEFAULTCOLOR)
|
||||
|| (color[i] == DEFAULTCOLOR_EXT)) {
|
||||
color_name[i] = default_color;
|
||||
} else if (color[i] >= 0 && color[i] <= MAXCOLORS) {
|
||||
color_name[i] = name[color[i]];
|
||||
} else {
|
||||
EXIT(_("unknown color"));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
snprintf(theme_name, BUFSIZ, "%s on %s", color_name[0],
|
||||
color_name[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static int config_serialize_calendar_view(char *buf, void *dummy)
|
||||
{
|
||||
if (ui_calendar_get_view() == CAL_WEEK_VIEW)
|
||||
strcpy(buf, "weekly");
|
||||
else
|
||||
strcpy(buf, "monthly");
|
||||
if (ui_calendar_get_view() == CAL_WEEK_VIEW)
|
||||
strcpy(buf, "weekly");
|
||||
else
|
||||
strcpy(buf, "monthly");
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_serialize_default_panel(char *buf, void *dummy)
|
||||
{
|
||||
if (conf.default_panel == CAL)
|
||||
strcpy(buf, "calendar");
|
||||
else if (conf.default_panel == APP)
|
||||
strcpy(buf, "appointments");
|
||||
else
|
||||
strcpy(buf, "todo");
|
||||
if (conf.default_panel == CAL)
|
||||
strcpy(buf, "calendar");
|
||||
else if (conf.default_panel == APP)
|
||||
strcpy(buf, "appointments");
|
||||
else
|
||||
strcpy(buf, "todo");
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_serialize_first_day_of_week(char *buf, void *dummy)
|
||||
{
|
||||
if (ui_calendar_week_begins_on_monday())
|
||||
strcpy(buf, "monday");
|
||||
else
|
||||
strcpy(buf, "sunday");
|
||||
if (ui_calendar_week_begins_on_monday())
|
||||
strcpy(buf, "monday");
|
||||
else
|
||||
strcpy(buf, "sunday");
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_serialize_color_theme(char *buf, void *dummy)
|
||||
{
|
||||
config_color_theme_name(buf);
|
||||
return 1;
|
||||
config_color_theme_name(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_serialize_layout(char *buf, void *dummy)
|
||||
{
|
||||
int tmp = wins_layout();
|
||||
return config_serialize_int(buf, &tmp);
|
||||
int tmp = wins_layout();
|
||||
return config_serialize_int(buf, &tmp);
|
||||
}
|
||||
|
||||
static int config_serialize_sidebar_width(char *buf, void *dummy)
|
||||
{
|
||||
int tmp = wins_sbar_wperc();
|
||||
return config_serialize_int(buf, &tmp);
|
||||
int tmp = wins_sbar_wperc();
|
||||
return config_serialize_int(buf, &tmp);
|
||||
}
|
||||
|
||||
static int config_serialize_output_datefmt(char *buf, void *dummy)
|
||||
{
|
||||
return config_serialize_str(buf, conf.output_datefmt);
|
||||
return config_serialize_str(buf, conf.output_datefmt);
|
||||
}
|
||||
|
||||
static int config_serialize_input_datefmt(char *buf, void *dummy)
|
||||
{
|
||||
return config_serialize_int(buf, &conf.input_datefmt);
|
||||
return config_serialize_int(buf, &conf.input_datefmt);
|
||||
}
|
||||
|
||||
/* Serialize the value of a configuration variable. */
|
||||
static int
|
||||
config_serialize_conf(char *buf, const char *key,
|
||||
struct config_save_status *status)
|
||||
struct config_save_status *status)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (!key)
|
||||
return -1;
|
||||
if (!key)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
|
||||
if (!strcmp(confmap[i].key, key)) {
|
||||
if (confmap[i].fn_serialize(buf, confmap[i].target)) {
|
||||
if (status)
|
||||
status->done[i] = 1;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
|
||||
if (!strcmp(confmap[i].key, key)) {
|
||||
if (confmap[i].
|
||||
fn_serialize(buf, confmap[i].target)) {
|
||||
if (status)
|
||||
status->done[i] = 1;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
config_file_walk(config_fn_walk_cb_t fn_cb,
|
||||
config_fn_walk_junk_cb_t fn_junk_cb, void *data)
|
||||
config_fn_walk_junk_cb_t fn_junk_cb, void *data)
|
||||
{
|
||||
FILE *data_file;
|
||||
char buf[BUFSIZ], e_conf[BUFSIZ];
|
||||
char *key, *value;
|
||||
FILE *data_file;
|
||||
char buf[BUFSIZ], e_conf[BUFSIZ];
|
||||
char *key, *value;
|
||||
|
||||
data_file = fopen(path_conf, "r");
|
||||
EXIT_IF(data_file == NULL, _("failed to open configuration file"));
|
||||
data_file = fopen(path_conf, "r");
|
||||
EXIT_IF(data_file == NULL, _("failed to open configuration file"));
|
||||
|
||||
pthread_mutex_lock(&nbar.mutex);
|
||||
for (;;) {
|
||||
if (fgets(buf, sizeof buf, data_file) == NULL)
|
||||
break;
|
||||
io_extract_data(e_conf, buf, sizeof buf);
|
||||
pthread_mutex_lock(&nbar.mutex);
|
||||
for (;;) {
|
||||
if (fgets(buf, sizeof buf, data_file) == NULL)
|
||||
break;
|
||||
io_extract_data(e_conf, buf, sizeof buf);
|
||||
|
||||
if (*e_conf == '\0') {
|
||||
if (fn_junk_cb)
|
||||
fn_junk_cb(buf, data);
|
||||
continue;
|
||||
}
|
||||
if (*e_conf == '\0') {
|
||||
if (fn_junk_cb)
|
||||
fn_junk_cb(buf, data);
|
||||
continue;
|
||||
}
|
||||
|
||||
key = e_conf;
|
||||
value = strchr(e_conf, '=');
|
||||
if (value) {
|
||||
*value = '\0';
|
||||
value++;
|
||||
} else {
|
||||
EXIT(_("invalid configuration directive: \"%s\""), e_conf);
|
||||
}
|
||||
key = e_conf;
|
||||
value = strchr(e_conf, '=');
|
||||
if (value) {
|
||||
*value = '\0';
|
||||
value++;
|
||||
} else {
|
||||
EXIT(_("invalid configuration directive: \"%s\""),
|
||||
e_conf);
|
||||
}
|
||||
|
||||
if (strcmp(key, "auto_save") == 0 ||
|
||||
strcmp(key, "auto_gc") == 0 ||
|
||||
strcmp(key, "periodic_save") == 0 ||
|
||||
strcmp(key, "confirm_quit") == 0 ||
|
||||
strcmp(key, "confirm_delete") == 0 ||
|
||||
strcmp(key, "skip_system_dialogs") == 0 ||
|
||||
strcmp(key, "skip_progress_bar") == 0 ||
|
||||
strcmp(key, "calendar_default_view") == 0 ||
|
||||
strcmp(key, "week_begins_on_monday") == 0 ||
|
||||
strcmp(key, "color-theme") == 0 ||
|
||||
strcmp(key, "layout") == 0 ||
|
||||
strcmp(key, "side-bar_width") == 0 ||
|
||||
strcmp(key, "notify-bar_show") == 0 ||
|
||||
strcmp(key, "notify-bar_date") == 0 ||
|
||||
strcmp(key, "notify-bar_clock") == 0 ||
|
||||
strcmp(key, "notify-bar_warning") == 0 ||
|
||||
strcmp(key, "notify-bar_command") == 0 ||
|
||||
strcmp(key, "notify-all") == 0 ||
|
||||
strcmp(key, "output_datefmt") == 0 ||
|
||||
strcmp(key, "input_datefmt") == 0 ||
|
||||
strcmp(key, "notify-daemon_enable") == 0 ||
|
||||
strcmp(key, "notify-daemon_log") == 0) {
|
||||
WARN_MSG(_("Pre-3.0.0 configuration file format detected, "
|
||||
"please upgrade running `calcurse-upgrade`."));
|
||||
}
|
||||
if (strcmp(key, "auto_save") == 0 ||
|
||||
strcmp(key, "auto_gc") == 0 ||
|
||||
strcmp(key, "periodic_save") == 0 ||
|
||||
strcmp(key, "confirm_quit") == 0 ||
|
||||
strcmp(key, "confirm_delete") == 0 ||
|
||||
strcmp(key, "skip_system_dialogs") == 0 ||
|
||||
strcmp(key, "skip_progress_bar") == 0 ||
|
||||
strcmp(key, "calendar_default_view") == 0 ||
|
||||
strcmp(key, "week_begins_on_monday") == 0 ||
|
||||
strcmp(key, "color-theme") == 0 ||
|
||||
strcmp(key, "layout") == 0 ||
|
||||
strcmp(key, "side-bar_width") == 0 ||
|
||||
strcmp(key, "notify-bar_show") == 0 ||
|
||||
strcmp(key, "notify-bar_date") == 0 ||
|
||||
strcmp(key, "notify-bar_clock") == 0 ||
|
||||
strcmp(key, "notify-bar_warning") == 0 ||
|
||||
strcmp(key, "notify-bar_command") == 0 ||
|
||||
strcmp(key, "notify-all") == 0 ||
|
||||
strcmp(key, "output_datefmt") == 0 ||
|
||||
strcmp(key, "input_datefmt") == 0 ||
|
||||
strcmp(key, "notify-daemon_enable") == 0 ||
|
||||
strcmp(key, "notify-daemon_log") == 0) {
|
||||
WARN_MSG(_("Pre-3.0.0 configuration file format detected, "
|
||||
"please upgrade running `calcurse-upgrade`."));
|
||||
}
|
||||
|
||||
if (value && (*value == '\0' || *value == '\n')) {
|
||||
/* Backward compatibility mode. */
|
||||
if (fgets(buf, sizeof buf, data_file) == NULL)
|
||||
break;
|
||||
io_extract_data(e_conf, buf, sizeof buf);
|
||||
value = e_conf;
|
||||
}
|
||||
if (value && (*value == '\0' || *value == '\n')) {
|
||||
/* Backward compatibility mode. */
|
||||
if (fgets(buf, sizeof buf, data_file) == NULL)
|
||||
break;
|
||||
io_extract_data(e_conf, buf, sizeof buf);
|
||||
value = e_conf;
|
||||
}
|
||||
|
||||
fn_cb(key, value, data);
|
||||
}
|
||||
file_close(data_file, __FILE_POS__);
|
||||
pthread_mutex_unlock(&nbar.mutex);
|
||||
fn_cb(key, value, data);
|
||||
}
|
||||
file_close(data_file, __FILE_POS__);
|
||||
pthread_mutex_unlock(&nbar.mutex);
|
||||
}
|
||||
|
||||
static int config_load_cb(const char *key, const char *value, void *dummy)
|
||||
{
|
||||
int result = config_set_conf(key, value);
|
||||
int result = config_set_conf(key, value);
|
||||
|
||||
if (result < 0) {
|
||||
EXIT(_("configuration variable unknown: \"%s\""), key);
|
||||
/* NOTREACHED */
|
||||
} else if (result == 0) {
|
||||
EXIT(_("wrong configuration variable format for \"%s\""), key);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (result < 0) {
|
||||
EXIT(_("configuration variable unknown: \"%s\""), key);
|
||||
/* NOTREACHED */
|
||||
} else if (result == 0) {
|
||||
EXIT(_("wrong configuration variable format for \"%s\""),
|
||||
key);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load the user configuration. */
|
||||
void config_load(void)
|
||||
{
|
||||
config_file_walk(config_load_cb, NULL, NULL);
|
||||
config_file_walk(config_load_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
static int config_save_cb(const char *key, const char *value, void *status)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
int result =
|
||||
config_serialize_conf(buf, key, (struct config_save_status *)status);
|
||||
char buf[BUFSIZ];
|
||||
int result =
|
||||
config_serialize_conf(buf, key,
|
||||
(struct config_save_status *)status);
|
||||
|
||||
if (result < 0) {
|
||||
EXIT(_("configuration variable unknown: \"%s\""), key);
|
||||
/* NOTREACHED */
|
||||
} else if (result == 0) {
|
||||
EXIT(_("wrong configuration variable format for \"%s\""), key);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (result < 0) {
|
||||
EXIT(_("configuration variable unknown: \"%s\""), key);
|
||||
/* NOTREACHED */
|
||||
} else if (result == 0) {
|
||||
EXIT(_("wrong configuration variable format for \"%s\""),
|
||||
key);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
fputs(key, ((struct config_save_status *)status)->fp);
|
||||
fputc('=', ((struct config_save_status *)status)->fp);
|
||||
fputs(buf, ((struct config_save_status *)status)->fp);
|
||||
fputc('\n', ((struct config_save_status *)status)->fp);
|
||||
fputs(key, ((struct config_save_status *)status)->fp);
|
||||
fputc('=', ((struct config_save_status *)status)->fp);
|
||||
fputs(buf, ((struct config_save_status *)status)->fp);
|
||||
fputc('\n', ((struct config_save_status *)status)->fp);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_save_junk_cb(const char *data, void *status)
|
||||
{
|
||||
fputs(data, ((struct config_save_status *)status)->fp);
|
||||
return 1;
|
||||
fputs(data, ((struct config_save_status *)status)->fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Save the user configuration. */
|
||||
unsigned config_save(void)
|
||||
{
|
||||
char tmppath[BUFSIZ];
|
||||
char *tmpext;
|
||||
struct config_save_status status;
|
||||
int i;
|
||||
char tmppath[BUFSIZ];
|
||||
char *tmpext;
|
||||
struct config_save_status status;
|
||||
int i;
|
||||
|
||||
if (read_only)
|
||||
return 1;
|
||||
if (read_only)
|
||||
return 1;
|
||||
|
||||
strncpy(tmppath, get_tempdir(), BUFSIZ);
|
||||
strncat(tmppath, "/" CONF_PATH_NAME ".", BUFSIZ - strlen(tmppath) - 1);
|
||||
if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
|
||||
return 0;
|
||||
strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
|
||||
mem_free(tmpext);
|
||||
strncpy(tmppath, get_tempdir(), BUFSIZ);
|
||||
strncat(tmppath, "/" CONF_PATH_NAME ".",
|
||||
BUFSIZ - strlen(tmppath) - 1);
|
||||
if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
|
||||
return 0;
|
||||
strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
|
||||
mem_free(tmpext);
|
||||
|
||||
status.fp = fopen(tmppath, "w");
|
||||
if (!status.fp)
|
||||
return 0;
|
||||
status.fp = fopen(tmppath, "w");
|
||||
if (!status.fp)
|
||||
return 0;
|
||||
|
||||
memset(status.done, 0, sizeof(status.done));
|
||||
memset(status.done, 0, sizeof(status.done));
|
||||
|
||||
config_file_walk(config_save_cb, config_save_junk_cb, (void *)&status);
|
||||
config_file_walk(config_save_cb, config_save_junk_cb,
|
||||
(void *)&status);
|
||||
|
||||
/* Set variables that were missing from the configuration file. */
|
||||
for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
|
||||
if (!status.done[i])
|
||||
config_save_cb(confmap[i].key, NULL, &status);
|
||||
}
|
||||
/* Set variables that were missing from the configuration file. */
|
||||
for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
|
||||
if (!status.done[i])
|
||||
config_save_cb(confmap[i].key, NULL, &status);
|
||||
}
|
||||
|
||||
file_close(status.fp, __FILE_POS__);
|
||||
file_close(status.fp, __FILE_POS__);
|
||||
|
||||
if (io_file_cp(tmppath, path_conf))
|
||||
unlink(tmppath);
|
||||
if (io_file_cp(tmppath, path_conf))
|
||||
unlink(tmppath);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
1743
src/custom.c
1743
src/custom.c
File diff suppressed because it is too large
Load Diff
205
src/dmon.c
205
src/dmon.c
@ -66,124 +66,130 @@ static unsigned data_loaded;
|
||||
|
||||
static void dmon_sigs_hdlr(int sig)
|
||||
{
|
||||
if (data_loaded)
|
||||
free_user_data();
|
||||
if (data_loaded)
|
||||
free_user_data();
|
||||
|
||||
DMON_LOG(_("terminated at %s with signal %d\n"), nowstr(), sig);
|
||||
DMON_LOG(_("terminated at %s with signal %d\n"), nowstr(), sig);
|
||||
|
||||
if (unlink(path_dpid) != 0) {
|
||||
DMON_LOG(_("Could not remove daemon lock file: %s\n"), strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (unlink(path_dpid) != 0) {
|
||||
DMON_LOG(_("Could not remove daemon lock file: %s\n"),
|
||||
strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static unsigned daemonize(int status)
|
||||
{
|
||||
int fd;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Operate in the background: Daemonizing.
|
||||
*
|
||||
* First need to fork in order to become a child of the init process,
|
||||
* once the father exits.
|
||||
*/
|
||||
switch (fork()) {
|
||||
case -1: /* fork error */
|
||||
EXIT(_("Could not fork: %s\n"), strerror(errno));
|
||||
break;
|
||||
case 0: /* child */
|
||||
break;
|
||||
default: /* parent */
|
||||
exit(status);
|
||||
}
|
||||
/*
|
||||
* Operate in the background: Daemonizing.
|
||||
*
|
||||
* First need to fork in order to become a child of the init process,
|
||||
* once the father exits.
|
||||
*/
|
||||
switch (fork()) {
|
||||
case -1: /* fork error */
|
||||
EXIT(_("Could not fork: %s\n"), strerror(errno));
|
||||
break;
|
||||
case 0: /* child */
|
||||
break;
|
||||
default: /* parent */
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process independency.
|
||||
*
|
||||
* Obtain a new process group and session in order to get detached from the
|
||||
* controlling terminal.
|
||||
*/
|
||||
if (setsid() == -1) {
|
||||
DMON_LOG(_("Could not detach from the controlling terminal: %s\n"),
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Process independency.
|
||||
*
|
||||
* Obtain a new process group and session in order to get detached from the
|
||||
* controlling terminal.
|
||||
*/
|
||||
if (setsid() == -1) {
|
||||
DMON_LOG(_("Could not detach from the controlling terminal: %s\n"),
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change working directory to root directory,
|
||||
* to prevent filesystem unmounts.
|
||||
*/
|
||||
if (chdir("/") == -1) {
|
||||
DMON_LOG(_("Could not change working directory: %s\n"), strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Change working directory to root directory,
|
||||
* to prevent filesystem unmounts.
|
||||
*/
|
||||
if (chdir("/") == -1) {
|
||||
DMON_LOG(_("Could not change working directory: %s\n"),
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Redirect standard file descriptors to /dev/null. */
|
||||
if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
|
||||
dup2(fd, STDIN_FILENO);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
if (fd > 2)
|
||||
close(fd);
|
||||
}
|
||||
/* Redirect standard file descriptors to /dev/null. */
|
||||
if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
|
||||
dup2(fd, STDIN_FILENO);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
if (fd > 2)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* Write access for the owner only. */
|
||||
umask(0022);
|
||||
/* Write access for the owner only. */
|
||||
umask(0022);
|
||||
|
||||
if (!sigs_set_hdlr(SIGINT, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGTERM, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGALRM, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGQUIT, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGCHLD, SIG_IGN))
|
||||
return 0;
|
||||
if (!sigs_set_hdlr(SIGINT, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGTERM, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGALRM, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGQUIT, dmon_sigs_hdlr)
|
||||
|| !sigs_set_hdlr(SIGCHLD, SIG_IGN))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void dmon_start(int parent_exit_status)
|
||||
{
|
||||
if (!daemonize(parent_exit_status))
|
||||
DMON_ABRT(_("Cannot daemonize, aborting\n"));
|
||||
if (!daemonize(parent_exit_status))
|
||||
DMON_ABRT(_("Cannot daemonize, aborting\n"));
|
||||
|
||||
if (!io_dump_pid(path_dpid))
|
||||
DMON_ABRT(_("Could not set lock file\n"));
|
||||
if (!io_dump_pid(path_dpid))
|
||||
DMON_ABRT(_("Could not set lock file\n"));
|
||||
|
||||
if (!io_file_exist(path_conf))
|
||||
DMON_ABRT(_("Could not access \"%s\": %s\n"), path_conf, strerror(errno));
|
||||
config_load();
|
||||
if (!io_file_exist(path_conf))
|
||||
DMON_ABRT(_("Could not access \"%s\": %s\n"), path_conf,
|
||||
strerror(errno));
|
||||
config_load();
|
||||
|
||||
if (!io_file_exist(path_apts))
|
||||
DMON_ABRT(_("Could not access \"%s\": %s\n"), path_apts, strerror(errno));
|
||||
apoint_llist_init();
|
||||
recur_apoint_llist_init();
|
||||
event_llist_init();
|
||||
todo_init_list();
|
||||
io_load_app();
|
||||
data_loaded = 1;
|
||||
if (!io_file_exist(path_apts))
|
||||
DMON_ABRT(_("Could not access \"%s\": %s\n"), path_apts,
|
||||
strerror(errno));
|
||||
apoint_llist_init();
|
||||
recur_apoint_llist_init();
|
||||
event_llist_init();
|
||||
todo_init_list();
|
||||
io_load_app();
|
||||
data_loaded = 1;
|
||||
|
||||
DMON_LOG(_("started at %s\n"), nowstr());
|
||||
for (;;) {
|
||||
int left;
|
||||
DMON_LOG(_("started at %s\n"), nowstr());
|
||||
for (;;) {
|
||||
int left;
|
||||
|
||||
if (!notify_get_next_bkgd())
|
||||
DMON_ABRT(_("error loading next appointment\n"));
|
||||
if (!notify_get_next_bkgd())
|
||||
DMON_ABRT(_("error loading next appointment\n"));
|
||||
|
||||
left = notify_time_left();
|
||||
if (left > 0 && left < nbar.cntdwn && notify_needs_reminder()) {
|
||||
DMON_LOG(_("launching notification at %s for: \"%s\"\n"),
|
||||
nowstr(), notify_app_txt());
|
||||
if (!notify_launch_cmd())
|
||||
DMON_LOG(_("error while sending notification\n"));
|
||||
}
|
||||
left = notify_time_left();
|
||||
if (left > 0 && left < nbar.cntdwn
|
||||
&& notify_needs_reminder()) {
|
||||
DMON_LOG(_("launching notification at %s for: \"%s\"\n"),
|
||||
nowstr(), notify_app_txt());
|
||||
if (!notify_launch_cmd())
|
||||
DMON_LOG(_("error while sending notification\n"));
|
||||
}
|
||||
|
||||
DMON_LOG(ngettext("sleeping at %s for %d second\n",
|
||||
"sleeping at %s for %d seconds\n",
|
||||
DMON_SLEEP_TIME), nowstr(), DMON_SLEEP_TIME);
|
||||
psleep(DMON_SLEEP_TIME);
|
||||
DMON_LOG(_("awakened at %s\n"), nowstr());
|
||||
}
|
||||
DMON_LOG(ngettext("sleeping at %s for %d second\n",
|
||||
"sleeping at %s for %d seconds\n",
|
||||
DMON_SLEEP_TIME), nowstr(),
|
||||
DMON_SLEEP_TIME);
|
||||
psleep(DMON_SLEEP_TIME);
|
||||
DMON_LOG(_("awakened at %s\n"), nowstr());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -192,12 +198,13 @@ void dmon_start(int parent_exit_status)
|
||||
*/
|
||||
void dmon_stop(void)
|
||||
{
|
||||
int dpid;
|
||||
int dpid;
|
||||
|
||||
dpid = io_get_pid(path_dpid);
|
||||
if (!dpid)
|
||||
return;
|
||||
dpid = io_get_pid(path_dpid);
|
||||
if (!dpid)
|
||||
return;
|
||||
|
||||
if (kill((pid_t) dpid, SIGINT) < 0 && errno != ESRCH)
|
||||
EXIT(_("Could not stop calcurse daemon: %s\n"), strerror(errno));
|
||||
if (kill((pid_t) dpid, SIGINT) < 0 && errno != ESRCH)
|
||||
EXIT(_("Could not stop calcurse daemon: %s\n"),
|
||||
strerror(errno));
|
||||
}
|
||||
|
124
src/event.c
124
src/event.c
@ -45,124 +45,124 @@ llist_t eventlist;
|
||||
|
||||
void event_free(struct event *ev)
|
||||
{
|
||||
mem_free(ev->mesg);
|
||||
erase_note(&ev->note);
|
||||
mem_free(ev);
|
||||
mem_free(ev->mesg);
|
||||
erase_note(&ev->note);
|
||||
mem_free(ev);
|
||||
}
|
||||
|
||||
struct event *event_dup(struct event *in)
|
||||
{
|
||||
EXIT_IF(!in, _("null pointer"));
|
||||
EXIT_IF(!in, _("null pointer"));
|
||||
|
||||
struct event *ev = mem_malloc(sizeof(struct event));
|
||||
ev->id = in->id;
|
||||
ev->day = in->day;
|
||||
ev->mesg = mem_strdup(in->mesg);
|
||||
if (in->note)
|
||||
ev->note = mem_strdup(in->note);
|
||||
else
|
||||
ev->note = NULL;
|
||||
struct event *ev = mem_malloc(sizeof(struct event));
|
||||
ev->id = in->id;
|
||||
ev->day = in->day;
|
||||
ev->mesg = mem_strdup(in->mesg);
|
||||
if (in->note)
|
||||
ev->note = mem_strdup(in->note);
|
||||
else
|
||||
ev->note = NULL;
|
||||
|
||||
return ev;
|
||||
return ev;
|
||||
}
|
||||
|
||||
void event_llist_init(void)
|
||||
{
|
||||
LLIST_INIT(&eventlist);
|
||||
LLIST_INIT(&eventlist);
|
||||
}
|
||||
|
||||
void event_llist_free(void)
|
||||
{
|
||||
LLIST_FREE_INNER(&eventlist, event_free);
|
||||
LLIST_FREE(&eventlist);
|
||||
LLIST_FREE_INNER(&eventlist, event_free);
|
||||
LLIST_FREE(&eventlist);
|
||||
}
|
||||
|
||||
static int event_cmp_day(struct event *a, struct event *b)
|
||||
{
|
||||
return a->day < b->day ? -1 : (a->day == b->day ? 0 : 1);
|
||||
return a->day < b->day ? -1 : (a->day == b->day ? 0 : 1);
|
||||
}
|
||||
|
||||
/* Create a new event */
|
||||
struct event *event_new(char *mesg, char *note, long day, int id)
|
||||
{
|
||||
struct event *ev;
|
||||
struct event *ev;
|
||||
|
||||
ev = mem_malloc(sizeof(struct event));
|
||||
ev->mesg = mem_strdup(mesg);
|
||||
ev->day = day;
|
||||
ev->id = id;
|
||||
ev->note = (note != NULL) ? mem_strdup(note) : NULL;
|
||||
ev = mem_malloc(sizeof(struct event));
|
||||
ev->mesg = mem_strdup(mesg);
|
||||
ev->day = day;
|
||||
ev->id = id;
|
||||
ev->note = (note != NULL) ? mem_strdup(note) : NULL;
|
||||
|
||||
LLIST_ADD_SORTED(&eventlist, ev, event_cmp_day);
|
||||
LLIST_ADD_SORTED(&eventlist, ev, event_cmp_day);
|
||||
|
||||
return ev;
|
||||
return ev;
|
||||
}
|
||||
|
||||
/* Check if the event belongs to the selected day */
|
||||
unsigned event_inday(struct event *i, long *start)
|
||||
{
|
||||
return (i->day < *start + DAYINSEC && i->day >= *start);
|
||||
return (i->day < *start + DAYINSEC && i->day >= *start);
|
||||
}
|
||||
|
||||
/* Write to file the event in user-friendly format */
|
||||
void event_write(struct event *o, FILE * f)
|
||||
{
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
|
||||
t = o->day;
|
||||
localtime_r(&t, <);
|
||||
fprintf(f, "%02u/%02u/%04u [%d] ", lt.tm_mon + 1, lt.tm_mday,
|
||||
1900 + lt.tm_year, o->id);
|
||||
if (o->note != NULL)
|
||||
fprintf(f, ">%s ", o->note);
|
||||
fprintf(f, "%s\n", o->mesg);
|
||||
t = o->day;
|
||||
localtime_r(&t, <);
|
||||
fprintf(f, "%02u/%02u/%04u [%d] ", lt.tm_mon + 1, lt.tm_mday,
|
||||
1900 + lt.tm_year, o->id);
|
||||
if (o->note != NULL)
|
||||
fprintf(f, ">%s ", o->note);
|
||||
fprintf(f, "%s\n", o->mesg);
|
||||
}
|
||||
|
||||
/* Load the events from file */
|
||||
struct event *event_scan(FILE * f, struct tm start, int id, char *note)
|
||||
{
|
||||
char buf[BUFSIZ], *nl;
|
||||
time_t tstart;
|
||||
char buf[BUFSIZ], *nl;
|
||||
time_t tstart;
|
||||
|
||||
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
|
||||
!check_time(start.tm_hour, start.tm_min),
|
||||
_("date error in event"));
|
||||
EXIT_IF(!check_date(start.tm_year, start.tm_mon, start.tm_mday) ||
|
||||
!check_time(start.tm_hour, start.tm_min),
|
||||
_("date error in event"));
|
||||
|
||||
/* Read the event description */
|
||||
if (!fgets(buf, sizeof buf, f))
|
||||
return NULL;
|
||||
/* Read the event description */
|
||||
if (!fgets(buf, sizeof buf, f))
|
||||
return NULL;
|
||||
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl) {
|
||||
*nl = '\0';
|
||||
}
|
||||
start.tm_hour = 0;
|
||||
start.tm_min = 0;
|
||||
start.tm_sec = 0;
|
||||
start.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl) {
|
||||
*nl = '\0';
|
||||
}
|
||||
start.tm_hour = 0;
|
||||
start.tm_min = 0;
|
||||
start.tm_sec = 0;
|
||||
start.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
|
||||
tstart = mktime(&start);
|
||||
EXIT_IF(tstart == -1, _("date error in the event\n"));
|
||||
tstart = mktime(&start);
|
||||
EXIT_IF(tstart == -1, _("date error in the event\n"));
|
||||
|
||||
return event_new(buf, note, tstart, id);
|
||||
return event_new(buf, note, tstart, id);
|
||||
}
|
||||
|
||||
/* Delete an event from the list. */
|
||||
void event_delete(struct event *ev)
|
||||
{
|
||||
llist_item_t *i = LLIST_FIND_FIRST(&eventlist, ev, NULL);
|
||||
llist_item_t *i = LLIST_FIND_FIRST(&eventlist, ev, NULL);
|
||||
|
||||
if (!i)
|
||||
EXIT(_("no such appointment"));
|
||||
if (!i)
|
||||
EXIT(_("no such appointment"));
|
||||
|
||||
LLIST_REMOVE(&eventlist, i);
|
||||
LLIST_REMOVE(&eventlist, i);
|
||||
}
|
||||
|
||||
void event_paste_item(struct event *ev, long date)
|
||||
{
|
||||
ev->day = date;
|
||||
LLIST_ADD_SORTED(&eventlist, ev, event_cmp_day);
|
||||
ev->day = date;
|
||||
LLIST_ADD_SORTED(&eventlist, ev, event_cmp_day);
|
||||
}
|
||||
|
355
src/getstring.c
355
src/getstring.c
@ -37,126 +37,134 @@
|
||||
#include "calcurse.h"
|
||||
|
||||
struct getstr_charinfo {
|
||||
unsigned int offset, dpyoff;
|
||||
unsigned int offset, dpyoff;
|
||||
};
|
||||
|
||||
struct getstr_status {
|
||||
char *s;
|
||||
struct getstr_charinfo *ci;
|
||||
int pos, len;
|
||||
int scrpos;
|
||||
char *s;
|
||||
struct getstr_charinfo *ci;
|
||||
int pos, len;
|
||||
int scrpos;
|
||||
};
|
||||
|
||||
/* Print the string at the desired position. */
|
||||
static void getstr_print(WINDOW * win, int x, int y, struct getstr_status *st)
|
||||
static void getstr_print(WINDOW * win, int x, int y,
|
||||
struct getstr_status *st)
|
||||
{
|
||||
char c = 0;
|
||||
char c = 0;
|
||||
|
||||
/* print string */
|
||||
mvwaddnstr(win, y, x, &st->s[st->ci[st->scrpos].offset], -1);
|
||||
wclrtoeol(win);
|
||||
/* print string */
|
||||
mvwaddnstr(win, y, x, &st->s[st->ci[st->scrpos].offset], -1);
|
||||
wclrtoeol(win);
|
||||
|
||||
/* print scrolling indicator */
|
||||
if (st->scrpos > 0 && st->ci[st->len].dpyoff -
|
||||
st->ci[st->scrpos].dpyoff > col - 2)
|
||||
c = '*';
|
||||
else if (st->scrpos > 0)
|
||||
c = '<';
|
||||
else if (st->ci[st->len].dpyoff - st->ci[st->scrpos].dpyoff > col - 2)
|
||||
c = '>';
|
||||
mvwprintw(win, y, col - 2, " %c", c);
|
||||
/* print scrolling indicator */
|
||||
if (st->scrpos > 0 && st->ci[st->len].dpyoff -
|
||||
st->ci[st->scrpos].dpyoff > col - 2)
|
||||
c = '*';
|
||||
else if (st->scrpos > 0)
|
||||
c = '<';
|
||||
else if (st->ci[st->len].dpyoff - st->ci[st->scrpos].dpyoff >
|
||||
col - 2)
|
||||
c = '>';
|
||||
mvwprintw(win, y, col - 2, " %c", c);
|
||||
|
||||
/* print cursor */
|
||||
wmove(win, y, st->ci[st->pos].dpyoff - st->ci[st->scrpos].dpyoff);
|
||||
wchgat(win, 1, A_REVERSE, COLR_CUSTOM, NULL);
|
||||
/* print cursor */
|
||||
wmove(win, y, st->ci[st->pos].dpyoff - st->ci[st->scrpos].dpyoff);
|
||||
wchgat(win, 1, A_REVERSE, COLR_CUSTOM, NULL);
|
||||
}
|
||||
|
||||
/* Delete a character at the given position in string. */
|
||||
static void getstr_del_char(struct getstr_status *st)
|
||||
{
|
||||
char *str = st->s + st->ci[st->pos].offset;
|
||||
int cl = st->ci[st->pos + 1].offset - st->ci[st->pos].offset;
|
||||
int cw = st->ci[st->pos + 1].dpyoff - st->ci[st->pos].dpyoff;
|
||||
int i;
|
||||
char *str = st->s + st->ci[st->pos].offset;
|
||||
int cl = st->ci[st->pos + 1].offset - st->ci[st->pos].offset;
|
||||
int cw = st->ci[st->pos + 1].dpyoff - st->ci[st->pos].dpyoff;
|
||||
int i;
|
||||
|
||||
memmove(str, str + cl, strlen(str) + 1);
|
||||
memmove(str, str + cl, strlen(str) + 1);
|
||||
|
||||
st->len--;
|
||||
for (i = st->pos; i <= st->len; i++) {
|
||||
st->ci[i].offset = st->ci[i + 1].offset - cl;
|
||||
st->ci[i].dpyoff = st->ci[i + 1].dpyoff - cw;
|
||||
}
|
||||
st->len--;
|
||||
for (i = st->pos; i <= st->len; i++) {
|
||||
st->ci[i].offset = st->ci[i + 1].offset - cl;
|
||||
st->ci[i].dpyoff = st->ci[i + 1].dpyoff - cw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a character at the given position in string. */
|
||||
static void getstr_ins_char(struct getstr_status *st, char *c)
|
||||
{
|
||||
char *str = st->s + st->ci[st->pos].offset;
|
||||
int cl = UTF8_LENGTH(c[0]);
|
||||
int cw = utf8_width(c);
|
||||
int i;
|
||||
char *str = st->s + st->ci[st->pos].offset;
|
||||
int cl = UTF8_LENGTH(c[0]);
|
||||
int cw = utf8_width(c);
|
||||
int i;
|
||||
|
||||
memmove(str + cl, str, strlen(str) + 1);
|
||||
for (i = 0; i < cl; i++, str++)
|
||||
*str = c[i];
|
||||
memmove(str + cl, str, strlen(str) + 1);
|
||||
for (i = 0; i < cl; i++, str++)
|
||||
*str = c[i];
|
||||
|
||||
for (i = st->len; i >= st->pos; i--) {
|
||||
st->ci[i + 1].offset = st->ci[i].offset + cl;
|
||||
st->ci[i + 1].dpyoff = st->ci[i].dpyoff + cw;
|
||||
}
|
||||
st->len++;
|
||||
for (i = st->len; i >= st->pos; i--) {
|
||||
st->ci[i + 1].offset = st->ci[i].offset + cl;
|
||||
st->ci[i + 1].dpyoff = st->ci[i].dpyoff + cw;
|
||||
}
|
||||
st->len++;
|
||||
}
|
||||
|
||||
static void bell(void)
|
||||
{
|
||||
putchar('\a');
|
||||
putchar('\a');
|
||||
}
|
||||
|
||||
/* Initialize getstring data structure. */
|
||||
static void
|
||||
getstr_init(struct getstr_status *st, char *str, struct getstr_charinfo *ci)
|
||||
getstr_init(struct getstr_status *st, char *str,
|
||||
struct getstr_charinfo *ci)
|
||||
{
|
||||
int width;
|
||||
int width;
|
||||
|
||||
st->s = str;
|
||||
st->ci = ci;
|
||||
st->s = str;
|
||||
st->ci = ci;
|
||||
|
||||
st->len = width = 0;
|
||||
while (*str) {
|
||||
st->ci[st->len].offset = str - st->s;
|
||||
st->ci[st->len].dpyoff = width;
|
||||
st->len = width = 0;
|
||||
while (*str) {
|
||||
st->ci[st->len].offset = str - st->s;
|
||||
st->ci[st->len].dpyoff = width;
|
||||
|
||||
st->len++;
|
||||
width += utf8_width(str);
|
||||
str += UTF8_LENGTH(*str);
|
||||
}
|
||||
st->ci[st->len].offset = str - st->s;
|
||||
st->ci[st->len].dpyoff = width;
|
||||
st->len++;
|
||||
width += utf8_width(str);
|
||||
str += UTF8_LENGTH(*str);
|
||||
}
|
||||
st->ci[st->len].offset = str - st->s;
|
||||
st->ci[st->len].dpyoff = width;
|
||||
|
||||
st->pos = st->len;
|
||||
st->scrpos = 0;
|
||||
st->pos = st->len;
|
||||
st->scrpos = 0;
|
||||
}
|
||||
|
||||
/* Scroll left/right if the cursor moves outside the window range. */
|
||||
static void getstr_fixscr(struct getstr_status *st)
|
||||
{
|
||||
const int pgsize = col / 3;
|
||||
int pgskip;
|
||||
const int pgsize = col / 3;
|
||||
int pgskip;
|
||||
|
||||
while (st->pos < st->scrpos) {
|
||||
pgskip = 0;
|
||||
while (pgskip < pgsize && st->scrpos > 0) {
|
||||
st->scrpos--;
|
||||
pgskip += st->ci[st->scrpos + 1].dpyoff - st->ci[st->scrpos].dpyoff;
|
||||
}
|
||||
}
|
||||
while (st->ci[st->pos].dpyoff - st->ci[st->scrpos].dpyoff > col - 2) {
|
||||
pgskip = 0;
|
||||
while (pgskip < pgsize && st->scrpos < st->len) {
|
||||
pgskip += st->ci[st->scrpos + 1].dpyoff - st->ci[st->scrpos].dpyoff;
|
||||
st->scrpos++;
|
||||
}
|
||||
}
|
||||
while (st->pos < st->scrpos) {
|
||||
pgskip = 0;
|
||||
while (pgskip < pgsize && st->scrpos > 0) {
|
||||
st->scrpos--;
|
||||
pgskip +=
|
||||
st->ci[st->scrpos + 1].dpyoff -
|
||||
st->ci[st->scrpos].dpyoff;
|
||||
}
|
||||
}
|
||||
while (st->ci[st->pos].dpyoff - st->ci[st->scrpos].dpyoff >
|
||||
col - 2) {
|
||||
pgskip = 0;
|
||||
while (pgskip < pgsize && st->scrpos < st->len) {
|
||||
pgskip +=
|
||||
st->ci[st->scrpos + 1].dpyoff -
|
||||
st->ci[st->scrpos].dpyoff;
|
||||
st->scrpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -169,114 +177,119 @@ static void getstr_fixscr(struct getstr_status *st)
|
||||
*/
|
||||
enum getstr getstring(WINDOW * win, char *str, int l, int x, int y)
|
||||
{
|
||||
struct getstr_status st;
|
||||
struct getstr_charinfo ci[l + 1];
|
||||
struct getstr_status st;
|
||||
struct getstr_charinfo ci[l + 1];
|
||||
|
||||
int ch, k;
|
||||
char c[UTF8_MAXLEN];
|
||||
int ch, k;
|
||||
char c[UTF8_MAXLEN];
|
||||
|
||||
getstr_init(&st, str, ci);
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
getstr_init(&st, str, ci);
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
|
||||
for (;;) {
|
||||
getstr_fixscr(&st);
|
||||
getstr_print(win, x, y, &st);
|
||||
wins_doupdate();
|
||||
for (;;) {
|
||||
getstr_fixscr(&st);
|
||||
getstr_print(win, x, y, &st);
|
||||
wins_doupdate();
|
||||
|
||||
if ((ch = wgetch(win)) == '\n')
|
||||
break;
|
||||
switch (ch) {
|
||||
case KEY_BACKSPACE: /* delete one character */
|
||||
case 330:
|
||||
case 127:
|
||||
case CTRL('H'):
|
||||
if (st.pos > 0) {
|
||||
st.pos--;
|
||||
getstr_del_char(&st);
|
||||
} else {
|
||||
bell();
|
||||
}
|
||||
break;
|
||||
case CTRL('D'): /* delete next character */
|
||||
if (st.pos < st.len)
|
||||
getstr_del_char(&st);
|
||||
else
|
||||
bell();
|
||||
break;
|
||||
case CTRL('W'): /* delete a word */
|
||||
if (st.pos > 0) {
|
||||
while (st.pos && st.s[st.ci[st.pos - 1].offset] == ' ') {
|
||||
st.pos--;
|
||||
getstr_del_char(&st);
|
||||
}
|
||||
while (st.pos && st.s[st.ci[st.pos - 1].offset] != ' ') {
|
||||
st.pos--;
|
||||
getstr_del_char(&st);
|
||||
}
|
||||
} else {
|
||||
bell();
|
||||
}
|
||||
break;
|
||||
case CTRL('K'): /* delete to end-of-line */
|
||||
st.s[st.ci[st.pos].offset] = 0;
|
||||
st.len = st.pos;
|
||||
break;
|
||||
case CTRL('A'): /* go to begginning of string */
|
||||
st.pos = 0;
|
||||
break;
|
||||
case CTRL('E'): /* go to end of string */
|
||||
st.pos = st.len;
|
||||
break;
|
||||
case KEY_LEFT: /* move one char backward */
|
||||
case CTRL('B'):
|
||||
if (st.pos > 0)
|
||||
st.pos--;
|
||||
break;
|
||||
case KEY_RIGHT: /* move one char forward */
|
||||
case CTRL('F'):
|
||||
if (st.pos < st.len)
|
||||
st.pos++;
|
||||
break;
|
||||
case ESCAPE: /* cancel editing */
|
||||
return GETSTRING_ESC;
|
||||
break;
|
||||
default: /* insert one character */
|
||||
c[0] = ch;
|
||||
for (k = 1; k < MIN(UTF8_LENGTH(c[0]), UTF8_MAXLEN); k++)
|
||||
c[k] = (unsigned char)wgetch(win);
|
||||
if (st.ci[st.len].offset + k < l) {
|
||||
getstr_ins_char(&st, c);
|
||||
st.pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((ch = wgetch(win)) == '\n')
|
||||
break;
|
||||
switch (ch) {
|
||||
case KEY_BACKSPACE: /* delete one character */
|
||||
case 330:
|
||||
case 127:
|
||||
case CTRL('H'):
|
||||
if (st.pos > 0) {
|
||||
st.pos--;
|
||||
getstr_del_char(&st);
|
||||
} else {
|
||||
bell();
|
||||
}
|
||||
break;
|
||||
case CTRL('D'): /* delete next character */
|
||||
if (st.pos < st.len)
|
||||
getstr_del_char(&st);
|
||||
else
|
||||
bell();
|
||||
break;
|
||||
case CTRL('W'): /* delete a word */
|
||||
if (st.pos > 0) {
|
||||
while (st.pos
|
||||
&& st.s[st.ci[st.pos - 1].offset] ==
|
||||
' ') {
|
||||
st.pos--;
|
||||
getstr_del_char(&st);
|
||||
}
|
||||
while (st.pos
|
||||
&& st.s[st.ci[st.pos - 1].offset] !=
|
||||
' ') {
|
||||
st.pos--;
|
||||
getstr_del_char(&st);
|
||||
}
|
||||
} else {
|
||||
bell();
|
||||
}
|
||||
break;
|
||||
case CTRL('K'): /* delete to end-of-line */
|
||||
st.s[st.ci[st.pos].offset] = 0;
|
||||
st.len = st.pos;
|
||||
break;
|
||||
case CTRL('A'): /* go to begginning of string */
|
||||
st.pos = 0;
|
||||
break;
|
||||
case CTRL('E'): /* go to end of string */
|
||||
st.pos = st.len;
|
||||
break;
|
||||
case KEY_LEFT: /* move one char backward */
|
||||
case CTRL('B'):
|
||||
if (st.pos > 0)
|
||||
st.pos--;
|
||||
break;
|
||||
case KEY_RIGHT: /* move one char forward */
|
||||
case CTRL('F'):
|
||||
if (st.pos < st.len)
|
||||
st.pos++;
|
||||
break;
|
||||
case ESCAPE: /* cancel editing */
|
||||
return GETSTRING_ESC;
|
||||
break;
|
||||
default: /* insert one character */
|
||||
c[0] = ch;
|
||||
for (k = 1;
|
||||
k < MIN(UTF8_LENGTH(c[0]), UTF8_MAXLEN); k++)
|
||||
c[k] = (unsigned char)wgetch(win);
|
||||
if (st.ci[st.len].offset + k < l) {
|
||||
getstr_ins_char(&st, c);
|
||||
st.pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
|
||||
return st.len == 0 ? GETSTRING_RET : GETSTRING_VALID;
|
||||
return st.len == 0 ? GETSTRING_RET : GETSTRING_VALID;
|
||||
}
|
||||
|
||||
/* Update an already existing string. */
|
||||
int updatestring(WINDOW * win, char **str, int x, int y)
|
||||
{
|
||||
int len = strlen(*str);
|
||||
char *buf;
|
||||
enum getstr ret;
|
||||
int len = strlen(*str);
|
||||
char *buf;
|
||||
enum getstr ret;
|
||||
|
||||
EXIT_IF(len + 1 > BUFSIZ, _("Internal error: line too long"));
|
||||
EXIT_IF(len + 1 > BUFSIZ, _("Internal error: line too long"));
|
||||
|
||||
buf = mem_malloc(BUFSIZ);
|
||||
memcpy(buf, *str, len + 1);
|
||||
buf = mem_malloc(BUFSIZ);
|
||||
memcpy(buf, *str, len + 1);
|
||||
|
||||
ret = getstring(win, buf, BUFSIZ, x, y);
|
||||
ret = getstring(win, buf, BUFSIZ, x, y);
|
||||
|
||||
if (ret == GETSTRING_VALID) {
|
||||
len = strlen(buf);
|
||||
*str = mem_realloc(*str, len + 1, 1);
|
||||
EXIT_IF(*str == NULL, _("out of memory"));
|
||||
memcpy(*str, buf, len + 1);
|
||||
}
|
||||
if (ret == GETSTRING_VALID) {
|
||||
len = strlen(buf);
|
||||
*str = mem_realloc(*str, len + 1, 1);
|
||||
EXIT_IF(*str == NULL, _("out of memory"));
|
||||
memcpy(*str, buf, len + 1);
|
||||
}
|
||||
|
||||
mem_free(buf);
|
||||
return ret;
|
||||
mem_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
1297
src/help.c
1297
src/help.c
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,7 @@ struct name { \
|
||||
}
|
||||
|
||||
#define HTABLE_ENTRY(type) \
|
||||
struct type *next /* To build the bucket chain list. */
|
||||
struct type *next /* To build the bucket chain list. */
|
||||
|
||||
#define HTABLE_SIZE(head) \
|
||||
(sizeof (*(head)->bkts) ? sizeof ((head)->bkts) / sizeof (*(head)->bkts) : 0)
|
||||
|
1558
src/ical.c
1558
src/ical.c
File diff suppressed because it is too large
Load Diff
830
src/keys.c
830
src/keys.c
@ -39,406 +39,416 @@
|
||||
|
||||
#include "calcurse.h"
|
||||
|
||||
#define MAXKEYVAL KEY_MAX /* ncurses defines KEY_MAX as maximum key value */
|
||||
#define MAXKEYVAL KEY_MAX /* ncurses defines KEY_MAX as maximum key value */
|
||||
|
||||
struct keydef_s {
|
||||
const char *label;
|
||||
const char *binding;
|
||||
const char *label;
|
||||
const char *binding;
|
||||
};
|
||||
|
||||
static llist_t keys[NBKEYS];
|
||||
static enum key actions[MAXKEYVAL];
|
||||
|
||||
static struct keydef_s keydef[NBKEYS] = {
|
||||
{"generic-cancel", "ESC"},
|
||||
{"generic-select", "SPC"},
|
||||
{"generic-credits", "@"},
|
||||
{"generic-help", "?"},
|
||||
{"generic-quit", "q Q"},
|
||||
{"generic-save", "s S C-s"},
|
||||
{"generic-copy", "c"},
|
||||
{"generic-paste", "p C-v"},
|
||||
{"generic-change-view", "TAB"},
|
||||
{"generic-import", "i I"},
|
||||
{"generic-export", "x X"},
|
||||
{"generic-goto", "g G"},
|
||||
{"generic-other-cmd", "o O"},
|
||||
{"generic-config-menu", "C"},
|
||||
{"generic-redraw", "C-r"},
|
||||
{"generic-add-appt", "C-a"},
|
||||
{"generic-add-todo", "C-t"},
|
||||
{"generic-prev-day", "T C-h"},
|
||||
{"generic-next-day", "t C-l"},
|
||||
{"generic-prev-week", "W C-k"},
|
||||
{"generic-next-week", "w C-j"},
|
||||
{"generic-prev-month", "M"},
|
||||
{"generic-next-month", "m"},
|
||||
{"generic-prev-year", "Y"},
|
||||
{"generic-next-year", "y"},
|
||||
{"generic-scroll-down", "C-n"},
|
||||
{"generic-scroll-up", "C-p"},
|
||||
{"generic-goto-today", "C-g"},
|
||||
{"generic-cancel", "ESC"},
|
||||
{"generic-select", "SPC"},
|
||||
{"generic-credits", "@"},
|
||||
{"generic-help", "?"},
|
||||
{"generic-quit", "q Q"},
|
||||
{"generic-save", "s S C-s"},
|
||||
{"generic-copy", "c"},
|
||||
{"generic-paste", "p C-v"},
|
||||
{"generic-change-view", "TAB"},
|
||||
{"generic-import", "i I"},
|
||||
{"generic-export", "x X"},
|
||||
{"generic-goto", "g G"},
|
||||
{"generic-other-cmd", "o O"},
|
||||
{"generic-config-menu", "C"},
|
||||
{"generic-redraw", "C-r"},
|
||||
{"generic-add-appt", "C-a"},
|
||||
{"generic-add-todo", "C-t"},
|
||||
{"generic-prev-day", "T C-h"},
|
||||
{"generic-next-day", "t C-l"},
|
||||
{"generic-prev-week", "W C-k"},
|
||||
{"generic-next-week", "w C-j"},
|
||||
{"generic-prev-month", "M"},
|
||||
{"generic-next-month", "m"},
|
||||
{"generic-prev-year", "Y"},
|
||||
{"generic-next-year", "y"},
|
||||
{"generic-scroll-down", "C-n"},
|
||||
{"generic-scroll-up", "C-p"},
|
||||
{"generic-goto-today", "C-g"},
|
||||
|
||||
{"move-right", "l L RGT"},
|
||||
{"move-left", "h H LFT"},
|
||||
{"move-down", "j J DWN"},
|
||||
{"move-up", "k K UP"},
|
||||
{"start-of-week", "0"},
|
||||
{"end-of-week", "$"},
|
||||
{"add-item", "a A"},
|
||||
{"del-item", "d D"},
|
||||
{"edit-item", "e E"},
|
||||
{"view-item", "v V"},
|
||||
{"pipe-item", "|"},
|
||||
{"flag-item", "!"},
|
||||
{"repeat", "r R"},
|
||||
{"edit-note", "n N"},
|
||||
{"view-note", ">"},
|
||||
{"raise-priority", "+"},
|
||||
{"lower-priority", "-"},
|
||||
{"move-right", "l L RGT"},
|
||||
{"move-left", "h H LFT"},
|
||||
{"move-down", "j J DWN"},
|
||||
{"move-up", "k K UP"},
|
||||
{"start-of-week", "0"},
|
||||
{"end-of-week", "$"},
|
||||
{"add-item", "a A"},
|
||||
{"del-item", "d D"},
|
||||
{"edit-item", "e E"},
|
||||
{"view-item", "v V"},
|
||||
{"pipe-item", "|"},
|
||||
{"flag-item", "!"},
|
||||
{"repeat", "r R"},
|
||||
{"edit-note", "n N"},
|
||||
{"view-note", ">"},
|
||||
{"raise-priority", "+"},
|
||||
{"lower-priority", "-"},
|
||||
};
|
||||
|
||||
static void dump_intro(FILE * fd)
|
||||
{
|
||||
const char *intro =
|
||||
_("#\n"
|
||||
"# Calcurse keys configuration file\n#\n"
|
||||
"# This file sets the keybindings used by Calcurse.\n"
|
||||
"# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n"
|
||||
"# To assign a keybinding to an action, this file must contain a line\n"
|
||||
"# with the following syntax:\n#\n"
|
||||
"# ACTION KEY1 KEY2 ... KEYn\n#\n"
|
||||
"# Where ACTION is what will be performed when KEY1, KEY2, ..., or KEYn\n"
|
||||
"# will be pressed.\n"
|
||||
"#\n"
|
||||
"# To define bindings which use the CONTROL key, prefix the key with "
|
||||
"'C-'.\n"
|
||||
"# The escape, space bar and horizontal Tab key can be specified using\n"
|
||||
"# the 'ESC', 'SPC' and 'TAB' keyword, respectively.\n"
|
||||
"# Arrow keys can also be specified with the UP, DWN, LFT, RGT keywords.\n"
|
||||
"# Last, Home and End keys can be assigned using 'KEY_HOME' and 'KEY_END'\n"
|
||||
"# keywords."
|
||||
"\n#\n"
|
||||
"# A description of what each ACTION keyword is used for is available\n"
|
||||
"# from calcurse online configuration menu.\n");
|
||||
const char *intro =
|
||||
_("#\n"
|
||||
"# Calcurse keys configuration file\n#\n"
|
||||
"# This file sets the keybindings used by Calcurse.\n"
|
||||
"# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n"
|
||||
"# To assign a keybinding to an action, this file must contain a line\n"
|
||||
"# with the following syntax:\n#\n"
|
||||
"# ACTION KEY1 KEY2 ... KEYn\n#\n"
|
||||
"# Where ACTION is what will be performed when KEY1, KEY2, ..., or KEYn\n"
|
||||
"# will be pressed.\n"
|
||||
"#\n"
|
||||
"# To define bindings which use the CONTROL key, prefix the key with "
|
||||
"'C-'.\n"
|
||||
"# The escape, space bar and horizontal Tab key can be specified using\n"
|
||||
"# the 'ESC', 'SPC' and 'TAB' keyword, respectively.\n"
|
||||
"# Arrow keys can also be specified with the UP, DWN, LFT, RGT keywords.\n"
|
||||
"# Last, Home and End keys can be assigned using 'KEY_HOME' and 'KEY_END'\n"
|
||||
"# keywords."
|
||||
"\n#\n"
|
||||
"# A description of what each ACTION keyword is used for is available\n"
|
||||
"# from calcurse online configuration menu.\n");
|
||||
|
||||
fprintf(fd, "%s\n", intro);
|
||||
fprintf(fd, "%s\n", intro);
|
||||
}
|
||||
|
||||
void keys_init(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXKEYVAL; i++)
|
||||
actions[i] = KEY_UNDEF;
|
||||
for (i = 0; i < NBKEYS; i++)
|
||||
LLIST_INIT(&keys[i]);
|
||||
for (i = 0; i < MAXKEYVAL; i++)
|
||||
actions[i] = KEY_UNDEF;
|
||||
for (i = 0; i < NBKEYS; i++)
|
||||
LLIST_INIT(&keys[i]);
|
||||
}
|
||||
|
||||
static void key_free(char *s)
|
||||
{
|
||||
mem_free(s);
|
||||
mem_free(s);
|
||||
}
|
||||
|
||||
void keys_free(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
LLIST_FREE_INNER(&keys[i], key_free);
|
||||
LLIST_FREE(&keys[i]);
|
||||
}
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
LLIST_FREE_INNER(&keys[i], key_free);
|
||||
LLIST_FREE(&keys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void keys_dump_defaults(char *file)
|
||||
{
|
||||
FILE *fd;
|
||||
int i;
|
||||
FILE *fd;
|
||||
int i;
|
||||
|
||||
fd = fopen(file, "w");
|
||||
EXIT_IF(fd == NULL, _("FATAL ERROR: could not create default keys file."));
|
||||
fd = fopen(file, "w");
|
||||
EXIT_IF(fd == NULL,
|
||||
_("FATAL ERROR: could not create default keys file."));
|
||||
|
||||
dump_intro(fd);
|
||||
for (i = 0; i < NBKEYS; i++)
|
||||
fprintf(fd, "%s %s\n", keydef[i].label, keydef[i].binding);
|
||||
file_close(fd, __FILE_POS__);
|
||||
dump_intro(fd);
|
||||
for (i = 0; i < NBKEYS; i++)
|
||||
fprintf(fd, "%s %s\n", keydef[i].label,
|
||||
keydef[i].binding);
|
||||
file_close(fd, __FILE_POS__);
|
||||
}
|
||||
|
||||
const char *keys_get_label(enum key key)
|
||||
{
|
||||
EXIT_IF(key < 0 || key > NBKEYS, _("FATAL ERROR: key value out of bounds"));
|
||||
EXIT_IF(key < 0
|
||||
|| key > NBKEYS,
|
||||
_("FATAL ERROR: key value out of bounds"));
|
||||
|
||||
return keydef[key].label;
|
||||
return keydef[key].label;
|
||||
}
|
||||
|
||||
enum key keys_get_action(int pressed)
|
||||
{
|
||||
if (pressed < 0 || pressed > MAXKEYVAL)
|
||||
return -1;
|
||||
else
|
||||
return actions[pressed];
|
||||
if (pressed < 0 || pressed > MAXKEYVAL)
|
||||
return -1;
|
||||
else
|
||||
return actions[pressed];
|
||||
}
|
||||
|
||||
enum key keys_getch(WINDOW * win, int *count, int *reg)
|
||||
{
|
||||
int ch = '0';
|
||||
int ch = '0';
|
||||
|
||||
if (count && reg) {
|
||||
*count = 0;
|
||||
*reg = 0;
|
||||
do {
|
||||
*count = *count * 10 + ch - '0';
|
||||
ch = wgetch(win);
|
||||
}
|
||||
while ((ch == '0' && *count > 0) || (ch >= '1' && ch <= '9'));
|
||||
if (count && reg) {
|
||||
*count = 0;
|
||||
*reg = 0;
|
||||
do {
|
||||
*count = *count * 10 + ch - '0';
|
||||
ch = wgetch(win);
|
||||
}
|
||||
while ((ch == '0' && *count > 0)
|
||||
|| (ch >= '1' && ch <= '9'));
|
||||
|
||||
if (*count == 0)
|
||||
*count = 1;
|
||||
if (*count == 0)
|
||||
*count = 1;
|
||||
|
||||
if (ch == '"') {
|
||||
ch = wgetch(win);
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
*reg = ch - '1' + 1;
|
||||
} else if (ch >= 'a' && ch <= 'z') {
|
||||
*reg = ch - 'a' + 10;
|
||||
} else if (ch == '_') {
|
||||
*reg = REG_BLACK_HOLE;
|
||||
}
|
||||
ch = wgetch(win);
|
||||
}
|
||||
} else {
|
||||
ch = wgetch(win);
|
||||
}
|
||||
if (ch == '"') {
|
||||
ch = wgetch(win);
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
*reg = ch - '1' + 1;
|
||||
} else if (ch >= 'a' && ch <= 'z') {
|
||||
*reg = ch - 'a' + 10;
|
||||
} else if (ch == '_') {
|
||||
*reg = REG_BLACK_HOLE;
|
||||
}
|
||||
ch = wgetch(win);
|
||||
}
|
||||
} else {
|
||||
ch = wgetch(win);
|
||||
}
|
||||
|
||||
switch (ch) {
|
||||
case KEY_RESIZE:
|
||||
return KEY_RESIZE;
|
||||
default:
|
||||
return keys_get_action(ch);
|
||||
}
|
||||
switch (ch) {
|
||||
case KEY_RESIZE:
|
||||
return KEY_RESIZE;
|
||||
default:
|
||||
return keys_get_action(ch);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_key_str(enum key action, int key)
|
||||
{
|
||||
if (action > NBKEYS)
|
||||
return;
|
||||
if (action > NBKEYS)
|
||||
return;
|
||||
|
||||
LLIST_ADD(&keys[action], mem_strdup(keys_int2str(key)));
|
||||
LLIST_ADD(&keys[action], mem_strdup(keys_int2str(key)));
|
||||
}
|
||||
|
||||
int keys_assign_binding(int key, enum key action)
|
||||
{
|
||||
if (key < 0 || key > MAXKEYVAL || actions[key] != KEY_UNDEF) {
|
||||
return 1;
|
||||
} else {
|
||||
actions[key] = action;
|
||||
add_key_str(action, key);
|
||||
}
|
||||
if (key < 0 || key > MAXKEYVAL || actions[key] != KEY_UNDEF) {
|
||||
return 1;
|
||||
} else {
|
||||
actions[key] = action;
|
||||
add_key_str(action, key);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void del_key_str(enum key action, int key)
|
||||
{
|
||||
llist_item_t *i;
|
||||
char oldstr[BUFSIZ];
|
||||
llist_item_t *i;
|
||||
char oldstr[BUFSIZ];
|
||||
|
||||
if (action > NBKEYS)
|
||||
return;
|
||||
if (action > NBKEYS)
|
||||
return;
|
||||
|
||||
strncpy(oldstr, keys_int2str(key), BUFSIZ);
|
||||
strncpy(oldstr, keys_int2str(key), BUFSIZ);
|
||||
|
||||
LLIST_FOREACH(&keys[action], i) {
|
||||
if (strcmp(LLIST_GET_DATA(i), oldstr) == 0) {
|
||||
LLIST_REMOVE(&keys[action], i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
LLIST_FOREACH(&keys[action], i) {
|
||||
if (strcmp(LLIST_GET_DATA(i), oldstr) == 0) {
|
||||
LLIST_REMOVE(&keys[action], i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keys_remove_binding(int key, enum key action)
|
||||
{
|
||||
if (key >= 0 && key <= MAXKEYVAL) {
|
||||
actions[key] = KEY_UNDEF;
|
||||
del_key_str(action, key);
|
||||
}
|
||||
if (key >= 0 && key <= MAXKEYVAL) {
|
||||
actions[key] = KEY_UNDEF;
|
||||
del_key_str(action, key);
|
||||
}
|
||||
}
|
||||
|
||||
int keys_str2int(const char *key)
|
||||
{
|
||||
const char CONTROL_KEY[] = "C-";
|
||||
const char TAB_KEY[] = "TAB";
|
||||
const char SPACE_KEY[] = "SPC";
|
||||
const char ESCAPE_KEY[] = "ESC";
|
||||
const char CURSES_KEY_UP[] = "UP";
|
||||
const char CURSES_KEY_DOWN[] = "DWN";
|
||||
const char CURSES_KEY_LEFT[] = "LFT";
|
||||
const char CURSES_KEY_RIGHT[] = "RGT";
|
||||
const char CURSES_KEY_HOME[] = "KEY_HOME";
|
||||
const char CURSES_KEY_END[] = "KEY_END";
|
||||
const char CONTROL_KEY[] = "C-";
|
||||
const char TAB_KEY[] = "TAB";
|
||||
const char SPACE_KEY[] = "SPC";
|
||||
const char ESCAPE_KEY[] = "ESC";
|
||||
const char CURSES_KEY_UP[] = "UP";
|
||||
const char CURSES_KEY_DOWN[] = "DWN";
|
||||
const char CURSES_KEY_LEFT[] = "LFT";
|
||||
const char CURSES_KEY_RIGHT[] = "RGT";
|
||||
const char CURSES_KEY_HOME[] = "KEY_HOME";
|
||||
const char CURSES_KEY_END[] = "KEY_END";
|
||||
|
||||
if (!key)
|
||||
return -1;
|
||||
if (strlen(key) == 1) {
|
||||
return (int)key[0];
|
||||
} else {
|
||||
if (key[0] == '^')
|
||||
return CTRL((int)key[1]);
|
||||
else if (!strncmp(key, CONTROL_KEY, sizeof(CONTROL_KEY) - 1))
|
||||
return CTRL((int)key[sizeof(CONTROL_KEY) - 1]);
|
||||
else if (!strcmp(key, TAB_KEY))
|
||||
return TAB;
|
||||
else if (!strcmp(key, ESCAPE_KEY))
|
||||
return ESCAPE;
|
||||
else if (!strcmp(key, SPACE_KEY))
|
||||
return SPACE;
|
||||
else if (!strcmp(key, CURSES_KEY_UP))
|
||||
return KEY_UP;
|
||||
else if (!strcmp(key, CURSES_KEY_DOWN))
|
||||
return KEY_DOWN;
|
||||
else if (!strcmp(key, CURSES_KEY_LEFT))
|
||||
return KEY_LEFT;
|
||||
else if (!strcmp(key, CURSES_KEY_RIGHT))
|
||||
return KEY_RIGHT;
|
||||
else if (!strcmp(key, CURSES_KEY_HOME))
|
||||
return KEY_HOME;
|
||||
else if (!strcmp(key, CURSES_KEY_END))
|
||||
return KEY_END;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (!key)
|
||||
return -1;
|
||||
if (strlen(key) == 1) {
|
||||
return (int)key[0];
|
||||
} else {
|
||||
if (key[0] == '^')
|
||||
return CTRL((int)key[1]);
|
||||
else if (!strncmp
|
||||
(key, CONTROL_KEY, sizeof(CONTROL_KEY) - 1))
|
||||
return CTRL((int)key[sizeof(CONTROL_KEY) - 1]);
|
||||
else if (!strcmp(key, TAB_KEY))
|
||||
return TAB;
|
||||
else if (!strcmp(key, ESCAPE_KEY))
|
||||
return ESCAPE;
|
||||
else if (!strcmp(key, SPACE_KEY))
|
||||
return SPACE;
|
||||
else if (!strcmp(key, CURSES_KEY_UP))
|
||||
return KEY_UP;
|
||||
else if (!strcmp(key, CURSES_KEY_DOWN))
|
||||
return KEY_DOWN;
|
||||
else if (!strcmp(key, CURSES_KEY_LEFT))
|
||||
return KEY_LEFT;
|
||||
else if (!strcmp(key, CURSES_KEY_RIGHT))
|
||||
return KEY_RIGHT;
|
||||
else if (!strcmp(key, CURSES_KEY_HOME))
|
||||
return KEY_HOME;
|
||||
else if (!strcmp(key, CURSES_KEY_END))
|
||||
return KEY_END;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const char *keys_int2str(int key)
|
||||
{
|
||||
switch (key) {
|
||||
case TAB:
|
||||
return "TAB";
|
||||
case SPACE:
|
||||
return "SPC";
|
||||
case ESCAPE:
|
||||
return "ESC";
|
||||
case KEY_UP:
|
||||
return "UP";
|
||||
case KEY_DOWN:
|
||||
return "DWN";
|
||||
case KEY_LEFT:
|
||||
return "LFT";
|
||||
case KEY_RIGHT:
|
||||
return "RGT";
|
||||
case KEY_HOME:
|
||||
return "KEY_HOME";
|
||||
case KEY_END:
|
||||
return "KEY_END";
|
||||
default:
|
||||
return (char *)keyname(key);
|
||||
}
|
||||
switch (key) {
|
||||
case TAB:
|
||||
return "TAB";
|
||||
case SPACE:
|
||||
return "SPC";
|
||||
case ESCAPE:
|
||||
return "ESC";
|
||||
case KEY_UP:
|
||||
return "UP";
|
||||
case KEY_DOWN:
|
||||
return "DWN";
|
||||
case KEY_LEFT:
|
||||
return "LFT";
|
||||
case KEY_RIGHT:
|
||||
return "RGT";
|
||||
case KEY_HOME:
|
||||
return "KEY_HOME";
|
||||
case KEY_END:
|
||||
return "KEY_END";
|
||||
default:
|
||||
return (char *)keyname(key);
|
||||
}
|
||||
}
|
||||
|
||||
int keys_action_count_keys(enum key action)
|
||||
{
|
||||
llist_item_t *i;
|
||||
int n = 0;
|
||||
llist_item_t *i;
|
||||
int n = 0;
|
||||
|
||||
LLIST_FOREACH(&keys[action], i)
|
||||
n++;
|
||||
LLIST_FOREACH(&keys[action], i)
|
||||
n++;
|
||||
|
||||
return n;
|
||||
return n;
|
||||
}
|
||||
|
||||
const char *keys_action_firstkey(enum key action)
|
||||
{
|
||||
const char *s = LLIST_GET_DATA(LLIST_FIRST(&keys[action]));
|
||||
return (s != NULL) ? s : "XXX";
|
||||
const char *s = LLIST_GET_DATA(LLIST_FIRST(&keys[action]));
|
||||
return (s != NULL) ? s : "XXX";
|
||||
}
|
||||
|
||||
const char *keys_action_nkey(enum key action, int keynum)
|
||||
{
|
||||
return LLIST_GET_DATA(LLIST_NTH(&keys[action], keynum));
|
||||
return LLIST_GET_DATA(LLIST_NTH(&keys[action], keynum));
|
||||
}
|
||||
|
||||
char *keys_action_allkeys(enum key action)
|
||||
{
|
||||
llist_item_t *i;
|
||||
static char keystr[BUFSIZ];
|
||||
const char *CHAR_SPACE = " ";
|
||||
llist_item_t *i;
|
||||
static char keystr[BUFSIZ];
|
||||
const char *CHAR_SPACE = " ";
|
||||
|
||||
if (!LLIST_FIRST(&keys[action]))
|
||||
return NULL;
|
||||
if (!LLIST_FIRST(&keys[action]))
|
||||
return NULL;
|
||||
|
||||
keystr[0] = '\0';
|
||||
LLIST_FOREACH(&keys[action], i) {
|
||||
const int MAXLEN = sizeof(keystr) - 1 - strlen(keystr);
|
||||
strncat(keystr, LLIST_GET_DATA(i), MAXLEN - 1);
|
||||
strncat(keystr, CHAR_SPACE, 1);
|
||||
}
|
||||
keystr[0] = '\0';
|
||||
LLIST_FOREACH(&keys[action], i) {
|
||||
const int MAXLEN = sizeof(keystr) - 1 - strlen(keystr);
|
||||
strncat(keystr, LLIST_GET_DATA(i), MAXLEN - 1);
|
||||
strncat(keystr, CHAR_SPACE, 1);
|
||||
}
|
||||
|
||||
return keystr;
|
||||
return keystr;
|
||||
}
|
||||
|
||||
/* Need this to display keys properly inside status bar. */
|
||||
static char *keys_format_label(char *key, int keylen)
|
||||
{
|
||||
static char fmtkey[BUFSIZ];
|
||||
const int len = strlen(key);
|
||||
const char dot = '.';
|
||||
int i;
|
||||
static char fmtkey[BUFSIZ];
|
||||
const int len = strlen(key);
|
||||
const char dot = '.';
|
||||
int i;
|
||||
|
||||
if (keylen > BUFSIZ)
|
||||
return NULL;
|
||||
if (keylen > BUFSIZ)
|
||||
return NULL;
|
||||
|
||||
memset(fmtkey, 0, sizeof(fmtkey));
|
||||
if (len == 0) {
|
||||
strncpy(fmtkey, "?", sizeof(fmtkey));
|
||||
} else if (len <= keylen) {
|
||||
for (i = 0; i < keylen - len; i++)
|
||||
fmtkey[i] = ' ';
|
||||
strncat(fmtkey, key, keylen);
|
||||
} else {
|
||||
for (i = 0; i < keylen - 1; i++)
|
||||
fmtkey[i] = key[i];
|
||||
fmtkey[keylen - 1] = dot;
|
||||
}
|
||||
return fmtkey;
|
||||
memset(fmtkey, 0, sizeof(fmtkey));
|
||||
if (len == 0) {
|
||||
strncpy(fmtkey, "?", sizeof(fmtkey));
|
||||
} else if (len <= keylen) {
|
||||
for (i = 0; i < keylen - len; i++)
|
||||
fmtkey[i] = ' ';
|
||||
strncat(fmtkey, key, keylen);
|
||||
} else {
|
||||
for (i = 0; i < keylen - 1; i++)
|
||||
fmtkey[i] = key[i];
|
||||
fmtkey[keylen - 1] = dot;
|
||||
}
|
||||
return fmtkey;
|
||||
}
|
||||
|
||||
void
|
||||
keys_display_bindings_bar(WINDOW * win, struct binding *bindings[], int count,
|
||||
int page_base, int page_size, struct binding *more)
|
||||
keys_display_bindings_bar(WINDOW * win, struct binding *bindings[],
|
||||
int count, int page_base, int page_size,
|
||||
struct binding *more)
|
||||
{
|
||||
/* Padding between two key bindings. */
|
||||
const int padding = (col * 2) / page_size - (KEYS_KEYLEN + KEYS_LABELEN + 1);
|
||||
/* Total length of a key binding (including padding). */
|
||||
const int cmd_len = KEYS_KEYLEN + KEYS_LABELEN + 1 + padding;
|
||||
/* Padding between two key bindings. */
|
||||
const int padding =
|
||||
(col * 2) / page_size - (KEYS_KEYLEN + KEYS_LABELEN + 1);
|
||||
/* Total length of a key binding (including padding). */
|
||||
const int cmd_len = KEYS_KEYLEN + KEYS_LABELEN + 1 + padding;
|
||||
|
||||
int i;
|
||||
int i;
|
||||
|
||||
wins_erase_status_bar();
|
||||
for (i = 0; i < page_size && page_base + i < count; i++) {
|
||||
/* Location of key and label. */
|
||||
const int key_pos_x = (i / 2) * cmd_len;
|
||||
const int key_pos_y = i % 2;
|
||||
const int label_pos_x = key_pos_x + KEYS_KEYLEN + 1;
|
||||
const int label_pos_y = key_pos_y;
|
||||
wins_erase_status_bar();
|
||||
for (i = 0; i < page_size && page_base + i < count; i++) {
|
||||
/* Location of key and label. */
|
||||
const int key_pos_x = (i / 2) * cmd_len;
|
||||
const int key_pos_y = i % 2;
|
||||
const int label_pos_x = key_pos_x + KEYS_KEYLEN + 1;
|
||||
const int label_pos_y = key_pos_y;
|
||||
|
||||
struct binding *binding;
|
||||
char key[KEYS_KEYLEN + 1], *fmtkey;
|
||||
struct binding *binding;
|
||||
char key[KEYS_KEYLEN + 1], *fmtkey;
|
||||
|
||||
if (!more || i < page_size - 1 || page_base + i == count - 1)
|
||||
binding = bindings[page_base + i];
|
||||
else
|
||||
binding = more;
|
||||
if (!more || i < page_size - 1
|
||||
|| page_base + i == count - 1)
|
||||
binding = bindings[page_base + i];
|
||||
else
|
||||
binding = more;
|
||||
|
||||
strncpy(key, keys_action_firstkey(binding->action), KEYS_KEYLEN);
|
||||
key[KEYS_KEYLEN] = '\0';
|
||||
fmtkey = keys_format_label(key, KEYS_KEYLEN);
|
||||
strncpy(key, keys_action_firstkey(binding->action),
|
||||
KEYS_KEYLEN);
|
||||
key[KEYS_KEYLEN] = '\0';
|
||||
fmtkey = keys_format_label(key, KEYS_KEYLEN);
|
||||
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
mvwaddstr(win, key_pos_y, key_pos_x, fmtkey);
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
mvwaddstr(win, label_pos_y, label_pos_x, binding->label);
|
||||
}
|
||||
wnoutrefresh(win);
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
mvwaddstr(win, key_pos_y, key_pos_x, fmtkey);
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
mvwaddstr(win, label_pos_y, label_pos_x, binding->label);
|
||||
}
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -447,155 +457,161 @@ keys_display_bindings_bar(WINDOW * win, struct binding *bindings[], int count,
|
||||
*/
|
||||
void keys_popup_info(enum key key)
|
||||
{
|
||||
char *info[NBKEYS];
|
||||
WINDOW *infowin;
|
||||
char *info[NBKEYS];
|
||||
WINDOW *infowin;
|
||||
|
||||
info[KEY_GENERIC_CANCEL] = _("Cancel the ongoing action.");
|
||||
info[KEY_GENERIC_SELECT] = _("Select the highlighted item.");
|
||||
info[KEY_GENERIC_CREDITS] =
|
||||
_("Print general information about calcurse's authors, license, etc.");
|
||||
info[KEY_GENERIC_HELP] =
|
||||
_("Display hints whenever some help screens are available.");
|
||||
info[KEY_GENERIC_QUIT] = _("Exit from the current menu, or quit calcurse.");
|
||||
info[KEY_GENERIC_SAVE] = _("Save calcurse data.");
|
||||
info[KEY_GENERIC_COPY] = _("Copy the item that is currently selected.");
|
||||
info[KEY_GENERIC_PASTE] = _("Paste an item at the current position.");
|
||||
info[KEY_GENERIC_CHANGE_VIEW] =
|
||||
_("Select next panel in calcurse main screen.");
|
||||
info[KEY_GENERIC_IMPORT] = _("Import data from an external file.");
|
||||
info[KEY_GENERIC_EXPORT] = _("Export data to a new file format.");
|
||||
info[KEY_GENERIC_GOTO] = _("Select the day to go to.");
|
||||
info[KEY_GENERIC_OTHER_CMD] =
|
||||
_("Show next possible actions inside status bar.");
|
||||
info[KEY_GENERIC_CONFIG_MENU] = _("Enter the configuration menu.");
|
||||
info[KEY_GENERIC_REDRAW] = _("Redraw calcurse's screen.");
|
||||
info[KEY_GENERIC_ADD_APPT] =
|
||||
_("Add an appointment, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_ADD_TODO] =
|
||||
_("Add a todo item, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_PREV_DAY] =
|
||||
_("Move to previous day in calendar, whichever panel is currently "
|
||||
"selected.");
|
||||
info[KEY_GENERIC_NEXT_DAY] =
|
||||
_("Move to next day in calendar, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_PREV_WEEK] =
|
||||
_("Move to previous week in calendar, whichever panel is currently "
|
||||
"selected");
|
||||
info[KEY_GENERIC_NEXT_WEEK] =
|
||||
_
|
||||
("Move to next week in calendar, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_PREV_MONTH] =
|
||||
_("Move to previous month in calendar, whichever panel is currently "
|
||||
"selected");
|
||||
info[KEY_GENERIC_NEXT_MONTH] =
|
||||
_
|
||||
("Move to next month in calendar, whichever panel is currently "
|
||||
"selected.");
|
||||
info[KEY_GENERIC_PREV_YEAR] =
|
||||
_("Move to previous year in calendar, whichever panel is currently "
|
||||
"selected");
|
||||
info[KEY_GENERIC_NEXT_YEAR] =
|
||||
_
|
||||
("Move to next year in calendar, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_SCROLL_DOWN] =
|
||||
_
|
||||
("Scroll window down (e.g. when displaying text inside a popup window).");
|
||||
info[KEY_GENERIC_SCROLL_UP] =
|
||||
_("Scroll window up (e.g. when displaying text inside a popup window).");
|
||||
info[KEY_GENERIC_GOTO_TODAY] = _("Go to today, whichever panel is selected.");
|
||||
info[KEY_MOVE_RIGHT] = _("Move to the right.");
|
||||
info[KEY_MOVE_LEFT] = _("Move to the left.");
|
||||
info[KEY_MOVE_DOWN] = _("Move down.");
|
||||
info[KEY_MOVE_UP] = _("Move up.");
|
||||
info[KEY_START_OF_WEEK] =
|
||||
_("Select the first day of the current week when inside the calendar "
|
||||
"panel.");
|
||||
info[KEY_END_OF_WEEK] =
|
||||
_("Select the last day of the current week when inside the calendar "
|
||||
"panel.");
|
||||
info[KEY_ADD_ITEM] = _("Add an item to the currently selected panel.");
|
||||
info[KEY_DEL_ITEM] = _("Delete the currently selected item.");
|
||||
info[KEY_EDIT_ITEM] = _("Edit the currently seleted item.");
|
||||
info[KEY_VIEW_ITEM] =
|
||||
_("Display the currently selected item inside a popup window.");
|
||||
info[KEY_FLAG_ITEM] = _("Flag the currently selected item as important.");
|
||||
info[KEY_REPEAT_ITEM] = _("Repeat an item");
|
||||
info[KEY_PIPE_ITEM] =
|
||||
_("Pipe the currently selected item to an external program.");
|
||||
info[KEY_EDIT_NOTE] =
|
||||
_("Attach (or edit if one exists) a note to the currently selected item");
|
||||
info[KEY_VIEW_NOTE] =
|
||||
_("View the note attached to the currently selected item.");
|
||||
info[KEY_RAISE_PRIORITY] = _("Raise a task priority inside the todo panel.");
|
||||
info[KEY_LOWER_PRIORITY] = _("Lower a task priority inside the todo panel.");
|
||||
info[KEY_GENERIC_CANCEL] = _("Cancel the ongoing action.");
|
||||
info[KEY_GENERIC_SELECT] = _("Select the highlighted item.");
|
||||
info[KEY_GENERIC_CREDITS] =
|
||||
_("Print general information about calcurse's authors, license, etc.");
|
||||
info[KEY_GENERIC_HELP] =
|
||||
_("Display hints whenever some help screens are available.");
|
||||
info[KEY_GENERIC_QUIT] =
|
||||
_("Exit from the current menu, or quit calcurse.");
|
||||
info[KEY_GENERIC_SAVE] = _("Save calcurse data.");
|
||||
info[KEY_GENERIC_COPY] =
|
||||
_("Copy the item that is currently selected.");
|
||||
info[KEY_GENERIC_PASTE] =
|
||||
_("Paste an item at the current position.");
|
||||
info[KEY_GENERIC_CHANGE_VIEW] =
|
||||
_("Select next panel in calcurse main screen.");
|
||||
info[KEY_GENERIC_IMPORT] = _("Import data from an external file.");
|
||||
info[KEY_GENERIC_EXPORT] = _("Export data to a new file format.");
|
||||
info[KEY_GENERIC_GOTO] = _("Select the day to go to.");
|
||||
info[KEY_GENERIC_OTHER_CMD] =
|
||||
_("Show next possible actions inside status bar.");
|
||||
info[KEY_GENERIC_CONFIG_MENU] = _("Enter the configuration menu.");
|
||||
info[KEY_GENERIC_REDRAW] = _("Redraw calcurse's screen.");
|
||||
info[KEY_GENERIC_ADD_APPT] =
|
||||
_("Add an appointment, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_ADD_TODO] =
|
||||
_("Add a todo item, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_PREV_DAY] =
|
||||
_("Move to previous day in calendar, whichever panel is currently "
|
||||
"selected.");
|
||||
info[KEY_GENERIC_NEXT_DAY] =
|
||||
_("Move to next day in calendar, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_PREV_WEEK] =
|
||||
_("Move to previous week in calendar, whichever panel is currently "
|
||||
"selected");
|
||||
info[KEY_GENERIC_NEXT_WEEK] =
|
||||
_("Move to next week in calendar, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_PREV_MONTH] =
|
||||
_("Move to previous month in calendar, whichever panel is currently "
|
||||
"selected");
|
||||
info[KEY_GENERIC_NEXT_MONTH] =
|
||||
_("Move to next month in calendar, whichever panel is currently "
|
||||
"selected.");
|
||||
info[KEY_GENERIC_PREV_YEAR] =
|
||||
_("Move to previous year in calendar, whichever panel is currently "
|
||||
"selected");
|
||||
info[KEY_GENERIC_NEXT_YEAR] =
|
||||
_("Move to next year in calendar, whichever panel is currently selected.");
|
||||
info[KEY_GENERIC_SCROLL_DOWN] =
|
||||
_("Scroll window down (e.g. when displaying text inside a popup window).");
|
||||
info[KEY_GENERIC_SCROLL_UP] =
|
||||
_("Scroll window up (e.g. when displaying text inside a popup window).");
|
||||
info[KEY_GENERIC_GOTO_TODAY] =
|
||||
_("Go to today, whichever panel is selected.");
|
||||
info[KEY_MOVE_RIGHT] = _("Move to the right.");
|
||||
info[KEY_MOVE_LEFT] = _("Move to the left.");
|
||||
info[KEY_MOVE_DOWN] = _("Move down.");
|
||||
info[KEY_MOVE_UP] = _("Move up.");
|
||||
info[KEY_START_OF_WEEK] =
|
||||
_("Select the first day of the current week when inside the calendar "
|
||||
"panel.");
|
||||
info[KEY_END_OF_WEEK] =
|
||||
_("Select the last day of the current week when inside the calendar "
|
||||
"panel.");
|
||||
info[KEY_ADD_ITEM] =
|
||||
_("Add an item to the currently selected panel.");
|
||||
info[KEY_DEL_ITEM] = _("Delete the currently selected item.");
|
||||
info[KEY_EDIT_ITEM] = _("Edit the currently seleted item.");
|
||||
info[KEY_VIEW_ITEM] =
|
||||
_("Display the currently selected item inside a popup window.");
|
||||
info[KEY_FLAG_ITEM] =
|
||||
_("Flag the currently selected item as important.");
|
||||
info[KEY_REPEAT_ITEM] = _("Repeat an item");
|
||||
info[KEY_PIPE_ITEM] =
|
||||
_("Pipe the currently selected item to an external program.");
|
||||
info[KEY_EDIT_NOTE] =
|
||||
_("Attach (or edit if one exists) a note to the currently selected item");
|
||||
info[KEY_VIEW_NOTE] =
|
||||
_("View the note attached to the currently selected item.");
|
||||
info[KEY_RAISE_PRIORITY] =
|
||||
_("Raise a task priority inside the todo panel.");
|
||||
info[KEY_LOWER_PRIORITY] =
|
||||
_("Lower a task priority inside the todo panel.");
|
||||
|
||||
if (key > NBKEYS)
|
||||
return;
|
||||
if (key > NBKEYS)
|
||||
return;
|
||||
|
||||
#define WINROW 10
|
||||
#define WINCOL (col - 4)
|
||||
infowin = popup(WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2,
|
||||
keydef[key].label, info[key], 1);
|
||||
keys_getch(infowin, NULL, NULL);
|
||||
delwin(infowin);
|
||||
infowin =
|
||||
popup(WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2,
|
||||
keydef[key].label, info[key], 1);
|
||||
keys_getch(infowin, NULL, NULL);
|
||||
delwin(infowin);
|
||||
#undef WINROW
|
||||
#undef WINCOL
|
||||
}
|
||||
|
||||
void keys_save_bindings(FILE * fd)
|
||||
{
|
||||
int i;
|
||||
char *action;
|
||||
int i;
|
||||
char *action;
|
||||
|
||||
EXIT_IF(fd == NULL, _("FATAL ERROR: null file pointer."));
|
||||
dump_intro(fd);
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
action = keys_action_allkeys(i);
|
||||
if (action)
|
||||
fprintf(fd, "%s %s\n", keydef[i].label, action);
|
||||
}
|
||||
EXIT_IF(fd == NULL, _("FATAL ERROR: null file pointer."));
|
||||
dump_intro(fd);
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
action = keys_action_allkeys(i);
|
||||
if (action)
|
||||
fprintf(fd, "%s %s\n", keydef[i].label, action);
|
||||
}
|
||||
}
|
||||
|
||||
int keys_check_missing_bindings(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
if (!LLIST_FIRST(&keys[i]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
if (!LLIST_FIRST(&keys[i]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void keys_fill_missing(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
if (!LLIST_FIRST(&keys[i])) {
|
||||
char *p, tmpbuf[BUFSIZ];
|
||||
for (i = 0; i < NBKEYS; i++) {
|
||||
if (!LLIST_FIRST(&keys[i])) {
|
||||
char *p, tmpbuf[BUFSIZ];
|
||||
|
||||
strncpy(tmpbuf, keydef[i].binding, BUFSIZ);
|
||||
p = tmpbuf;
|
||||
for (;;) {
|
||||
char key_ch[BUFSIZ];
|
||||
strncpy(tmpbuf, keydef[i].binding, BUFSIZ);
|
||||
p = tmpbuf;
|
||||
for (;;) {
|
||||
char key_ch[BUFSIZ];
|
||||
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
if (sscanf(p, "%s", key_ch) == 1) {
|
||||
int ch, used;
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
if (sscanf(p, "%s", key_ch) == 1) {
|
||||
int ch, used;
|
||||
|
||||
ch = keys_str2int(key_ch);
|
||||
used = keys_assign_binding(ch, i);
|
||||
if (used)
|
||||
WARN_MSG(_("When adding default key for \"%s\", "
|
||||
"\"%s\" was already assigned!"),
|
||||
keydef[i].label, key_ch);
|
||||
p += strlen(key_ch) + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ch = keys_str2int(key_ch);
|
||||
used = keys_assign_binding(ch, i);
|
||||
if (used)
|
||||
WARN_MSG(_("When adding default key for \"%s\", "
|
||||
"\"%s\" was already assigned!"),
|
||||
keydef[i].label,
|
||||
key_ch);
|
||||
p += strlen(key_ch) + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
243
src/llist.c
243
src/llist.c
@ -41,8 +41,8 @@
|
||||
*/
|
||||
void llist_init(llist_t * l)
|
||||
{
|
||||
l->head = NULL;
|
||||
l->tail = NULL;
|
||||
l->head = NULL;
|
||||
l->tail = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -50,15 +50,15 @@ void llist_init(llist_t * l)
|
||||
*/
|
||||
void llist_free(llist_t * l)
|
||||
{
|
||||
llist_item_t *i, *t;
|
||||
llist_item_t *i, *t;
|
||||
|
||||
for (i = l->head; i; i = t) {
|
||||
t = i->next;
|
||||
mem_free(i);
|
||||
}
|
||||
for (i = l->head; i; i = t) {
|
||||
t = i->next;
|
||||
mem_free(i);
|
||||
}
|
||||
|
||||
l->head = NULL;
|
||||
l->tail = NULL;
|
||||
l->head = NULL;
|
||||
l->tail = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -66,14 +66,14 @@ void llist_free(llist_t * l)
|
||||
*/
|
||||
void llist_free_inner(llist_t * l, llist_fn_free_t fn_free)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (i->data) {
|
||||
fn_free(i->data);
|
||||
i->data = NULL;
|
||||
}
|
||||
}
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (i->data) {
|
||||
fn_free(i->data);
|
||||
i->data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -81,7 +81,7 @@ void llist_free_inner(llist_t * l, llist_fn_free_t fn_free)
|
||||
*/
|
||||
llist_item_t *llist_first(llist_t * l)
|
||||
{
|
||||
return l->head;
|
||||
return l->head;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -89,15 +89,15 @@ llist_item_t *llist_first(llist_t * l)
|
||||
*/
|
||||
llist_item_t *llist_nth(llist_t * l, int n)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
|
||||
for (i = l->head; i && n != 0; n--)
|
||||
i = i->next;
|
||||
for (i = l->head; i && n != 0; n--)
|
||||
i = i->next;
|
||||
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -105,7 +105,7 @@ llist_item_t *llist_nth(llist_t * l, int n)
|
||||
*/
|
||||
llist_item_t *llist_next(llist_item_t * i)
|
||||
{
|
||||
return i ? i->next : NULL;
|
||||
return i ? i->next : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -113,12 +113,12 @@ llist_item_t *llist_next(llist_item_t * i)
|
||||
* callback. Return NULL otherwise.
|
||||
*/
|
||||
llist_item_t *llist_next_filter(llist_item_t * i, void *data,
|
||||
llist_fn_match_t fn_match)
|
||||
llist_fn_match_t fn_match)
|
||||
{
|
||||
if (i && i->next && fn_match(i->next->data, data))
|
||||
return i->next;
|
||||
else
|
||||
return NULL;
|
||||
if (i && i->next && fn_match(i->next->data, data))
|
||||
return i->next;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -126,7 +126,7 @@ llist_item_t *llist_next_filter(llist_item_t * i, void *data,
|
||||
*/
|
||||
void *llist_get_data(llist_item_t * i)
|
||||
{
|
||||
return i ? i->data : NULL;
|
||||
return i ? i->data : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -134,19 +134,19 @@ void *llist_get_data(llist_item_t * i)
|
||||
*/
|
||||
void llist_add(llist_t * l, void *data)
|
||||
{
|
||||
llist_item_t *o = mem_malloc(sizeof(llist_item_t));
|
||||
llist_item_t *o = mem_malloc(sizeof(llist_item_t));
|
||||
|
||||
if (o) {
|
||||
o->data = data;
|
||||
o->next = NULL;
|
||||
if (o) {
|
||||
o->data = data;
|
||||
o->next = NULL;
|
||||
|
||||
if (!l->head) {
|
||||
l->head = l->tail = o;
|
||||
} else {
|
||||
l->tail->next = o;
|
||||
l->tail = o;
|
||||
}
|
||||
}
|
||||
if (!l->head) {
|
||||
l->head = l->tail = o;
|
||||
} else {
|
||||
l->tail->next = o;
|
||||
l->tail = o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -154,29 +154,30 @@ void llist_add(llist_t * l, void *data)
|
||||
*/
|
||||
void llist_add_sorted(llist_t * l, void *data, llist_fn_cmp_t fn_cmp)
|
||||
{
|
||||
llist_item_t *o = mem_malloc(sizeof(llist_item_t));
|
||||
llist_item_t *i;
|
||||
llist_item_t *o = mem_malloc(sizeof(llist_item_t));
|
||||
llist_item_t *i;
|
||||
|
||||
if (o) {
|
||||
o->data = data;
|
||||
o->next = NULL;
|
||||
if (o) {
|
||||
o->data = data;
|
||||
o->next = NULL;
|
||||
|
||||
if (!l->head) {
|
||||
l->head = l->tail = o;
|
||||
} else if (fn_cmp(o->data, l->tail->data) >= 0) {
|
||||
l->tail->next = o;
|
||||
l->tail = o;
|
||||
} else if (fn_cmp(o->data, l->head->data) < 0) {
|
||||
o->next = l->head;
|
||||
l->head = o;
|
||||
} else {
|
||||
i = l->head;
|
||||
while (i->next && fn_cmp(o->data, i->next->data) >= 0)
|
||||
i = i->next;
|
||||
o->next = i->next;
|
||||
i->next = o;
|
||||
}
|
||||
}
|
||||
if (!l->head) {
|
||||
l->head = l->tail = o;
|
||||
} else if (fn_cmp(o->data, l->tail->data) >= 0) {
|
||||
l->tail->next = o;
|
||||
l->tail = o;
|
||||
} else if (fn_cmp(o->data, l->head->data) < 0) {
|
||||
o->next = l->head;
|
||||
l->head = o;
|
||||
} else {
|
||||
i = l->head;
|
||||
while (i->next
|
||||
&& fn_cmp(o->data, i->next->data) >= 0)
|
||||
i = i->next;
|
||||
o->next = i->next;
|
||||
i->next = o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -184,93 +185,93 @@ void llist_add_sorted(llist_t * l, void *data, llist_fn_cmp_t fn_cmp)
|
||||
*/
|
||||
void llist_remove(llist_t * l, llist_item_t * i)
|
||||
{
|
||||
llist_item_t *j = NULL;
|
||||
llist_item_t *j = NULL;
|
||||
|
||||
if (l->head && i == l->head) {
|
||||
l->head = i->next;
|
||||
} else {
|
||||
for (j = l->head; j && j->next != i; j = j->next) ;
|
||||
}
|
||||
if (l->head && i == l->head) {
|
||||
l->head = i->next;
|
||||
} else {
|
||||
for (j = l->head; j && j->next != i; j = j->next) ;
|
||||
}
|
||||
|
||||
if (i) {
|
||||
if (j)
|
||||
j->next = i->next;
|
||||
if (i == l->tail)
|
||||
l->tail = j;
|
||||
if (i) {
|
||||
if (j)
|
||||
j->next = i->next;
|
||||
if (i == l->tail)
|
||||
l->tail = j;
|
||||
|
||||
mem_free(i);
|
||||
}
|
||||
mem_free(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first item matched by some filter callback.
|
||||
*/
|
||||
llist_item_t *llist_find_first(llist_t * l, void *data,
|
||||
llist_fn_match_t fn_match)
|
||||
llist_fn_match_t fn_match)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
if (fn_match) {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (fn_match(i->data, data))
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (i->data == data)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (fn_match) {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (fn_match(i->data, data))
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (i->data == data)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next item matched by some filter callback.
|
||||
*/
|
||||
llist_item_t *llist_find_next(llist_item_t * i, void *data,
|
||||
llist_fn_match_t fn_match)
|
||||
llist_fn_match_t fn_match)
|
||||
{
|
||||
if (i) {
|
||||
i = i->next;
|
||||
if (fn_match) {
|
||||
for (; i; i = i->next) {
|
||||
if (fn_match(i->data, data))
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
for (; i; i = i->next) {
|
||||
if (i->data == data)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i) {
|
||||
i = i->next;
|
||||
if (fn_match) {
|
||||
for (; i; i = i->next) {
|
||||
if (fn_match(i->data, data))
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
for (; i; i = i->next) {
|
||||
if (i->data == data)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the nth item matched by some filter callback.
|
||||
*/
|
||||
llist_item_t *llist_find_nth(llist_t * l, int n, void *data,
|
||||
llist_fn_match_t fn_match)
|
||||
llist_fn_match_t fn_match)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
|
||||
if (fn_match) {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (fn_match(i->data, data) && (n-- == 0))
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if ((i->data == data) && (n-- == 0))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (fn_match) {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if (fn_match(i->data, data) && (n-- == 0))
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
for (i = l->head; i; i = i->next) {
|
||||
if ((i->data == data) && (n-- == 0))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -37,14 +37,14 @@
|
||||
/* Linked lists. */
|
||||
typedef struct llist_item llist_item_t;
|
||||
struct llist_item {
|
||||
struct llist_item *next;
|
||||
void *data;
|
||||
struct llist_item *next;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef struct llist llist_t;
|
||||
struct llist {
|
||||
struct llist_item *head;
|
||||
struct llist_item *tail;
|
||||
struct llist_item *head;
|
||||
struct llist_item *tail;
|
||||
};
|
||||
|
||||
typedef int (*llist_fn_cmp_t) (void *, void *);
|
||||
|
@ -37,9 +37,9 @@
|
||||
/* Thread-safe linked lists. */
|
||||
typedef struct llist_ts llist_ts_t;
|
||||
struct llist_ts {
|
||||
llist_item_t *head;
|
||||
llist_item_t *tail;
|
||||
pthread_mutex_t mutex;
|
||||
llist_item_t *head;
|
||||
llist_item_t *tail;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
/* Initialization and deallocation. */
|
||||
|
271
src/mem.c
271
src/mem.c
@ -44,10 +44,10 @@
|
||||
#ifdef CALCURSE_MEMORY_DEBUG
|
||||
|
||||
enum {
|
||||
BLK_STATE,
|
||||
BLK_SIZE,
|
||||
BLK_ID,
|
||||
EXTRA_SPACE_START
|
||||
BLK_STATE,
|
||||
BLK_SIZE,
|
||||
BLK_ID,
|
||||
EXTRA_SPACE_START
|
||||
};
|
||||
|
||||
#define EXTRA_SPACE_END 1
|
||||
@ -57,14 +57,14 @@ enum {
|
||||
#define MAGIC_FREE 0xdf
|
||||
|
||||
struct mem_blk {
|
||||
unsigned id, size;
|
||||
const char *pos;
|
||||
struct mem_blk *next;
|
||||
unsigned id, size;
|
||||
const char *pos;
|
||||
struct mem_blk *next;
|
||||
};
|
||||
|
||||
struct mem_stats {
|
||||
unsigned ncall, nalloc, nfree;
|
||||
struct mem_blk *blk;
|
||||
unsigned ncall, nalloc, nfree;
|
||||
struct mem_blk *blk;
|
||||
};
|
||||
|
||||
static struct mem_stats mstats;
|
||||
@ -73,229 +73,232 @@ static struct mem_stats mstats;
|
||||
|
||||
void *xmalloc(size_t size)
|
||||
{
|
||||
void *p;
|
||||
void *p;
|
||||
|
||||
EXIT_IF(size == 0, _("xmalloc: zero size"));
|
||||
p = malloc(size);
|
||||
EXIT_IF(p == NULL, _("xmalloc: out of memory"));
|
||||
EXIT_IF(size == 0, _("xmalloc: zero size"));
|
||||
p = malloc(size);
|
||||
EXIT_IF(p == NULL, _("xmalloc: out of memory"));
|
||||
|
||||
return p;
|
||||
return p;
|
||||
}
|
||||
|
||||
void *xcalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
void *p;
|
||||
|
||||
EXIT_IF(nmemb == 0 || size == 0, _("xcalloc: zero size"));
|
||||
EXIT_IF(SIZE_MAX / nmemb < size, _("xcalloc: overflow"));
|
||||
p = calloc(nmemb, size);
|
||||
EXIT_IF(p == NULL, _("xcalloc: out of memory"));
|
||||
EXIT_IF(nmemb == 0 || size == 0, _("xcalloc: zero size"));
|
||||
EXIT_IF(SIZE_MAX / nmemb < size, _("xcalloc: overflow"));
|
||||
p = calloc(nmemb, size);
|
||||
EXIT_IF(p == NULL, _("xcalloc: out of memory"));
|
||||
|
||||
return p;
|
||||
return p;
|
||||
}
|
||||
|
||||
void *xrealloc(void *ptr, size_t nmemb, size_t size)
|
||||
{
|
||||
void *new_ptr;
|
||||
size_t new_size;
|
||||
void *new_ptr;
|
||||
size_t new_size;
|
||||
|
||||
new_size = nmemb * size;
|
||||
EXIT_IF(new_size == 0, _("xrealloc: zero size"));
|
||||
EXIT_IF(SIZE_MAX / nmemb < size, _("xrealloc: overflow"));
|
||||
new_ptr = realloc(ptr, new_size);
|
||||
EXIT_IF(new_ptr == NULL, _("xrealloc: out of memory"));
|
||||
new_size = nmemb * size;
|
||||
EXIT_IF(new_size == 0, _("xrealloc: zero size"));
|
||||
EXIT_IF(SIZE_MAX / nmemb < size, _("xrealloc: overflow"));
|
||||
new_ptr = realloc(ptr, new_size);
|
||||
EXIT_IF(new_ptr == NULL, _("xrealloc: out of memory"));
|
||||
|
||||
return new_ptr;
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
char *xstrdup(const char *str)
|
||||
{
|
||||
size_t len;
|
||||
char *cp;
|
||||
size_t len;
|
||||
char *cp;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
cp = xmalloc(len);
|
||||
len = strlen(str) + 1;
|
||||
cp = xmalloc(len);
|
||||
|
||||
return strncpy(cp, str, len);
|
||||
return strncpy(cp, str, len);
|
||||
}
|
||||
|
||||
void xfree(void *p)
|
||||
{
|
||||
EXIT_IF(p == NULL, _("xfree: null pointer"));
|
||||
free(p);
|
||||
EXIT_IF(p == NULL, _("xfree: null pointer"));
|
||||
free(p);
|
||||
}
|
||||
|
||||
#ifdef CALCURSE_MEMORY_DEBUG
|
||||
|
||||
static unsigned stats_add_blk(size_t size, const char *pos)
|
||||
{
|
||||
struct mem_blk *o, **i;
|
||||
struct mem_blk *o, **i;
|
||||
|
||||
o = malloc(sizeof(*o));
|
||||
EXIT_IF(o == NULL, _("could not allocate memory to store block info"));
|
||||
o = malloc(sizeof(*o));
|
||||
EXIT_IF(o == NULL,
|
||||
_("could not allocate memory to store block info"));
|
||||
|
||||
mstats.ncall++;
|
||||
mstats.ncall++;
|
||||
|
||||
o->pos = pos;
|
||||
o->size = (unsigned)size;
|
||||
o->next = 0;
|
||||
o->pos = pos;
|
||||
o->size = (unsigned)size;
|
||||
o->next = 0;
|
||||
|
||||
for (i = &mstats.blk; *i; i = &(*i)->next) ;
|
||||
o->id = mstats.ncall;
|
||||
*i = o;
|
||||
for (i = &mstats.blk; *i; i = &(*i)->next) ;
|
||||
o->id = mstats.ncall;
|
||||
*i = o;
|
||||
|
||||
return o->id;
|
||||
return o->id;
|
||||
}
|
||||
|
||||
static void stats_del_blk(unsigned id)
|
||||
{
|
||||
struct mem_blk *o, **i;
|
||||
struct mem_blk *o, **i;
|
||||
|
||||
i = &mstats.blk;
|
||||
for (o = mstats.blk; o; o = o->next) {
|
||||
if (o->id == id) {
|
||||
*i = o->next;
|
||||
free(o);
|
||||
return;
|
||||
}
|
||||
i = &o->next;
|
||||
}
|
||||
i = &mstats.blk;
|
||||
for (o = mstats.blk; o; o = o->next) {
|
||||
if (o->id == id) {
|
||||
*i = o->next;
|
||||
free(o);
|
||||
return;
|
||||
}
|
||||
i = &o->next;
|
||||
}
|
||||
|
||||
EXIT(_("Block not found"));
|
||||
/* NOTREACHED */
|
||||
EXIT(_("Block not found"));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void *dbg_malloc(size_t size, const char *pos)
|
||||
{
|
||||
unsigned *buf;
|
||||
unsigned *buf;
|
||||
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
size = EXTRA_SPACE + (size + sizeof(unsigned) - 1) / sizeof(unsigned);
|
||||
buf = xmalloc(size * sizeof(unsigned));
|
||||
size =
|
||||
EXTRA_SPACE + (size + sizeof(unsigned) - 1) / sizeof(unsigned);
|
||||
buf = xmalloc(size * sizeof(unsigned));
|
||||
|
||||
buf[BLK_STATE] = MAGIC_ALLOC; /* state of the block */
|
||||
buf[BLK_SIZE] = size; /* size of the block */
|
||||
buf[BLK_ID] = stats_add_blk(size, pos); /* identify a block by its id */
|
||||
buf[size - 1] = buf[BLK_ID]; /* mark at end of block */
|
||||
buf[BLK_STATE] = MAGIC_ALLOC; /* state of the block */
|
||||
buf[BLK_SIZE] = size; /* size of the block */
|
||||
buf[BLK_ID] = stats_add_blk(size, pos); /* identify a block by its id */
|
||||
buf[size - 1] = buf[BLK_ID]; /* mark at end of block */
|
||||
|
||||
mstats.nalloc += size;
|
||||
mstats.nalloc += size;
|
||||
|
||||
return (void *)(buf + EXTRA_SPACE_START);
|
||||
return (void *)(buf + EXTRA_SPACE_START);
|
||||
}
|
||||
|
||||
void *dbg_calloc(size_t nmemb, size_t size, const char *pos)
|
||||
{
|
||||
void *buf;
|
||||
void *buf;
|
||||
|
||||
if (!nmemb || !size)
|
||||
return NULL;
|
||||
if (!nmemb || !size)
|
||||
return NULL;
|
||||
|
||||
EXIT_IF(nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
|
||||
EXIT_IF(nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
|
||||
|
||||
size *= nmemb;
|
||||
if ((buf = dbg_malloc(size, pos)) == NULL)
|
||||
return NULL;
|
||||
size *= nmemb;
|
||||
if ((buf = dbg_malloc(size, pos)) == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(buf, 0, size);
|
||||
memset(buf, 0, size);
|
||||
|
||||
return buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void *dbg_realloc(void *ptr, size_t nmemb, size_t size, const char *pos)
|
||||
{
|
||||
unsigned *buf, old_size, new_size, cpy_size;
|
||||
unsigned *buf, old_size, new_size, cpy_size;
|
||||
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
new_size = nmemb * size;
|
||||
if (new_size == 0)
|
||||
return NULL;
|
||||
new_size = nmemb * size;
|
||||
if (new_size == 0)
|
||||
return NULL;
|
||||
|
||||
EXIT_IF(nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
|
||||
EXIT_IF(nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
|
||||
|
||||
if ((buf = dbg_malloc(new_size, pos)) == NULL)
|
||||
return NULL;
|
||||
if ((buf = dbg_malloc(new_size, pos)) == NULL)
|
||||
return NULL;
|
||||
|
||||
old_size = *((unsigned *)ptr - EXTRA_SPACE_START + BLK_SIZE);
|
||||
cpy_size = (old_size > new_size) ? new_size : old_size;
|
||||
memmove(buf, ptr, cpy_size);
|
||||
old_size = *((unsigned *)ptr - EXTRA_SPACE_START + BLK_SIZE);
|
||||
cpy_size = (old_size > new_size) ? new_size : old_size;
|
||||
memmove(buf, ptr, cpy_size);
|
||||
|
||||
mem_free(ptr);
|
||||
mem_free(ptr);
|
||||
|
||||
return (void *)buf;
|
||||
return (void *)buf;
|
||||
}
|
||||
|
||||
char *dbg_strdup(const char *s, const char *pos)
|
||||
{
|
||||
size_t size;
|
||||
char *buf;
|
||||
size_t size;
|
||||
char *buf;
|
||||
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
size = strlen(s);
|
||||
if ((buf = dbg_malloc(size + 1, pos)) == NULL)
|
||||
return NULL;
|
||||
size = strlen(s);
|
||||
if ((buf = dbg_malloc(size + 1, pos)) == NULL)
|
||||
return NULL;
|
||||
|
||||
return strncpy(buf, s, size + 1);
|
||||
return strncpy(buf, s, size + 1);
|
||||
}
|
||||
|
||||
void dbg_free(void *ptr, const char *pos)
|
||||
{
|
||||
unsigned *buf, size;
|
||||
unsigned *buf, size;
|
||||
|
||||
EXIT_IF(ptr == NULL, _("dbg_free: null pointer at %s"), pos);
|
||||
EXIT_IF(ptr == NULL, _("dbg_free: null pointer at %s"), pos);
|
||||
|
||||
buf = (unsigned *)ptr - EXTRA_SPACE_START;
|
||||
size = buf[BLK_SIZE];
|
||||
buf = (unsigned *)ptr - EXTRA_SPACE_START;
|
||||
size = buf[BLK_SIZE];
|
||||
|
||||
EXIT_IF(buf[BLK_STATE] == MAGIC_FREE,
|
||||
_("block seems already freed at %s"), pos);
|
||||
EXIT_IF(buf[BLK_STATE] != MAGIC_ALLOC, _("corrupt block header at %s"), pos);
|
||||
EXIT_IF(buf[size - 1] != buf[BLK_ID],
|
||||
_("corrupt block end at %s, (end = %u, should be %d)"), pos,
|
||||
buf[size - 1], buf[BLK_ID]);
|
||||
EXIT_IF(buf[BLK_STATE] == MAGIC_FREE,
|
||||
_("block seems already freed at %s"), pos);
|
||||
EXIT_IF(buf[BLK_STATE] != MAGIC_ALLOC,
|
||||
_("corrupt block header at %s"), pos);
|
||||
EXIT_IF(buf[size - 1] != buf[BLK_ID],
|
||||
_("corrupt block end at %s, (end = %u, should be %d)"),
|
||||
pos, buf[size - 1], buf[BLK_ID]);
|
||||
|
||||
buf[0] = MAGIC_FREE;
|
||||
buf[0] = MAGIC_FREE;
|
||||
|
||||
stats_del_blk(buf[BLK_ID]);
|
||||
stats_del_blk(buf[BLK_ID]);
|
||||
|
||||
free(buf);
|
||||
mstats.nfree += size;
|
||||
free(buf);
|
||||
mstats.nfree += size;
|
||||
}
|
||||
|
||||
static void dump_block_info(struct mem_blk *blk)
|
||||
{
|
||||
if (blk == NULL)
|
||||
return;
|
||||
if (blk == NULL)
|
||||
return;
|
||||
|
||||
puts(_("---==== MEMORY BLOCK ====----------------\n"));
|
||||
printf(_(" id: %u\n"), blk->id);
|
||||
printf(_(" size: %u\n"), blk->size);
|
||||
printf(_(" allocated in: %s\n"), blk->pos);
|
||||
puts(_("-----------------------------------------\n"));
|
||||
puts(_("---==== MEMORY BLOCK ====----------------\n"));
|
||||
printf(_(" id: %u\n"), blk->id);
|
||||
printf(_(" size: %u\n"), blk->size);
|
||||
printf(_(" allocated in: %s\n"), blk->pos);
|
||||
puts(_("-----------------------------------------\n"));
|
||||
}
|
||||
|
||||
void mem_stats(void)
|
||||
{
|
||||
putchar('\n');
|
||||
puts(_("+------------------------------+\n"));
|
||||
puts(_("| calcurse memory usage report |\n"));
|
||||
puts(_("+------------------------------+\n"));
|
||||
printf(_(" number of calls: %u\n"), mstats.ncall);
|
||||
printf(_(" allocated blocks: %u\n"), mstats.nalloc);
|
||||
printf(_(" unfreed blocks: %u\n"), mstats.nalloc - mstats.nfree);
|
||||
putchar('\n');
|
||||
putchar('\n');
|
||||
puts(_("+------------------------------+\n"));
|
||||
puts(_("| calcurse memory usage report |\n"));
|
||||
puts(_("+------------------------------+\n"));
|
||||
printf(_(" number of calls: %u\n"), mstats.ncall);
|
||||
printf(_(" allocated blocks: %u\n"), mstats.nalloc);
|
||||
printf(_(" unfreed blocks: %u\n"), mstats.nalloc - mstats.nfree);
|
||||
putchar('\n');
|
||||
|
||||
if (mstats.nfree < mstats.nalloc) {
|
||||
struct mem_blk *blk;
|
||||
if (mstats.nfree < mstats.nalloc) {
|
||||
struct mem_blk *blk;
|
||||
|
||||
for (blk = mstats.blk; blk; blk = blk->next)
|
||||
dump_block_info(blk);
|
||||
}
|
||||
for (blk = mstats.blk; blk; blk = blk->next)
|
||||
dump_block_info(blk);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CALCURSE_MEMORY_DEBUG */
|
||||
|
248
src/note.c
248
src/note.c
@ -41,12 +41,13 @@
|
||||
#include "sha1.h"
|
||||
|
||||
struct note_gc_hash {
|
||||
char *hash;
|
||||
char buf[MAX_NOTESIZ + 1];
|
||||
HTABLE_ENTRY(note_gc_hash);
|
||||
char *hash;
|
||||
char buf[MAX_NOTESIZ + 1];
|
||||
HTABLE_ENTRY(note_gc_hash);
|
||||
};
|
||||
|
||||
static void note_gc_extract_key(struct note_gc_hash *, const char **, int *);
|
||||
static void note_gc_extract_key(struct note_gc_hash *, const char **,
|
||||
int *);
|
||||
static int note_gc_cmp(struct note_gc_hash *, struct note_gc_hash *);
|
||||
|
||||
HTABLE_HEAD(htp, NOTE_GC_HSIZE, note_gc_hash);
|
||||
@ -57,179 +58,180 @@ HTABLE_PROTOTYPE(htp, note_gc_hash)
|
||||
* contains its name. */
|
||||
char *generate_note(const char *str)
|
||||
{
|
||||
char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
|
||||
char notepath[BUFSIZ];
|
||||
FILE *fp;
|
||||
char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
|
||||
char notepath[BUFSIZ];
|
||||
FILE *fp;
|
||||
|
||||
sha1_digest(str, sha1);
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, sha1);
|
||||
fp = fopen(notepath, "w");
|
||||
EXIT_IF(fp == NULL, _("Warning: could not open %s, Aborting..."), notepath);
|
||||
fputs(str, fp);
|
||||
file_close(fp, __FILE_POS__);
|
||||
sha1_digest(str, sha1);
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, sha1);
|
||||
fp = fopen(notepath, "w");
|
||||
EXIT_IF(fp == NULL, _("Warning: could not open %s, Aborting..."),
|
||||
notepath);
|
||||
fputs(str, fp);
|
||||
file_close(fp, __FILE_POS__);
|
||||
|
||||
return sha1;
|
||||
return sha1;
|
||||
}
|
||||
|
||||
/* Edit a note with an external editor. */
|
||||
void edit_note(char **note, const char *editor)
|
||||
{
|
||||
char tmppath[BUFSIZ];
|
||||
char *tmpext;
|
||||
char notepath[BUFSIZ];
|
||||
char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
|
||||
FILE *fp;
|
||||
char tmppath[BUFSIZ];
|
||||
char *tmpext;
|
||||
char notepath[BUFSIZ];
|
||||
char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
|
||||
FILE *fp;
|
||||
|
||||
strncpy(tmppath, get_tempdir(), BUFSIZ);
|
||||
strncat(tmppath, "/calcurse-note.", BUFSIZ - strlen(tmppath) - 1);
|
||||
if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
|
||||
return;
|
||||
strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
|
||||
mem_free(tmpext);
|
||||
strncpy(tmppath, get_tempdir(), BUFSIZ);
|
||||
strncat(tmppath, "/calcurse-note.", BUFSIZ - strlen(tmppath) - 1);
|
||||
if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
|
||||
return;
|
||||
strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
|
||||
mem_free(tmpext);
|
||||
|
||||
if (*note != NULL) {
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, *note);
|
||||
io_file_cp(notepath, tmppath);
|
||||
}
|
||||
if (*note != NULL) {
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, *note);
|
||||
io_file_cp(notepath, tmppath);
|
||||
}
|
||||
|
||||
wins_launch_external(tmppath, editor);
|
||||
wins_launch_external(tmppath, editor);
|
||||
|
||||
if (io_file_is_empty(tmppath) > 0) {
|
||||
erase_note(note);
|
||||
} else if ((fp = fopen(tmppath, "r"))) {
|
||||
sha1_stream(fp, sha1);
|
||||
fclose(fp);
|
||||
*note = sha1;
|
||||
if (io_file_is_empty(tmppath) > 0) {
|
||||
erase_note(note);
|
||||
} else if ((fp = fopen(tmppath, "r"))) {
|
||||
sha1_stream(fp, sha1);
|
||||
fclose(fp);
|
||||
*note = sha1;
|
||||
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, *note);
|
||||
io_file_cp(tmppath, notepath);
|
||||
}
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, *note);
|
||||
io_file_cp(tmppath, notepath);
|
||||
}
|
||||
|
||||
unlink(tmppath);
|
||||
unlink(tmppath);
|
||||
}
|
||||
|
||||
/* View a note in an external pager. */
|
||||
void view_note(const char *note, const char *pager)
|
||||
{
|
||||
char fullname[BUFSIZ];
|
||||
char fullname[BUFSIZ];
|
||||
|
||||
if (note == NULL)
|
||||
return;
|
||||
snprintf(fullname, BUFSIZ, "%s%s", path_notes, note);
|
||||
wins_launch_external(fullname, pager);
|
||||
if (note == NULL)
|
||||
return;
|
||||
snprintf(fullname, BUFSIZ, "%s%s", path_notes, note);
|
||||
wins_launch_external(fullname, pager);
|
||||
}
|
||||
|
||||
/* Erase a note previously attached to an item. */
|
||||
void erase_note(char **note)
|
||||
{
|
||||
if (*note == NULL)
|
||||
return;
|
||||
mem_free(*note);
|
||||
*note = NULL;
|
||||
if (*note == NULL)
|
||||
return;
|
||||
mem_free(*note);
|
||||
*note = NULL;
|
||||
}
|
||||
|
||||
/* Read a serialized note file name from a stream and deserialize it. */
|
||||
void note_read(char *buffer, FILE * fp)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_NOTESIZ; i++) {
|
||||
buffer[i] = getc(fp);
|
||||
if (buffer[i] == ' ') {
|
||||
buffer[i] = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_NOTESIZ; i++) {
|
||||
buffer[i] = getc(fp);
|
||||
if (buffer[i] == ' ') {
|
||||
buffer[i] = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (getc(fp) != ' ') ;
|
||||
buffer[MAX_NOTESIZ] = '\0';
|
||||
while (getc(fp) != ' ') ;
|
||||
buffer[MAX_NOTESIZ] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
note_gc_extract_key(struct note_gc_hash *data, const char **key, int *len)
|
||||
{
|
||||
*key = data->hash;
|
||||
*len = strlen(data->hash);
|
||||
*key = data->hash;
|
||||
*len = strlen(data->hash);
|
||||
}
|
||||
|
||||
static int note_gc_cmp(struct note_gc_hash *a, struct note_gc_hash *b)
|
||||
{
|
||||
return strcmp(a->hash, b->hash);
|
||||
return strcmp(a->hash, b->hash);
|
||||
}
|
||||
|
||||
/* Spot and unlink unused note files. */
|
||||
void note_gc(void)
|
||||
{
|
||||
struct htp gc_htable = HTABLE_INITIALIZER(&gc_htable);
|
||||
struct note_gc_hash *hp;
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
llist_item_t *i;
|
||||
struct note_gc_hash tmph;
|
||||
char notepath[BUFSIZ];
|
||||
struct htp gc_htable = HTABLE_INITIALIZER(&gc_htable);
|
||||
struct note_gc_hash *hp;
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
llist_item_t *i;
|
||||
struct note_gc_hash tmph;
|
||||
char notepath[BUFSIZ];
|
||||
|
||||
if (!(dirp = opendir(path_notes)))
|
||||
return;
|
||||
if (!(dirp = opendir(path_notes)))
|
||||
return;
|
||||
|
||||
/* Insert all note file names into a hash table. */
|
||||
do {
|
||||
if ((dp = readdir(dirp)) && *(dp->d_name) != '.') {
|
||||
hp = mem_malloc(sizeof(struct note_gc_hash));
|
||||
/* Insert all note file names into a hash table. */
|
||||
do {
|
||||
if ((dp = readdir(dirp)) && *(dp->d_name) != '.') {
|
||||
hp = mem_malloc(sizeof(struct note_gc_hash));
|
||||
|
||||
strncpy(hp->buf, dp->d_name, MAX_NOTESIZ + 1);
|
||||
hp->hash = hp->buf;
|
||||
strncpy(hp->buf, dp->d_name, MAX_NOTESIZ + 1);
|
||||
hp->hash = hp->buf;
|
||||
|
||||
HTABLE_INSERT(htp, &gc_htable, hp);
|
||||
}
|
||||
}
|
||||
while (dp);
|
||||
HTABLE_INSERT(htp, &gc_htable, hp);
|
||||
}
|
||||
}
|
||||
while (dp);
|
||||
|
||||
closedir(dirp);
|
||||
closedir(dirp);
|
||||
|
||||
/* Remove hashes that are actually in use. */
|
||||
LLIST_TS_FOREACH(&alist_p, i) {
|
||||
struct apoint *apt = LLIST_GET_DATA(i);
|
||||
if (apt->note) {
|
||||
tmph.hash = apt->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
/* Remove hashes that are actually in use. */
|
||||
LLIST_TS_FOREACH(&alist_p, i) {
|
||||
struct apoint *apt = LLIST_GET_DATA(i);
|
||||
if (apt->note) {
|
||||
tmph.hash = apt->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
|
||||
LLIST_FOREACH(&eventlist, i) {
|
||||
struct event *ev = LLIST_GET_DATA(i);
|
||||
if (ev->note) {
|
||||
tmph.hash = ev->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
LLIST_FOREACH(&eventlist, i) {
|
||||
struct event *ev = LLIST_GET_DATA(i);
|
||||
if (ev->note) {
|
||||
tmph.hash = ev->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
|
||||
LLIST_TS_FOREACH(&recur_alist_p, i) {
|
||||
struct recur_apoint *rapt = LLIST_GET_DATA(i);
|
||||
if (rapt->note) {
|
||||
tmph.hash = rapt->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
LLIST_TS_FOREACH(&recur_alist_p, i) {
|
||||
struct recur_apoint *rapt = LLIST_GET_DATA(i);
|
||||
if (rapt->note) {
|
||||
tmph.hash = rapt->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
|
||||
LLIST_FOREACH(&recur_elist, i) {
|
||||
struct recur_event *rev = LLIST_GET_DATA(i);
|
||||
if (rev->note) {
|
||||
tmph.hash = rev->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
LLIST_FOREACH(&recur_elist, i) {
|
||||
struct recur_event *rev = LLIST_GET_DATA(i);
|
||||
if (rev->note) {
|
||||
tmph.hash = rev->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
struct todo *todo = LLIST_GET_DATA(i);
|
||||
if (todo->note) {
|
||||
tmph.hash = todo->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
struct todo *todo = LLIST_GET_DATA(i);
|
||||
if (todo->note) {
|
||||
tmph.hash = todo->note;
|
||||
free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlink unused note files. */
|
||||
HTABLE_FOREACH(hp, htp, &gc_htable) {
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, hp->hash);
|
||||
unlink(notepath);
|
||||
}
|
||||
/* Unlink unused note files. */
|
||||
HTABLE_FOREACH(hp, htp, &gc_htable) {
|
||||
snprintf(notepath, BUFSIZ, "%s%s", path_notes, hp->hash);
|
||||
unlink(notepath);
|
||||
}
|
||||
}
|
||||
|
1018
src/notify.c
1018
src/notify.c
File diff suppressed because it is too large
Load Diff
384
src/pcal.c
384
src/pcal.c
@ -56,55 +56,60 @@ typedef void (*cb_dump_t) (FILE *, long, long, char *);
|
||||
*/
|
||||
static void
|
||||
foreach_date_dump(const long date_end, struct rpt *rpt, llist_t * exc,
|
||||
long item_first_date, long item_dur, char *item_mesg,
|
||||
cb_dump_t cb_dump, FILE * stream)
|
||||
long item_first_date, long item_dur, char *item_mesg,
|
||||
cb_dump_t cb_dump, FILE * stream)
|
||||
{
|
||||
long date, item_time;
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
long date, item_time;
|
||||
struct tm lt;
|
||||
time_t t;
|
||||
|
||||
t = item_first_date;
|
||||
localtime_r(&t, <);
|
||||
lt.tm_hour = lt.tm_min = lt.tm_sec = 0;
|
||||
lt.tm_isdst = -1;
|
||||
date = mktime(<);
|
||||
item_time = item_first_date - date;
|
||||
t = item_first_date;
|
||||
localtime_r(&t, <);
|
||||
lt.tm_hour = lt.tm_min = lt.tm_sec = 0;
|
||||
lt.tm_isdst = -1;
|
||||
date = mktime(<);
|
||||
item_time = item_first_date - date;
|
||||
|
||||
while (date <= date_end && date <= rpt->until) {
|
||||
if (recur_item_inday(item_first_date, item_dur, exc, rpt->type,
|
||||
rpt->freq, rpt->until, date)) {
|
||||
(*cb_dump) (stream, date + item_time, item_dur, item_mesg);
|
||||
}
|
||||
switch (rpt->type) {
|
||||
case RECUR_DAILY:
|
||||
date = date_sec_change(date, 0, rpt->freq);
|
||||
break;
|
||||
case RECUR_WEEKLY:
|
||||
date = date_sec_change(date, 0, rpt->freq * WEEKINDAYS);
|
||||
break;
|
||||
case RECUR_MONTHLY:
|
||||
date = date_sec_change(date, rpt->freq, 0);
|
||||
break;
|
||||
case RECUR_YEARLY:
|
||||
date = date_sec_change(date, rpt->freq * 12, 0);
|
||||
break;
|
||||
default:
|
||||
EXIT(_("incoherent repetition type"));
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (date <= date_end && date <= rpt->until) {
|
||||
if (recur_item_inday
|
||||
(item_first_date, item_dur, exc, rpt->type, rpt->freq,
|
||||
rpt->until, date)) {
|
||||
(*cb_dump) (stream, date + item_time, item_dur,
|
||||
item_mesg);
|
||||
}
|
||||
switch (rpt->type) {
|
||||
case RECUR_DAILY:
|
||||
date = date_sec_change(date, 0, rpt->freq);
|
||||
break;
|
||||
case RECUR_WEEKLY:
|
||||
date =
|
||||
date_sec_change(date, 0,
|
||||
rpt->freq * WEEKINDAYS);
|
||||
break;
|
||||
case RECUR_MONTHLY:
|
||||
date = date_sec_change(date, rpt->freq, 0);
|
||||
break;
|
||||
case RECUR_YEARLY:
|
||||
date = date_sec_change(date, rpt->freq * 12, 0);
|
||||
break;
|
||||
default:
|
||||
EXIT(_("incoherent repetition type"));
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pcal_export_header(FILE * stream)
|
||||
{
|
||||
fputs("# calcurse pcal export\n", stream);
|
||||
fputs("\n# =======\n# options\n# =======\n", stream);
|
||||
fprintf(stream, "opt -A -K -l -m -F %s\n",
|
||||
ui_calendar_week_begins_on_monday()? "Monday" : "Sunday");
|
||||
fputs("# Display week number (i.e. 1-52) on every Monday\n", stream);
|
||||
fprintf(stream, "all monday in all week %%w\n");
|
||||
fputc('\n', stream);
|
||||
fputs("# calcurse pcal export\n", stream);
|
||||
fputs("\n# =======\n# options\n# =======\n", stream);
|
||||
fprintf(stream, "opt -A -K -l -m -F %s\n",
|
||||
ui_calendar_week_begins_on_monday()? "Monday" : "Sunday");
|
||||
fputs("# Display week number (i.e. 1-52) on every Monday\n",
|
||||
stream);
|
||||
fprintf(stream, "all monday in all week %%w\n");
|
||||
fputc('\n', stream);
|
||||
}
|
||||
|
||||
static void pcal_export_footer(FILE * stream)
|
||||
@ -114,178 +119,215 @@ static void pcal_export_footer(FILE * stream)
|
||||
/* Format and dump event data to a pcal formatted file. */
|
||||
static void
|
||||
pcal_dump_event(FILE * stream, long event_date, long event_dur,
|
||||
char *event_mesg)
|
||||
char *event_mesg)
|
||||
{
|
||||
char pcal_date[BUFSIZ];
|
||||
char pcal_date[BUFSIZ];
|
||||
|
||||
date_sec2date_fmt(event_date, "%b %d", pcal_date);
|
||||
fprintf(stream, "%s %s\n", pcal_date, event_mesg);
|
||||
date_sec2date_fmt(event_date, "%b %d", pcal_date);
|
||||
fprintf(stream, "%s %s\n", pcal_date, event_mesg);
|
||||
}
|
||||
|
||||
/* Format and dump appointment data to a pcal formatted file. */
|
||||
static void
|
||||
pcal_dump_apoint(FILE * stream, long apoint_date, long apoint_dur,
|
||||
char *apoint_mesg)
|
||||
char *apoint_mesg)
|
||||
{
|
||||
char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
|
||||
char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
|
||||
|
||||
date_sec2date_fmt(apoint_date, "%b %d", pcal_date);
|
||||
date_sec2date_fmt(apoint_date, "%R", pcal_beg);
|
||||
date_sec2date_fmt(apoint_date + apoint_dur, "%R", pcal_end);
|
||||
fprintf(stream, "%s ", pcal_date);
|
||||
fprintf(stream, "(%s -> %s) %s\n", pcal_beg, pcal_end, apoint_mesg);
|
||||
date_sec2date_fmt(apoint_date, "%b %d", pcal_date);
|
||||
date_sec2date_fmt(apoint_date, "%R", pcal_beg);
|
||||
date_sec2date_fmt(apoint_date + apoint_dur, "%R", pcal_end);
|
||||
fprintf(stream, "%s ", pcal_date);
|
||||
fprintf(stream, "(%s -> %s) %s\n", pcal_beg, pcal_end,
|
||||
apoint_mesg);
|
||||
}
|
||||
|
||||
static void pcal_export_recur_events(FILE * stream)
|
||||
{
|
||||
llist_item_t *i;
|
||||
char pcal_date[BUFSIZ];
|
||||
llist_item_t *i;
|
||||
char pcal_date[BUFSIZ];
|
||||
|
||||
fputs("\n# =============", stream);
|
||||
fputs("\n# Recur. Events", stream);
|
||||
fputs("\n# =============\n", stream);
|
||||
fputs("# (pcal does not support from..until dates specification\n", stream);
|
||||
fputs("\n# =============", stream);
|
||||
fputs("\n# Recur. Events", stream);
|
||||
fputs("\n# =============\n", stream);
|
||||
fputs("# (pcal does not support from..until dates specification\n",
|
||||
stream);
|
||||
|
||||
LLIST_FOREACH(&recur_elist, i) {
|
||||
struct recur_event *rev = LLIST_GET_DATA(i);
|
||||
if (rev->rpt->until == 0 && rev->rpt->freq == 1) {
|
||||
switch (rev->rpt->type) {
|
||||
case RECUR_DAILY:
|
||||
date_sec2date_fmt(rev->day, "%b %d", pcal_date);
|
||||
fprintf(stream, "all day on_or_after %s %s\n", pcal_date, rev->mesg);
|
||||
break;
|
||||
case RECUR_WEEKLY:
|
||||
date_sec2date_fmt(rev->day, "%a", pcal_date);
|
||||
fprintf(stream, "all %s on_or_after ", pcal_date);
|
||||
date_sec2date_fmt(rev->day, "%b %d", pcal_date);
|
||||
fprintf(stream, "%s %s\n", pcal_date, rev->mesg);
|
||||
break;
|
||||
case RECUR_MONTHLY:
|
||||
date_sec2date_fmt(rev->day, "%d", pcal_date);
|
||||
fprintf(stream, "day on all %s %s\n", pcal_date, rev->mesg);
|
||||
break;
|
||||
case RECUR_YEARLY:
|
||||
date_sec2date_fmt(rev->day, "%b %d", pcal_date);
|
||||
fprintf(stream, "%s %s\n", pcal_date, rev->mesg);
|
||||
break;
|
||||
default:
|
||||
EXIT(_("incoherent repetition type"));
|
||||
}
|
||||
} else {
|
||||
const long YEAR_START = ui_calendar_start_of_year();
|
||||
const long YEAR_END = ui_calendar_end_of_year();
|
||||
LLIST_FOREACH(&recur_elist, i) {
|
||||
struct recur_event *rev = LLIST_GET_DATA(i);
|
||||
if (rev->rpt->until == 0 && rev->rpt->freq == 1) {
|
||||
switch (rev->rpt->type) {
|
||||
case RECUR_DAILY:
|
||||
date_sec2date_fmt(rev->day, "%b %d",
|
||||
pcal_date);
|
||||
fprintf(stream,
|
||||
"all day on_or_after %s %s\n",
|
||||
pcal_date, rev->mesg);
|
||||
break;
|
||||
case RECUR_WEEKLY:
|
||||
date_sec2date_fmt(rev->day, "%a",
|
||||
pcal_date);
|
||||
fprintf(stream, "all %s on_or_after ",
|
||||
pcal_date);
|
||||
date_sec2date_fmt(rev->day, "%b %d",
|
||||
pcal_date);
|
||||
fprintf(stream, "%s %s\n", pcal_date,
|
||||
rev->mesg);
|
||||
break;
|
||||
case RECUR_MONTHLY:
|
||||
date_sec2date_fmt(rev->day, "%d",
|
||||
pcal_date);
|
||||
fprintf(stream, "day on all %s %s\n",
|
||||
pcal_date, rev->mesg);
|
||||
break;
|
||||
case RECUR_YEARLY:
|
||||
date_sec2date_fmt(rev->day, "%b %d",
|
||||
pcal_date);
|
||||
fprintf(stream, "%s %s\n", pcal_date,
|
||||
rev->mesg);
|
||||
break;
|
||||
default:
|
||||
EXIT(_("incoherent repetition type"));
|
||||
}
|
||||
} else {
|
||||
const long YEAR_START =
|
||||
ui_calendar_start_of_year();
|
||||
const long YEAR_END = ui_calendar_end_of_year();
|
||||
|
||||
if (rev->day < YEAR_END && rev->day > YEAR_START)
|
||||
foreach_date_dump(YEAR_END, rev->rpt, &rev->exc, rev->day, 0,
|
||||
rev->mesg, (cb_dump_t) pcal_dump_event, stream);
|
||||
}
|
||||
}
|
||||
if (rev->day < YEAR_END && rev->day > YEAR_START)
|
||||
foreach_date_dump(YEAR_END, rev->rpt,
|
||||
&rev->exc, rev->day, 0,
|
||||
rev->mesg,
|
||||
(cb_dump_t)
|
||||
pcal_dump_event, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pcal_export_events(FILE * stream)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
fputs("\n# ======\n# Events\n# ======\n", stream);
|
||||
LLIST_FOREACH(&eventlist, i) {
|
||||
struct event *ev = LLIST_TS_GET_DATA(i);
|
||||
pcal_dump_event(stream, ev->day, 0, ev->mesg);
|
||||
}
|
||||
fputc('\n', stream);
|
||||
fputs("\n# ======\n# Events\n# ======\n", stream);
|
||||
LLIST_FOREACH(&eventlist, i) {
|
||||
struct event *ev = LLIST_TS_GET_DATA(i);
|
||||
pcal_dump_event(stream, ev->day, 0, ev->mesg);
|
||||
}
|
||||
fputc('\n', stream);
|
||||
}
|
||||
|
||||
static void pcal_export_recur_apoints(FILE * stream)
|
||||
{
|
||||
llist_item_t *i;
|
||||
char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
|
||||
llist_item_t *i;
|
||||
char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
|
||||
|
||||
fputs("\n# ==============", stream);
|
||||
fputs("\n# Recur. Apoints", stream);
|
||||
fputs("\n# ==============\n", stream);
|
||||
fputs("# (pcal does not support from..until dates specification\n", stream);
|
||||
fputs("\n# ==============", stream);
|
||||
fputs("\n# Recur. Apoints", stream);
|
||||
fputs("\n# ==============\n", stream);
|
||||
fputs("# (pcal does not support from..until dates specification\n",
|
||||
stream);
|
||||
|
||||
LLIST_TS_FOREACH(&recur_alist_p, i) {
|
||||
struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
|
||||
LLIST_TS_FOREACH(&recur_alist_p, i) {
|
||||
struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
|
||||
|
||||
if (rapt->rpt->until == 0 && rapt->rpt->freq == 1) {
|
||||
date_sec2date_fmt(rapt->start, "%R", pcal_beg);
|
||||
date_sec2date_fmt(rapt->start + rapt->dur, "%R", pcal_end);
|
||||
switch (rapt->rpt->type) {
|
||||
case RECUR_DAILY:
|
||||
date_sec2date_fmt(rapt->start, "%b %d", pcal_date);
|
||||
fprintf(stream, "all day on_or_after %s (%s -> %s) %s\n",
|
||||
pcal_date, pcal_beg, pcal_end, rapt->mesg);
|
||||
break;
|
||||
case RECUR_WEEKLY:
|
||||
date_sec2date_fmt(rapt->start, "%a", pcal_date);
|
||||
fprintf(stream, "all %s on_or_after ", pcal_date);
|
||||
date_sec2date_fmt(rapt->start, "%b %d", pcal_date);
|
||||
fprintf(stream, "%s (%s -> %s) %s\n", pcal_date, pcal_beg,
|
||||
pcal_end, rapt->mesg);
|
||||
break;
|
||||
case RECUR_MONTHLY:
|
||||
date_sec2date_fmt(rapt->start, "%d", pcal_date);
|
||||
fprintf(stream, "day on all %s (%s -> %s) %s\n", pcal_date,
|
||||
pcal_beg, pcal_end, rapt->mesg);
|
||||
break;
|
||||
case RECUR_YEARLY:
|
||||
date_sec2date_fmt(rapt->start, "%b %d", pcal_date);
|
||||
fprintf(stream, "%s (%s -> %s) %s\n", pcal_date, pcal_beg,
|
||||
pcal_end, rapt->mesg);
|
||||
break;
|
||||
default:
|
||||
EXIT(_("incoherent repetition type"));
|
||||
}
|
||||
} else {
|
||||
const long YEAR_START = ui_calendar_start_of_year();
|
||||
const long YEAR_END = ui_calendar_end_of_year();
|
||||
if (rapt->rpt->until == 0 && rapt->rpt->freq == 1) {
|
||||
date_sec2date_fmt(rapt->start, "%R", pcal_beg);
|
||||
date_sec2date_fmt(rapt->start + rapt->dur, "%R",
|
||||
pcal_end);
|
||||
switch (rapt->rpt->type) {
|
||||
case RECUR_DAILY:
|
||||
date_sec2date_fmt(rapt->start, "%b %d",
|
||||
pcal_date);
|
||||
fprintf(stream,
|
||||
"all day on_or_after %s (%s -> %s) %s\n",
|
||||
pcal_date, pcal_beg, pcal_end,
|
||||
rapt->mesg);
|
||||
break;
|
||||
case RECUR_WEEKLY:
|
||||
date_sec2date_fmt(rapt->start, "%a",
|
||||
pcal_date);
|
||||
fprintf(stream, "all %s on_or_after ",
|
||||
pcal_date);
|
||||
date_sec2date_fmt(rapt->start, "%b %d",
|
||||
pcal_date);
|
||||
fprintf(stream, "%s (%s -> %s) %s\n",
|
||||
pcal_date, pcal_beg, pcal_end,
|
||||
rapt->mesg);
|
||||
break;
|
||||
case RECUR_MONTHLY:
|
||||
date_sec2date_fmt(rapt->start, "%d",
|
||||
pcal_date);
|
||||
fprintf(stream,
|
||||
"day on all %s (%s -> %s) %s\n",
|
||||
pcal_date, pcal_beg, pcal_end,
|
||||
rapt->mesg);
|
||||
break;
|
||||
case RECUR_YEARLY:
|
||||
date_sec2date_fmt(rapt->start, "%b %d",
|
||||
pcal_date);
|
||||
fprintf(stream, "%s (%s -> %s) %s\n",
|
||||
pcal_date, pcal_beg, pcal_end,
|
||||
rapt->mesg);
|
||||
break;
|
||||
default:
|
||||
EXIT(_("incoherent repetition type"));
|
||||
}
|
||||
} else {
|
||||
const long YEAR_START =
|
||||
ui_calendar_start_of_year();
|
||||
const long YEAR_END = ui_calendar_end_of_year();
|
||||
|
||||
if (rapt->start < YEAR_END && rapt->start > YEAR_START)
|
||||
foreach_date_dump(YEAR_END, rapt->rpt, &rapt->exc, rapt->start,
|
||||
rapt->dur, rapt->mesg,
|
||||
(cb_dump_t) pcal_dump_apoint, stream);
|
||||
}
|
||||
}
|
||||
if (rapt->start < YEAR_END
|
||||
&& rapt->start > YEAR_START)
|
||||
foreach_date_dump(YEAR_END, rapt->rpt,
|
||||
&rapt->exc, rapt->start,
|
||||
rapt->dur, rapt->mesg,
|
||||
(cb_dump_t)
|
||||
pcal_dump_apoint,
|
||||
stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pcal_export_apoints(FILE * stream)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
fputs("\n# ============\n# Appointments\n# ============\n", stream);
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_FOREACH(&alist_p, i) {
|
||||
struct apoint *apt = LLIST_TS_GET_DATA(i);
|
||||
pcal_dump_apoint(stream, apt->start, apt->dur, apt->mesg);
|
||||
}
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
fputc('\n', stream);
|
||||
fputs("\n# ============\n# Appointments\n# ============\n",
|
||||
stream);
|
||||
LLIST_TS_LOCK(&alist_p);
|
||||
LLIST_TS_FOREACH(&alist_p, i) {
|
||||
struct apoint *apt = LLIST_TS_GET_DATA(i);
|
||||
pcal_dump_apoint(stream, apt->start, apt->dur, apt->mesg);
|
||||
}
|
||||
LLIST_TS_UNLOCK(&alist_p);
|
||||
fputc('\n', stream);
|
||||
}
|
||||
|
||||
static void pcal_export_todo(FILE * stream)
|
||||
{
|
||||
llist_item_t *i;
|
||||
llist_item_t *i;
|
||||
|
||||
fputs("#\n# Todos\n#\n", stream);
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
struct todo *todo = LLIST_TS_GET_DATA(i);
|
||||
if (todo->id < 0) /* completed items */
|
||||
continue;
|
||||
fputs("#\n# Todos\n#\n", stream);
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
struct todo *todo = LLIST_TS_GET_DATA(i);
|
||||
if (todo->id < 0) /* completed items */
|
||||
continue;
|
||||
|
||||
fputs("note all ", stream);
|
||||
fprintf(stream, "%d. %s\n", todo->id, todo->mesg);
|
||||
}
|
||||
fputc('\n', stream);
|
||||
fputs("note all ", stream);
|
||||
fprintf(stream, "%d. %s\n", todo->id, todo->mesg);
|
||||
}
|
||||
fputc('\n', stream);
|
||||
}
|
||||
|
||||
/* Export calcurse data. */
|
||||
void pcal_export_data(FILE * stream)
|
||||
{
|
||||
pcal_export_header(stream);
|
||||
pcal_export_recur_events(stream);
|
||||
pcal_export_events(stream);
|
||||
pcal_export_recur_apoints(stream);
|
||||
pcal_export_apoints(stream);
|
||||
pcal_export_todo(stream);
|
||||
pcal_export_footer(stream);
|
||||
pcal_export_header(stream);
|
||||
pcal_export_recur_events(stream);
|
||||
pcal_export_events(stream);
|
||||
pcal_export_recur_apoints(stream);
|
||||
pcal_export_apoints(stream);
|
||||
pcal_export_todo(stream);
|
||||
pcal_export_footer(stream);
|
||||
}
|
||||
|
1031
src/recur.c
1031
src/recur.c
File diff suppressed because it is too large
Load Diff
321
src/sha1.c
321
src/sha1.c
@ -69,200 +69,203 @@
|
||||
|
||||
static void sha1_transform(uint32_t state[5], const uint8_t buffer[64])
|
||||
{
|
||||
typedef union {
|
||||
uint8_t c[64];
|
||||
uint32_t l[16];
|
||||
} b64_t;
|
||||
typedef union {
|
||||
uint8_t c[64];
|
||||
uint32_t l[16];
|
||||
} b64_t;
|
||||
|
||||
b64_t *block = (b64_t *) buffer;
|
||||
uint32_t a = state[0];
|
||||
uint32_t b = state[1];
|
||||
uint32_t c = state[2];
|
||||
uint32_t d = state[3];
|
||||
uint32_t e = state[4];
|
||||
b64_t *block = (b64_t *) buffer;
|
||||
uint32_t a = state[0];
|
||||
uint32_t b = state[1];
|
||||
uint32_t c = state[2];
|
||||
uint32_t d = state[3];
|
||||
uint32_t e = state[4];
|
||||
|
||||
R0(a, b, c, d, e, 0);
|
||||
R0(e, a, b, c, d, 1);
|
||||
R0(d, e, a, b, c, 2);
|
||||
R0(c, d, e, a, b, 3);
|
||||
R0(b, c, d, e, a, 4);
|
||||
R0(a, b, c, d, e, 5);
|
||||
R0(e, a, b, c, d, 6);
|
||||
R0(d, e, a, b, c, 7);
|
||||
R0(c, d, e, a, b, 8);
|
||||
R0(b, c, d, e, a, 9);
|
||||
R0(a, b, c, d, e, 10);
|
||||
R0(e, a, b, c, d, 11);
|
||||
R0(d, e, a, b, c, 12);
|
||||
R0(c, d, e, a, b, 13);
|
||||
R0(b, c, d, e, a, 14);
|
||||
R0(a, b, c, d, e, 15);
|
||||
R1(e, a, b, c, d, 16);
|
||||
R1(d, e, a, b, c, 17);
|
||||
R1(c, d, e, a, b, 18);
|
||||
R1(b, c, d, e, a, 19);
|
||||
R2(a, b, c, d, e, 20);
|
||||
R2(e, a, b, c, d, 21);
|
||||
R2(d, e, a, b, c, 22);
|
||||
R2(c, d, e, a, b, 23);
|
||||
R2(b, c, d, e, a, 24);
|
||||
R2(a, b, c, d, e, 25);
|
||||
R2(e, a, b, c, d, 26);
|
||||
R2(d, e, a, b, c, 27);
|
||||
R2(c, d, e, a, b, 28);
|
||||
R2(b, c, d, e, a, 29);
|
||||
R2(a, b, c, d, e, 30);
|
||||
R2(e, a, b, c, d, 31);
|
||||
R2(d, e, a, b, c, 32);
|
||||
R2(c, d, e, a, b, 33);
|
||||
R2(b, c, d, e, a, 34);
|
||||
R2(a, b, c, d, e, 35);
|
||||
R2(e, a, b, c, d, 36);
|
||||
R2(d, e, a, b, c, 37);
|
||||
R2(c, d, e, a, b, 38);
|
||||
R2(b, c, d, e, a, 39);
|
||||
R3(a, b, c, d, e, 40);
|
||||
R3(e, a, b, c, d, 41);
|
||||
R3(d, e, a, b, c, 42);
|
||||
R3(c, d, e, a, b, 43);
|
||||
R3(b, c, d, e, a, 44);
|
||||
R3(a, b, c, d, e, 45);
|
||||
R3(e, a, b, c, d, 46);
|
||||
R3(d, e, a, b, c, 47);
|
||||
R3(c, d, e, a, b, 48);
|
||||
R3(b, c, d, e, a, 49);
|
||||
R3(a, b, c, d, e, 50);
|
||||
R3(e, a, b, c, d, 51);
|
||||
R3(d, e, a, b, c, 52);
|
||||
R3(c, d, e, a, b, 53);
|
||||
R3(b, c, d, e, a, 54);
|
||||
R3(a, b, c, d, e, 55);
|
||||
R3(e, a, b, c, d, 56);
|
||||
R3(d, e, a, b, c, 57);
|
||||
R3(c, d, e, a, b, 58);
|
||||
R3(b, c, d, e, a, 59);
|
||||
R4(a, b, c, d, e, 60);
|
||||
R4(e, a, b, c, d, 61);
|
||||
R4(d, e, a, b, c, 62);
|
||||
R4(c, d, e, a, b, 63);
|
||||
R4(b, c, d, e, a, 64);
|
||||
R4(a, b, c, d, e, 65);
|
||||
R4(e, a, b, c, d, 66);
|
||||
R4(d, e, a, b, c, 67);
|
||||
R4(c, d, e, a, b, 68);
|
||||
R4(b, c, d, e, a, 69);
|
||||
R4(a, b, c, d, e, 70);
|
||||
R4(e, a, b, c, d, 71);
|
||||
R4(d, e, a, b, c, 72);
|
||||
R4(c, d, e, a, b, 73);
|
||||
R4(b, c, d, e, a, 74);
|
||||
R4(a, b, c, d, e, 75);
|
||||
R4(e, a, b, c, d, 76);
|
||||
R4(d, e, a, b, c, 77);
|
||||
R4(c, d, e, a, b, 78);
|
||||
R4(b, c, d, e, a, 79);
|
||||
R0(a, b, c, d, e, 0);
|
||||
R0(e, a, b, c, d, 1);
|
||||
R0(d, e, a, b, c, 2);
|
||||
R0(c, d, e, a, b, 3);
|
||||
R0(b, c, d, e, a, 4);
|
||||
R0(a, b, c, d, e, 5);
|
||||
R0(e, a, b, c, d, 6);
|
||||
R0(d, e, a, b, c, 7);
|
||||
R0(c, d, e, a, b, 8);
|
||||
R0(b, c, d, e, a, 9);
|
||||
R0(a, b, c, d, e, 10);
|
||||
R0(e, a, b, c, d, 11);
|
||||
R0(d, e, a, b, c, 12);
|
||||
R0(c, d, e, a, b, 13);
|
||||
R0(b, c, d, e, a, 14);
|
||||
R0(a, b, c, d, e, 15);
|
||||
R1(e, a, b, c, d, 16);
|
||||
R1(d, e, a, b, c, 17);
|
||||
R1(c, d, e, a, b, 18);
|
||||
R1(b, c, d, e, a, 19);
|
||||
R2(a, b, c, d, e, 20);
|
||||
R2(e, a, b, c, d, 21);
|
||||
R2(d, e, a, b, c, 22);
|
||||
R2(c, d, e, a, b, 23);
|
||||
R2(b, c, d, e, a, 24);
|
||||
R2(a, b, c, d, e, 25);
|
||||
R2(e, a, b, c, d, 26);
|
||||
R2(d, e, a, b, c, 27);
|
||||
R2(c, d, e, a, b, 28);
|
||||
R2(b, c, d, e, a, 29);
|
||||
R2(a, b, c, d, e, 30);
|
||||
R2(e, a, b, c, d, 31);
|
||||
R2(d, e, a, b, c, 32);
|
||||
R2(c, d, e, a, b, 33);
|
||||
R2(b, c, d, e, a, 34);
|
||||
R2(a, b, c, d, e, 35);
|
||||
R2(e, a, b, c, d, 36);
|
||||
R2(d, e, a, b, c, 37);
|
||||
R2(c, d, e, a, b, 38);
|
||||
R2(b, c, d, e, a, 39);
|
||||
R3(a, b, c, d, e, 40);
|
||||
R3(e, a, b, c, d, 41);
|
||||
R3(d, e, a, b, c, 42);
|
||||
R3(c, d, e, a, b, 43);
|
||||
R3(b, c, d, e, a, 44);
|
||||
R3(a, b, c, d, e, 45);
|
||||
R3(e, a, b, c, d, 46);
|
||||
R3(d, e, a, b, c, 47);
|
||||
R3(c, d, e, a, b, 48);
|
||||
R3(b, c, d, e, a, 49);
|
||||
R3(a, b, c, d, e, 50);
|
||||
R3(e, a, b, c, d, 51);
|
||||
R3(d, e, a, b, c, 52);
|
||||
R3(c, d, e, a, b, 53);
|
||||
R3(b, c, d, e, a, 54);
|
||||
R3(a, b, c, d, e, 55);
|
||||
R3(e, a, b, c, d, 56);
|
||||
R3(d, e, a, b, c, 57);
|
||||
R3(c, d, e, a, b, 58);
|
||||
R3(b, c, d, e, a, 59);
|
||||
R4(a, b, c, d, e, 60);
|
||||
R4(e, a, b, c, d, 61);
|
||||
R4(d, e, a, b, c, 62);
|
||||
R4(c, d, e, a, b, 63);
|
||||
R4(b, c, d, e, a, 64);
|
||||
R4(a, b, c, d, e, 65);
|
||||
R4(e, a, b, c, d, 66);
|
||||
R4(d, e, a, b, c, 67);
|
||||
R4(c, d, e, a, b, 68);
|
||||
R4(b, c, d, e, a, 69);
|
||||
R4(a, b, c, d, e, 70);
|
||||
R4(e, a, b, c, d, 71);
|
||||
R4(d, e, a, b, c, 72);
|
||||
R4(c, d, e, a, b, 73);
|
||||
R4(b, c, d, e, a, 74);
|
||||
R4(a, b, c, d, e, 75);
|
||||
R4(e, a, b, c, d, 76);
|
||||
R4(d, e, a, b, c, 77);
|
||||
R4(c, d, e, a, b, 78);
|
||||
R4(b, c, d, e, a, 79);
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
a = b = c = d = e = 0;
|
||||
a = b = c = d = e = 0;
|
||||
}
|
||||
|
||||
void sha1_init(sha1_ctx_t * ctx)
|
||||
{
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
}
|
||||
|
||||
void sha1_update(sha1_ctx_t * ctx, const uint8_t * data, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int i, j;
|
||||
|
||||
j = (ctx->count[0] >> 3) & 63;
|
||||
if ((ctx->count[0] += len << 3) < (len << 3))
|
||||
ctx->count[1]++;
|
||||
ctx->count[1] += (len >> 29);
|
||||
j = (ctx->count[0] >> 3) & 63;
|
||||
if ((ctx->count[0] += len << 3) < (len << 3))
|
||||
ctx->count[1]++;
|
||||
ctx->count[1] += (len >> 29);
|
||||
|
||||
if (j + len > 63) {
|
||||
memcpy(&ctx->buffer[j], data, (i = 64 - j));
|
||||
sha1_transform(ctx->state, ctx->buffer);
|
||||
for (; i + 63 < len; i += 64)
|
||||
sha1_transform(ctx->state, &data[i]);
|
||||
j = 0;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
memcpy(&ctx->buffer[j], &data[i], len - i);
|
||||
if (j + len > 63) {
|
||||
memcpy(&ctx->buffer[j], data, (i = 64 - j));
|
||||
sha1_transform(ctx->state, ctx->buffer);
|
||||
for (; i + 63 < len; i += 64)
|
||||
sha1_transform(ctx->state, &data[i]);
|
||||
j = 0;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
memcpy(&ctx->buffer[j], &data[i], len - i);
|
||||
}
|
||||
|
||||
void sha1_final(sha1_ctx_t * ctx, uint8_t digest[SHA1_DIGESTLEN])
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint8_t finalcount[8];
|
||||
uint32_t i, j;
|
||||
uint8_t finalcount[8];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
finalcount[i] = (uint8_t) ((ctx->count[(i >= 4 ? 0 : 1)] >>
|
||||
((3 - (i & 3)) * 8)) & 255);
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
finalcount[i] = (uint8_t) ((ctx->count[(i >= 4 ? 0 : 1)] >>
|
||||
((3 - (i & 3)) * 8)) & 255);
|
||||
}
|
||||
|
||||
sha1_update(ctx, (uint8_t *) "\200", 1);
|
||||
while ((ctx->count[0] & 504) != 448)
|
||||
sha1_update(ctx, (uint8_t *) "\0", 1);
|
||||
sha1_update(ctx, (uint8_t *) "\200", 1);
|
||||
while ((ctx->count[0] & 504) != 448)
|
||||
sha1_update(ctx, (uint8_t *) "\0", 1);
|
||||
|
||||
sha1_update(ctx, finalcount, 8);
|
||||
for (i = 0; i < SHA1_DIGESTLEN; i++)
|
||||
digest[i] = (uint8_t) ((ctx->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
|
||||
sha1_update(ctx, finalcount, 8);
|
||||
for (i = 0; i < SHA1_DIGESTLEN; i++)
|
||||
digest[i] =
|
||||
(uint8_t) ((ctx->
|
||||
state[i >> 2] >> ((3 - (i & 3)) *
|
||||
8)) & 255);
|
||||
|
||||
i = j = 0;
|
||||
memset(ctx->buffer, 0, SHA1_BLOCKLEN);
|
||||
memset(ctx->state, 0, SHA1_DIGESTLEN);
|
||||
memset(ctx->count, 0, 8);
|
||||
memset(&finalcount, 0, 8);
|
||||
i = j = 0;
|
||||
memset(ctx->buffer, 0, SHA1_BLOCKLEN);
|
||||
memset(ctx->state, 0, SHA1_DIGESTLEN);
|
||||
memset(ctx->count, 0, 8);
|
||||
memset(&finalcount, 0, 8);
|
||||
}
|
||||
|
||||
void sha1_digest(const char *data, char *buffer)
|
||||
{
|
||||
sha1_ctx_t ctx;
|
||||
uint8_t digest[SHA1_DIGESTLEN];
|
||||
int i;
|
||||
sha1_ctx_t ctx;
|
||||
uint8_t digest[SHA1_DIGESTLEN];
|
||||
int i;
|
||||
|
||||
sha1_init(&ctx);
|
||||
sha1_update(&ctx, (const uint8_t *)data, strlen(data));
|
||||
sha1_final(&ctx, (uint8_t *) digest);
|
||||
sha1_init(&ctx);
|
||||
sha1_update(&ctx, (const uint8_t *)data, strlen(data));
|
||||
sha1_final(&ctx, (uint8_t *) digest);
|
||||
|
||||
for (i = 0; i < SHA1_DIGESTLEN; i++) {
|
||||
snprintf(buffer, 3, "%02x", digest[i]);
|
||||
buffer += sizeof(char) * 2;
|
||||
}
|
||||
for (i = 0; i < SHA1_DIGESTLEN; i++) {
|
||||
snprintf(buffer, 3, "%02x", digest[i]);
|
||||
buffer += sizeof(char) * 2;
|
||||
}
|
||||
}
|
||||
|
||||
void sha1_stream(FILE * fp, char *buffer)
|
||||
{
|
||||
sha1_ctx_t ctx;
|
||||
uint8_t data[BUFSIZ];
|
||||
size_t bytes_read;
|
||||
uint8_t digest[SHA1_DIGESTLEN];
|
||||
int i;
|
||||
sha1_ctx_t ctx;
|
||||
uint8_t data[BUFSIZ];
|
||||
size_t bytes_read;
|
||||
uint8_t digest[SHA1_DIGESTLEN];
|
||||
int i;
|
||||
|
||||
sha1_init(&ctx);
|
||||
sha1_init(&ctx);
|
||||
|
||||
while (!feof(fp)) {
|
||||
bytes_read = fread(data, 1, BUFSIZ, fp);
|
||||
sha1_update(&ctx, data, bytes_read);
|
||||
}
|
||||
while (!feof(fp)) {
|
||||
bytes_read = fread(data, 1, BUFSIZ, fp);
|
||||
sha1_update(&ctx, data, bytes_read);
|
||||
}
|
||||
|
||||
sha1_final(&ctx, (uint8_t *) digest);
|
||||
sha1_final(&ctx, (uint8_t *) digest);
|
||||
|
||||
for (i = 0; i < SHA1_DIGESTLEN; i++) {
|
||||
snprintf(buffer, 3, "%02x", digest[i]);
|
||||
buffer += sizeof(char) * 2;
|
||||
}
|
||||
for (i = 0; i < SHA1_DIGESTLEN; i++) {
|
||||
snprintf(buffer, 3, "%02x", digest[i]);
|
||||
buffer += sizeof(char) * 2;
|
||||
}
|
||||
}
|
||||
|
@ -45,9 +45,9 @@
|
||||
#define SHA1_DIGESTLEN 20
|
||||
|
||||
typedef struct {
|
||||
uint32_t state[5];
|
||||
uint32_t count[2];
|
||||
uint8_t buffer[SHA1_BLOCKLEN];
|
||||
uint32_t state[5];
|
||||
uint32_t count[2];
|
||||
uint8_t buffer[SHA1_BLOCKLEN];
|
||||
} sha1_ctx_t;
|
||||
|
||||
void sha1_init(sha1_ctx_t *);
|
||||
|
72
src/sigs.c
72
src/sigs.c
@ -65,60 +65,62 @@
|
||||
*/
|
||||
static void generic_hdlr(int sig)
|
||||
{
|
||||
switch (sig) {
|
||||
case SIGCHLD:
|
||||
while (waitpid(WAIT_MYPGRP, NULL, WNOHANG) > 0) ;
|
||||
break;
|
||||
case SIGWINCH:
|
||||
resize = 1;
|
||||
clearok(curscr, TRUE);
|
||||
ungetch(KEY_RESIZE);
|
||||
break;
|
||||
case SIGTERM:
|
||||
if (unlink(path_cpid) != 0) {
|
||||
EXIT(_("Could not remove calcurse lock file: %s\n"), strerror(errno));
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
switch (sig) {
|
||||
case SIGCHLD:
|
||||
while (waitpid(WAIT_MYPGRP, NULL, WNOHANG) > 0) ;
|
||||
break;
|
||||
case SIGWINCH:
|
||||
resize = 1;
|
||||
clearok(curscr, TRUE);
|
||||
ungetch(KEY_RESIZE);
|
||||
break;
|
||||
case SIGTERM:
|
||||
if (unlink(path_cpid) != 0) {
|
||||
EXIT(_("Could not remove calcurse lock file: %s\n"),
|
||||
strerror(errno));
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned sigs_set_hdlr(int sig, void (*handler) (int))
|
||||
{
|
||||
struct sigaction sa;
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
if (sigaction(sig, &sa, NULL) == -1) {
|
||||
ERROR_MSG(_("Error setting signal #%d : %s\n"), sig, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
if (sigaction(sig, &sa, NULL) == -1) {
|
||||
ERROR_MSG(_("Error setting signal #%d : %s\n"), sig,
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Signal handling init. */
|
||||
void sigs_init()
|
||||
{
|
||||
if (!sigs_set_hdlr(SIGCHLD, generic_hdlr)
|
||||
|| !sigs_set_hdlr(SIGWINCH, generic_hdlr)
|
||||
|| !sigs_set_hdlr(SIGTERM, generic_hdlr)
|
||||
|| !sigs_set_hdlr(SIGINT, SIG_IGN))
|
||||
exit_calcurse(1);
|
||||
if (!sigs_set_hdlr(SIGCHLD, generic_hdlr)
|
||||
|| !sigs_set_hdlr(SIGWINCH, generic_hdlr)
|
||||
|| !sigs_set_hdlr(SIGTERM, generic_hdlr)
|
||||
|| !sigs_set_hdlr(SIGINT, SIG_IGN))
|
||||
exit_calcurse(1);
|
||||
}
|
||||
|
||||
/* Ignore SIGWINCH and SIGTERM signals. */
|
||||
void sigs_ignore(void)
|
||||
{
|
||||
sigs_set_hdlr(SIGWINCH, SIG_IGN);
|
||||
sigs_set_hdlr(SIGTERM, SIG_IGN);
|
||||
sigs_set_hdlr(SIGWINCH, SIG_IGN);
|
||||
sigs_set_hdlr(SIGTERM, SIG_IGN);
|
||||
}
|
||||
|
||||
/* No longer ignore SIGWINCH and SIGTERM signals. */
|
||||
void sigs_unignore(void)
|
||||
{
|
||||
sigs_set_hdlr(SIGWINCH, generic_hdlr);
|
||||
sigs_set_hdlr(SIGTERM, generic_hdlr);
|
||||
sigs_set_hdlr(SIGWINCH, generic_hdlr);
|
||||
sigs_set_hdlr(SIGTERM, generic_hdlr);
|
||||
}
|
||||
|
98
src/todo.c
98
src/todo.c
@ -45,20 +45,20 @@ llist_t todolist;
|
||||
/* Returns a structure containing the selected item. */
|
||||
struct todo *todo_get_item(int item_number)
|
||||
{
|
||||
return LLIST_GET_DATA(LLIST_NTH(&todolist, item_number - 1));
|
||||
return LLIST_GET_DATA(LLIST_NTH(&todolist, item_number - 1));
|
||||
}
|
||||
|
||||
static int todo_cmp_id(struct todo *a, struct todo *b)
|
||||
{
|
||||
/*
|
||||
* As of version 2.6, todo items can have a negative id, which means they
|
||||
* were completed. To keep them sorted, we need to consider the absolute id
|
||||
* value.
|
||||
*/
|
||||
int abs_a = abs(a->id);
|
||||
int abs_b = abs(b->id);
|
||||
/*
|
||||
* As of version 2.6, todo items can have a negative id, which means they
|
||||
* were completed. To keep them sorted, we need to consider the absolute id
|
||||
* value.
|
||||
*/
|
||||
int abs_a = abs(a->id);
|
||||
int abs_b = abs(b->id);
|
||||
|
||||
return abs_a < abs_b ? -1 : (abs_a == abs_b ? 0 : 1);
|
||||
return abs_a < abs_b ? -1 : (abs_a == abs_b ? 0 : 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -66,46 +66,48 @@ static int todo_cmp_id(struct todo *a, struct todo *b)
|
||||
*/
|
||||
struct todo *todo_add(char *mesg, int id, char *note)
|
||||
{
|
||||
struct todo *todo;
|
||||
struct todo *todo;
|
||||
|
||||
todo = mem_malloc(sizeof(struct todo));
|
||||
todo->mesg = mem_strdup(mesg);
|
||||
todo->id = id;
|
||||
todo->note = (note != NULL && note[0] != '\0') ? mem_strdup(note) : NULL;
|
||||
todo = mem_malloc(sizeof(struct todo));
|
||||
todo->mesg = mem_strdup(mesg);
|
||||
todo->id = id;
|
||||
todo->note = (note != NULL
|
||||
&& note[0] != '\0') ? mem_strdup(note) : NULL;
|
||||
|
||||
LLIST_ADD_SORTED(&todolist, todo, todo_cmp_id);
|
||||
LLIST_ADD_SORTED(&todolist, todo, todo_cmp_id);
|
||||
|
||||
return todo;
|
||||
return todo;
|
||||
}
|
||||
|
||||
void todo_write(struct todo *todo, FILE * f)
|
||||
{
|
||||
if (todo->note)
|
||||
fprintf(f, "[%d]>%s %s\n", todo->id, todo->note, todo->mesg);
|
||||
else
|
||||
fprintf(f, "[%d] %s\n", todo->id, todo->mesg);
|
||||
if (todo->note)
|
||||
fprintf(f, "[%d]>%s %s\n", todo->id, todo->note,
|
||||
todo->mesg);
|
||||
else
|
||||
fprintf(f, "[%d] %s\n", todo->id, todo->mesg);
|
||||
}
|
||||
|
||||
/* Delete a note previously attached to a todo item. */
|
||||
void todo_delete_note(struct todo *todo)
|
||||
{
|
||||
if (!todo->note)
|
||||
EXIT(_("no note attached"));
|
||||
erase_note(&todo->note);
|
||||
if (!todo->note)
|
||||
EXIT(_("no note attached"));
|
||||
erase_note(&todo->note);
|
||||
}
|
||||
|
||||
/* Delete an item from the todo linked list. */
|
||||
void todo_delete(struct todo *todo)
|
||||
{
|
||||
llist_item_t *i = LLIST_FIND_FIRST(&todolist, todo, NULL);
|
||||
llist_item_t *i = LLIST_FIND_FIRST(&todolist, todo, NULL);
|
||||
|
||||
if (!i)
|
||||
EXIT(_("no such todo"));
|
||||
if (!i)
|
||||
EXIT(_("no such todo"));
|
||||
|
||||
LLIST_REMOVE(&todolist, i);
|
||||
mem_free(todo->mesg);
|
||||
erase_note(&todo->note);
|
||||
mem_free(todo);
|
||||
LLIST_REMOVE(&todolist, i);
|
||||
mem_free(todo->mesg);
|
||||
erase_note(&todo->note);
|
||||
mem_free(todo);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -116,7 +118,7 @@ void todo_delete(struct todo *todo)
|
||||
*/
|
||||
void todo_flag(struct todo *t)
|
||||
{
|
||||
t->id = -t->id;
|
||||
t->id = -t->id;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -125,45 +127,45 @@ void todo_flag(struct todo *t)
|
||||
*/
|
||||
int todo_get_position(struct todo *needle)
|
||||
{
|
||||
llist_item_t *i;
|
||||
int n = 0;
|
||||
llist_item_t *i;
|
||||
int n = 0;
|
||||
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
n++;
|
||||
if (LLIST_TS_GET_DATA(i) == needle)
|
||||
return n;
|
||||
}
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
n++;
|
||||
if (LLIST_TS_GET_DATA(i) == needle)
|
||||
return n;
|
||||
}
|
||||
|
||||
EXIT(_("todo not found"));
|
||||
return -1; /* avoid compiler warnings */
|
||||
EXIT(_("todo not found"));
|
||||
return -1; /* avoid compiler warnings */
|
||||
}
|
||||
|
||||
/* Attach a note to a todo */
|
||||
void todo_edit_note(struct todo *i, const char *editor)
|
||||
{
|
||||
edit_note(&i->note, editor);
|
||||
edit_note(&i->note, editor);
|
||||
}
|
||||
|
||||
/* View a note previously attached to a todo */
|
||||
void todo_view_note(struct todo *i, const char *pager)
|
||||
{
|
||||
view_note(i->note, pager);
|
||||
view_note(i->note, pager);
|
||||
}
|
||||
|
||||
void todo_free(struct todo *todo)
|
||||
{
|
||||
mem_free(todo->mesg);
|
||||
erase_note(&todo->note);
|
||||
mem_free(todo);
|
||||
mem_free(todo->mesg);
|
||||
erase_note(&todo->note);
|
||||
mem_free(todo);
|
||||
}
|
||||
|
||||
void todo_init_list(void)
|
||||
{
|
||||
LLIST_INIT(&todolist);
|
||||
LLIST_INIT(&todolist);
|
||||
}
|
||||
|
||||
void todo_free_list(void)
|
||||
{
|
||||
LLIST_FREE_INNER(&todolist, todo_free);
|
||||
LLIST_FREE(&todolist);
|
||||
LLIST_FREE_INNER(&todolist, todo_free);
|
||||
LLIST_FREE(&todolist);
|
||||
}
|
||||
|
1096
src/ui-calendar.c
1096
src/ui-calendar.c
File diff suppressed because it is too large
Load Diff
1393
src/ui-day.c
1393
src/ui-day.c
File diff suppressed because it is too large
Load Diff
330
src/ui-todo.c
330
src/ui-todo.c
@ -44,147 +44,152 @@ static char *msgsav;
|
||||
/* Request user to enter a new todo item. */
|
||||
void ui_todo_add(void)
|
||||
{
|
||||
int ch = 0;
|
||||
const char *mesg = _("Enter the new ToDo item : ");
|
||||
const char *mesg_id =
|
||||
_("Enter the ToDo priority [1 (highest) - 9 (lowest)] :");
|
||||
char todo_input[BUFSIZ] = "";
|
||||
int ch = 0;
|
||||
const char *mesg = _("Enter the new ToDo item : ");
|
||||
const char *mesg_id =
|
||||
_("Enter the ToDo priority [1 (highest) - 9 (lowest)] :");
|
||||
char todo_input[BUFSIZ] = "";
|
||||
|
||||
status_mesg(mesg, "");
|
||||
if (getstring(win[STA].p, todo_input, BUFSIZ, 0, 1) == GETSTRING_VALID) {
|
||||
while ((ch < '1') || (ch > '9')) {
|
||||
status_mesg(mesg_id, "");
|
||||
ch = wgetch(win[KEY].p);
|
||||
}
|
||||
todo_add(todo_input, ch - '0', NULL);
|
||||
ui_todo_set_nb(ui_todo_nb() + 1);
|
||||
}
|
||||
status_mesg(mesg, "");
|
||||
if (getstring(win[STA].p, todo_input, BUFSIZ, 0, 1) ==
|
||||
GETSTRING_VALID) {
|
||||
while ((ch < '1') || (ch > '9')) {
|
||||
status_mesg(mesg_id, "");
|
||||
ch = wgetch(win[KEY].p);
|
||||
}
|
||||
todo_add(todo_input, ch - '0', NULL);
|
||||
ui_todo_set_nb(ui_todo_nb() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete an item from the ToDo list. */
|
||||
void ui_todo_delete(void)
|
||||
{
|
||||
const char *del_todo_str = _("Do you really want to delete this task ?");
|
||||
const char *erase_warning =
|
||||
_("This item has a note attached to it. "
|
||||
"Delete (t)odo or just its (n)ote ?");
|
||||
const char *erase_choice = _("[tn]");
|
||||
const int nb_erase_choice = 2;
|
||||
int answer;
|
||||
const char *del_todo_str =
|
||||
_("Do you really want to delete this task ?");
|
||||
const char *erase_warning =
|
||||
_("This item has a note attached to it. "
|
||||
"Delete (t)odo or just its (n)ote ?");
|
||||
const char *erase_choice = _("[tn]");
|
||||
const int nb_erase_choice = 2;
|
||||
int answer;
|
||||
|
||||
if ((ui_todo_nb() <= 0) ||
|
||||
(conf.confirm_delete && (status_ask_bool(del_todo_str) != 1))) {
|
||||
wins_erase_status_bar();
|
||||
return;
|
||||
}
|
||||
if ((ui_todo_nb() <= 0) ||
|
||||
(conf.confirm_delete
|
||||
&& (status_ask_bool(del_todo_str) != 1))) {
|
||||
wins_erase_status_bar();
|
||||
return;
|
||||
}
|
||||
|
||||
/* This todo item doesn't have any note associated. */
|
||||
if (todo_get_item(ui_todo_hilt())->note == NULL)
|
||||
answer = 1;
|
||||
else
|
||||
answer = status_ask_choice(erase_warning, erase_choice, nb_erase_choice);
|
||||
/* This todo item doesn't have any note associated. */
|
||||
if (todo_get_item(ui_todo_hilt())->note == NULL)
|
||||
answer = 1;
|
||||
else
|
||||
answer =
|
||||
status_ask_choice(erase_warning, erase_choice,
|
||||
nb_erase_choice);
|
||||
|
||||
switch (answer) {
|
||||
case 1:
|
||||
todo_delete(todo_get_item(ui_todo_hilt()));
|
||||
ui_todo_set_nb(ui_todo_nb() - 1);
|
||||
if (ui_todo_hilt() > 1)
|
||||
ui_todo_hilt_decrease(1);
|
||||
if (ui_todo_nb() == 0)
|
||||
ui_todo_hilt_set(0);
|
||||
if (ui_todo_hilt_pos() < 0)
|
||||
ui_todo_first_decrease(1);
|
||||
break;
|
||||
case 2:
|
||||
todo_delete_note(todo_get_item(ui_todo_hilt()));
|
||||
break;
|
||||
default:
|
||||
wins_erase_status_bar();
|
||||
return;
|
||||
}
|
||||
switch (answer) {
|
||||
case 1:
|
||||
todo_delete(todo_get_item(ui_todo_hilt()));
|
||||
ui_todo_set_nb(ui_todo_nb() - 1);
|
||||
if (ui_todo_hilt() > 1)
|
||||
ui_todo_hilt_decrease(1);
|
||||
if (ui_todo_nb() == 0)
|
||||
ui_todo_hilt_set(0);
|
||||
if (ui_todo_hilt_pos() < 0)
|
||||
ui_todo_first_decrease(1);
|
||||
break;
|
||||
case 2:
|
||||
todo_delete_note(todo_get_item(ui_todo_hilt()));
|
||||
break;
|
||||
default:
|
||||
wins_erase_status_bar();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Edit the description of an already existing todo item. */
|
||||
void ui_todo_edit(void)
|
||||
{
|
||||
struct todo *i;
|
||||
const char *mesg = _("Enter the new ToDo description :");
|
||||
struct todo *i;
|
||||
const char *mesg = _("Enter the new ToDo description :");
|
||||
|
||||
status_mesg(mesg, "");
|
||||
i = todo_get_item(ui_todo_hilt());
|
||||
updatestring(win[STA].p, &i->mesg, 0, 1);
|
||||
status_mesg(mesg, "");
|
||||
i = todo_get_item(ui_todo_hilt());
|
||||
updatestring(win[STA].p, &i->mesg, 0, 1);
|
||||
}
|
||||
|
||||
/* Pipe a todo item to an external program. */
|
||||
void ui_todo_pipe(void)
|
||||
{
|
||||
char cmd[BUFSIZ] = "";
|
||||
char const *arg[] = { cmd, NULL };
|
||||
int pout;
|
||||
int pid;
|
||||
FILE *fpout;
|
||||
struct todo *todo;
|
||||
char cmd[BUFSIZ] = "";
|
||||
char const *arg[] = { cmd, NULL };
|
||||
int pout;
|
||||
int pid;
|
||||
FILE *fpout;
|
||||
struct todo *todo;
|
||||
|
||||
status_mesg(_("Pipe item to external command:"), "");
|
||||
if (getstring(win[STA].p, cmd, BUFSIZ, 0, 1) != GETSTRING_VALID)
|
||||
return;
|
||||
status_mesg(_("Pipe item to external command:"), "");
|
||||
if (getstring(win[STA].p, cmd, BUFSIZ, 0, 1) != GETSTRING_VALID)
|
||||
return;
|
||||
|
||||
wins_prepare_external();
|
||||
if ((pid = shell_exec(NULL, &pout, *arg, arg))) {
|
||||
fpout = fdopen(pout, "w");
|
||||
wins_prepare_external();
|
||||
if ((pid = shell_exec(NULL, &pout, *arg, arg))) {
|
||||
fpout = fdopen(pout, "w");
|
||||
|
||||
todo = todo_get_item(ui_todo_hilt());
|
||||
todo_write(todo, fpout);
|
||||
todo = todo_get_item(ui_todo_hilt());
|
||||
todo_write(todo, fpout);
|
||||
|
||||
fclose(fpout);
|
||||
child_wait(NULL, &pout, pid);
|
||||
press_any_key();
|
||||
}
|
||||
wins_unprepare_external();
|
||||
fclose(fpout);
|
||||
child_wait(NULL, &pout, pid);
|
||||
press_any_key();
|
||||
}
|
||||
wins_unprepare_external();
|
||||
}
|
||||
|
||||
/* Sets which todo is highlighted. */
|
||||
void ui_todo_hilt_set(int highlighted)
|
||||
{
|
||||
hilt = highlighted;
|
||||
hilt = highlighted;
|
||||
}
|
||||
|
||||
void ui_todo_hilt_decrease(int n)
|
||||
{
|
||||
hilt -= n;
|
||||
hilt -= n;
|
||||
}
|
||||
|
||||
void ui_todo_hilt_increase(int n)
|
||||
{
|
||||
hilt += n;
|
||||
hilt += n;
|
||||
}
|
||||
|
||||
/* Return which todo is highlighted. */
|
||||
int ui_todo_hilt(void)
|
||||
{
|
||||
return hilt;
|
||||
return hilt;
|
||||
}
|
||||
|
||||
/* Set the number of todos. */
|
||||
void ui_todo_set_nb(int nb)
|
||||
{
|
||||
todos = nb;
|
||||
todos = nb;
|
||||
}
|
||||
|
||||
/* Set which one is the first todo to be displayed. */
|
||||
void ui_todo_set_first(int nb)
|
||||
{
|
||||
first = nb;
|
||||
first = nb;
|
||||
}
|
||||
|
||||
void ui_todo_first_increase(int n)
|
||||
{
|
||||
first += n;
|
||||
first += n;
|
||||
}
|
||||
|
||||
void ui_todo_first_decrease(int n)
|
||||
{
|
||||
first -= n;
|
||||
first -= n;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -193,118 +198,121 @@ void ui_todo_first_decrease(int n)
|
||||
*/
|
||||
int ui_todo_hilt_pos(void)
|
||||
{
|
||||
return hilt - first;
|
||||
return hilt - first;
|
||||
}
|
||||
|
||||
/* Return the number of todos. */
|
||||
int ui_todo_nb(void)
|
||||
{
|
||||
return todos;
|
||||
return todos;
|
||||
}
|
||||
|
||||
/* Return the last visited todo. */
|
||||
char *ui_todo_saved_mesg(void)
|
||||
{
|
||||
return msgsav;
|
||||
return msgsav;
|
||||
}
|
||||
|
||||
/* Display todo items in the corresponding panel. */
|
||||
static void
|
||||
display_todo_item(int incolor, char *msg, int prio, int note, int width, int y,
|
||||
int x)
|
||||
display_todo_item(int incolor, char *msg, int prio, int note, int width,
|
||||
int y, int x)
|
||||
{
|
||||
WINDOW *w;
|
||||
int ch_note;
|
||||
char buf[width * UTF8_MAXLEN], priostr[2];
|
||||
int i;
|
||||
WINDOW *w;
|
||||
int ch_note;
|
||||
char buf[width * UTF8_MAXLEN], priostr[2];
|
||||
int i;
|
||||
|
||||
w = win[TOD].p;
|
||||
ch_note = (note) ? '>' : '.';
|
||||
if (prio > 0)
|
||||
snprintf(priostr, sizeof priostr, "%d", prio);
|
||||
else
|
||||
strncpy(priostr, "X", sizeof priostr);
|
||||
w = win[TOD].p;
|
||||
ch_note = (note) ? '>' : '.';
|
||||
if (prio > 0)
|
||||
snprintf(priostr, sizeof priostr, "%d", prio);
|
||||
else
|
||||
strncpy(priostr, "X", sizeof priostr);
|
||||
|
||||
if (incolor == 0)
|
||||
custom_apply_attr(w, ATTR_HIGHEST);
|
||||
if (utf8_strwidth(msg) < width) {
|
||||
mvwprintw(w, y, x, "%s%c %s", priostr, ch_note, msg);
|
||||
} else {
|
||||
for (i = 0; msg[i] && width > 0; i++) {
|
||||
if (!UTF8_ISCONT(msg[i]))
|
||||
width -= utf8_width(&msg[i]);
|
||||
buf[i] = msg[i];
|
||||
}
|
||||
if (i)
|
||||
buf[i - 1] = 0;
|
||||
else
|
||||
buf[0] = 0;
|
||||
mvwprintw(w, y, x, "%s%c %s...", priostr, ch_note, buf);
|
||||
}
|
||||
if (incolor == 0)
|
||||
custom_remove_attr(w, ATTR_HIGHEST);
|
||||
if (incolor == 0)
|
||||
custom_apply_attr(w, ATTR_HIGHEST);
|
||||
if (utf8_strwidth(msg) < width) {
|
||||
mvwprintw(w, y, x, "%s%c %s", priostr, ch_note, msg);
|
||||
} else {
|
||||
for (i = 0; msg[i] && width > 0; i++) {
|
||||
if (!UTF8_ISCONT(msg[i]))
|
||||
width -= utf8_width(&msg[i]);
|
||||
buf[i] = msg[i];
|
||||
}
|
||||
if (i)
|
||||
buf[i - 1] = 0;
|
||||
else
|
||||
buf[0] = 0;
|
||||
mvwprintw(w, y, x, "%s%c %s...", priostr, ch_note, buf);
|
||||
}
|
||||
if (incolor == 0)
|
||||
custom_remove_attr(w, ATTR_HIGHEST);
|
||||
}
|
||||
|
||||
/* Updates the ToDo panel. */
|
||||
void ui_todo_update_panel(int which_pan)
|
||||
{
|
||||
llist_item_t *i;
|
||||
int len = win[TOD].w - 8;
|
||||
int num_todo = 0;
|
||||
int title_lines = conf.compact_panels ? 1 : 3;
|
||||
int y_offset = title_lines, x_offset = 1;
|
||||
int t_realpos = -1;
|
||||
int todo_lines = 1;
|
||||
int max_items = win[TOD].h - 4;
|
||||
int incolor = -1;
|
||||
llist_item_t *i;
|
||||
int len = win[TOD].w - 8;
|
||||
int num_todo = 0;
|
||||
int title_lines = conf.compact_panels ? 1 : 3;
|
||||
int y_offset = title_lines, x_offset = 1;
|
||||
int t_realpos = -1;
|
||||
int todo_lines = 1;
|
||||
int max_items = win[TOD].h - 4;
|
||||
int incolor = -1;
|
||||
|
||||
if ((int)win[TOD].h < 4)
|
||||
return;
|
||||
if ((int)win[TOD].h < 4)
|
||||
return;
|
||||
|
||||
/* Print todo item in the panel. */
|
||||
erase_window_part(win[TOD].p, 1, title_lines, win[TOD].w - 2, win[TOD].h - 2);
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
struct todo *todo = LLIST_TS_GET_DATA(i);
|
||||
num_todo++;
|
||||
t_realpos = num_todo - first;
|
||||
incolor = (which_pan == TOD) ? num_todo - hilt : num_todo;
|
||||
if (incolor == 0)
|
||||
msgsav = todo->mesg;
|
||||
if (t_realpos >= 0 && t_realpos < max_items) {
|
||||
display_todo_item(incolor, todo->mesg, todo->id,
|
||||
(todo->note != NULL) ? 1 : 0, len, y_offset, x_offset);
|
||||
y_offset = y_offset + todo_lines;
|
||||
}
|
||||
}
|
||||
/* Print todo item in the panel. */
|
||||
erase_window_part(win[TOD].p, 1, title_lines, win[TOD].w - 2,
|
||||
win[TOD].h - 2);
|
||||
LLIST_FOREACH(&todolist, i) {
|
||||
struct todo *todo = LLIST_TS_GET_DATA(i);
|
||||
num_todo++;
|
||||
t_realpos = num_todo - first;
|
||||
incolor = (which_pan == TOD) ? num_todo - hilt : num_todo;
|
||||
if (incolor == 0)
|
||||
msgsav = todo->mesg;
|
||||
if (t_realpos >= 0 && t_realpos < max_items) {
|
||||
display_todo_item(incolor, todo->mesg, todo->id,
|
||||
(todo->note != NULL) ? 1 : 0,
|
||||
len, y_offset, x_offset);
|
||||
y_offset = y_offset + todo_lines;
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the scrollbar if necessary. */
|
||||
if (todos > max_items) {
|
||||
int sbar_length = max_items * (max_items + 1) / todos;
|
||||
int highend = max_items * first / todos;
|
||||
unsigned hilt_bar = (which_pan == TOD) ? 1 : 0;
|
||||
int sbar_top = highend + title_lines;
|
||||
/* Draw the scrollbar if necessary. */
|
||||
if (todos > max_items) {
|
||||
int sbar_length = max_items * (max_items + 1) / todos;
|
||||
int highend = max_items * first / todos;
|
||||
unsigned hilt_bar = (which_pan == TOD) ? 1 : 0;
|
||||
int sbar_top = highend + title_lines;
|
||||
|
||||
if ((sbar_top + sbar_length) > win[TOD].h - 1)
|
||||
sbar_length = win[TOD].h - 1 - sbar_top;
|
||||
draw_scrollbar(win[TOD].p, sbar_top, win[TOD].w - 2,
|
||||
sbar_length, title_lines, win[TOD].h - 1, hilt_bar);
|
||||
}
|
||||
if ((sbar_top + sbar_length) > win[TOD].h - 1)
|
||||
sbar_length = win[TOD].h - 1 - sbar_top;
|
||||
draw_scrollbar(win[TOD].p, sbar_top, win[TOD].w - 2,
|
||||
sbar_length, title_lines, win[TOD].h - 1,
|
||||
hilt_bar);
|
||||
}
|
||||
|
||||
wnoutrefresh(win[TOD].p);
|
||||
wnoutrefresh(win[TOD].p);
|
||||
}
|
||||
|
||||
/* Change an item priority by pressing '+' or '-' inside TODO panel. */
|
||||
void ui_todo_chg_priority(struct todo *todo, int diff)
|
||||
{
|
||||
int id = todo->id + diff;
|
||||
struct todo *todo_new;
|
||||
int id = todo->id + diff;
|
||||
struct todo *todo_new;
|
||||
|
||||
if (id < 1)
|
||||
id = 1;
|
||||
else if (id > 9)
|
||||
id = 9;
|
||||
if (id < 1)
|
||||
id = 1;
|
||||
else if (id > 9)
|
||||
id = 9;
|
||||
|
||||
todo_new = todo_add(todo->mesg, id, todo->note);
|
||||
todo_delete(todo);
|
||||
hilt = todo_get_position(todo_new);
|
||||
todo_new = todo_add(todo->mesg, id, todo->note);
|
||||
todo_delete(todo);
|
||||
hilt = todo_get_position(todo_new);
|
||||
}
|
||||
|
556
src/utf8.c
556
src/utf8.c
@ -37,300 +37,302 @@
|
||||
#include "calcurse.h"
|
||||
|
||||
struct utf8_range {
|
||||
int min, max, width;
|
||||
int min, max, width;
|
||||
};
|
||||
|
||||
static const struct utf8_range utf8_widthtab[] = {
|
||||
{0x00300, 0x0036f, 0},
|
||||
{0x00483, 0x00489, 0},
|
||||
{0x00591, 0x005bd, 0},
|
||||
{0x005bf, 0x005bf, 0},
|
||||
{0x005c1, 0x005c2, 0},
|
||||
{0x005c4, 0x005c5, 0},
|
||||
{0x005c7, 0x005c7, 0},
|
||||
{0x00610, 0x0061a, 0},
|
||||
{0x0064b, 0x0065e, 0},
|
||||
{0x00670, 0x00670, 0},
|
||||
{0x006d6, 0x006dc, 0},
|
||||
{0x006de, 0x006e4, 0},
|
||||
{0x006e7, 0x006e8, 0},
|
||||
{0x006ea, 0x006ed, 0},
|
||||
{0x00711, 0x00711, 0},
|
||||
{0x00730, 0x0074a, 0},
|
||||
{0x007a6, 0x007b0, 0},
|
||||
{0x007eb, 0x007f3, 0},
|
||||
{0x00816, 0x00819, 0},
|
||||
{0x0081b, 0x00823, 0},
|
||||
{0x00825, 0x00827, 0},
|
||||
{0x00829, 0x0082d, 0},
|
||||
{0x00900, 0x00903, 0},
|
||||
{0x0093c, 0x0093c, 0},
|
||||
{0x0093e, 0x0094e, 0},
|
||||
{0x00951, 0x00955, 0},
|
||||
{0x00962, 0x00963, 0},
|
||||
{0x00981, 0x00983, 0},
|
||||
{0x009bc, 0x009bc, 0},
|
||||
{0x009be, 0x009c4, 0},
|
||||
{0x009c7, 0x009c8, 0},
|
||||
{0x009cb, 0x009cd, 0},
|
||||
{0x009d7, 0x009d7, 0},
|
||||
{0x009e2, 0x009e3, 0},
|
||||
{0x00a01, 0x00a03, 0},
|
||||
{0x00a3c, 0x00a3c, 0},
|
||||
{0x00a3e, 0x00a42, 0},
|
||||
{0x00a47, 0x00a48, 0},
|
||||
{0x00a4b, 0x00a4d, 0},
|
||||
{0x00a51, 0x00a51, 0},
|
||||
{0x00a70, 0x00a71, 0},
|
||||
{0x00a75, 0x00a75, 0},
|
||||
{0x00a81, 0x00a83, 0},
|
||||
{0x00abc, 0x00abc, 0},
|
||||
{0x00abe, 0x00ac5, 0},
|
||||
{0x00ac7, 0x00ac9, 0},
|
||||
{0x00acb, 0x00acd, 0},
|
||||
{0x00ae2, 0x00ae3, 0},
|
||||
{0x00b01, 0x00b03, 0},
|
||||
{0x00b3c, 0x00b3c, 0},
|
||||
{0x00b3e, 0x00b44, 0},
|
||||
{0x00b47, 0x00b48, 0},
|
||||
{0x00b4b, 0x00b4d, 0},
|
||||
{0x00b56, 0x00b57, 0},
|
||||
{0x00b62, 0x00b63, 0},
|
||||
{0x00b82, 0x00b82, 0},
|
||||
{0x00bbe, 0x00bc2, 0},
|
||||
{0x00bc6, 0x00bc8, 0},
|
||||
{0x00bca, 0x00bcd, 0},
|
||||
{0x00bd7, 0x00bd7, 0},
|
||||
{0x00c01, 0x00c03, 0},
|
||||
{0x00c3e, 0x00c44, 0},
|
||||
{0x00c46, 0x00c48, 0},
|
||||
{0x00c4a, 0x00c4d, 0},
|
||||
{0x00c55, 0x00c56, 0},
|
||||
{0x00c62, 0x00c63, 0},
|
||||
{0x00c82, 0x00c83, 0},
|
||||
{0x00cbc, 0x00cbc, 0},
|
||||
{0x00cbe, 0x00cc4, 0},
|
||||
{0x00cc6, 0x00cc8, 0},
|
||||
{0x00cca, 0x00ccd, 0},
|
||||
{0x00cd5, 0x00cd6, 0},
|
||||
{0x00ce2, 0x00ce3, 0},
|
||||
{0x00d02, 0x00d03, 0},
|
||||
{0x00d3e, 0x00d44, 0},
|
||||
{0x00d46, 0x00d48, 0},
|
||||
{0x00d4a, 0x00d4d, 0},
|
||||
{0x00d57, 0x00d57, 0},
|
||||
{0x00d62, 0x00d63, 0},
|
||||
{0x00d82, 0x00d83, 0},
|
||||
{0x00dca, 0x00dca, 0},
|
||||
{0x00dcf, 0x00dd4, 0},
|
||||
{0x00dd6, 0x00dd6, 0},
|
||||
{0x00dd8, 0x00ddf, 0},
|
||||
{0x00df2, 0x00df3, 0},
|
||||
{0x00e31, 0x00e31, 0},
|
||||
{0x00e34, 0x00e3a, 0},
|
||||
{0x00e47, 0x00e4e, 0},
|
||||
{0x00eb1, 0x00eb1, 0},
|
||||
{0x00eb4, 0x00eb9, 0},
|
||||
{0x00ebb, 0x00ebc, 0},
|
||||
{0x00ec8, 0x00ecd, 0},
|
||||
{0x00f18, 0x00f19, 0},
|
||||
{0x00f35, 0x00f35, 0},
|
||||
{0x00f37, 0x00f37, 0},
|
||||
{0x00f39, 0x00f39, 0},
|
||||
{0x00f3e, 0x00f3f, 0},
|
||||
{0x00f71, 0x00f84, 0},
|
||||
{0x00f86, 0x00f87, 0},
|
||||
{0x00f90, 0x00f97, 0},
|
||||
{0x00f99, 0x00fbc, 0},
|
||||
{0x00fc6, 0x00fc6, 0},
|
||||
{0x0102b, 0x0103e, 0},
|
||||
{0x01056, 0x01059, 0},
|
||||
{0x0105e, 0x01060, 0},
|
||||
{0x01062, 0x01064, 0},
|
||||
{0x01067, 0x0106d, 0},
|
||||
{0x01071, 0x01074, 0},
|
||||
{0x01082, 0x0108d, 0},
|
||||
{0x0108f, 0x0108f, 0},
|
||||
{0x0109a, 0x0109d, 0},
|
||||
{0x01100, 0x0115f, 2},
|
||||
{0x011a3, 0x011a7, 2},
|
||||
{0x011fa, 0x011ff, 2},
|
||||
{0x0135f, 0x0135f, 0},
|
||||
{0x01712, 0x01714, 0},
|
||||
{0x01732, 0x01734, 0},
|
||||
{0x01752, 0x01753, 0},
|
||||
{0x01772, 0x01773, 0},
|
||||
{0x017b6, 0x017d3, 0},
|
||||
{0x017dd, 0x017dd, 0},
|
||||
{0x0180b, 0x0180d, 0},
|
||||
{0x018a9, 0x018a9, 0},
|
||||
{0x01920, 0x0192b, 0},
|
||||
{0x01930, 0x0193b, 0},
|
||||
{0x019b0, 0x019c0, 0},
|
||||
{0x019c8, 0x019c9, 0},
|
||||
{0x01a17, 0x01a1b, 0},
|
||||
{0x01a55, 0x01a5e, 0},
|
||||
{0x01a60, 0x01a7c, 0},
|
||||
{0x01a7f, 0x01a7f, 0},
|
||||
{0x01b00, 0x01b04, 0},
|
||||
{0x01b34, 0x01b44, 0},
|
||||
{0x01b6b, 0x01b73, 0},
|
||||
{0x01b80, 0x01b82, 0},
|
||||
{0x01ba1, 0x01baa, 0},
|
||||
{0x01c24, 0x01c37, 0},
|
||||
{0x01cd0, 0x01cd2, 0},
|
||||
{0x01cd4, 0x01ce8, 0},
|
||||
{0x01ced, 0x01ced, 0},
|
||||
{0x01cf2, 0x01cf2, 0},
|
||||
{0x01dc0, 0x01de6, 0},
|
||||
{0x01dfd, 0x01dff, 0},
|
||||
{0x020d0, 0x020f0, 0},
|
||||
{0x02329, 0x0232a, 2},
|
||||
{0x02cef, 0x02cf1, 0},
|
||||
{0x02de0, 0x02dff, 0},
|
||||
{0x02e80, 0x02e99, 2},
|
||||
{0x02e9b, 0x02ef3, 2},
|
||||
{0x02f00, 0x02fd5, 2},
|
||||
{0x02ff0, 0x02ffb, 2},
|
||||
{0x03000, 0x03029, 2},
|
||||
{0x0302a, 0x0302f, 0},
|
||||
{0x03030, 0x0303e, 2},
|
||||
{0x03041, 0x03096, 2},
|
||||
{0x03099, 0x0309a, 0},
|
||||
{0x0309b, 0x030ff, 2},
|
||||
{0x03105, 0x0312d, 2},
|
||||
{0x03131, 0x0318e, 2},
|
||||
{0x03190, 0x031b7, 2},
|
||||
{0x031c0, 0x031e3, 2},
|
||||
{0x031f0, 0x0321e, 2},
|
||||
{0x03220, 0x03247, 2},
|
||||
{0x03250, 0x032fe, 2},
|
||||
{0x03300, 0x04dbf, 2},
|
||||
{0x04e00, 0x0a48c, 2},
|
||||
{0x0a490, 0x0a4c6, 2},
|
||||
{0x0a66f, 0x0a672, 0},
|
||||
{0x0a67c, 0x0a67d, 0},
|
||||
{0x0a6f0, 0x0a6f1, 0},
|
||||
{0x0a802, 0x0a802, 0},
|
||||
{0x0a806, 0x0a806, 0},
|
||||
{0x0a80b, 0x0a80b, 0},
|
||||
{0x0a823, 0x0a827, 0},
|
||||
{0x0a880, 0x0a881, 0},
|
||||
{0x0a8b4, 0x0a8c4, 0},
|
||||
{0x0a8e0, 0x0a8f1, 0},
|
||||
{0x0a926, 0x0a92d, 0},
|
||||
{0x0a947, 0x0a953, 0},
|
||||
{0x0a960, 0x0a97c, 2},
|
||||
{0x0a980, 0x0a983, 0},
|
||||
{0x0a9b3, 0x0a9c0, 0},
|
||||
{0x0aa29, 0x0aa36, 0},
|
||||
{0x0aa43, 0x0aa43, 0},
|
||||
{0x0aa4c, 0x0aa4d, 0},
|
||||
{0x0aa7b, 0x0aa7b, 0},
|
||||
{0x0aab0, 0x0aab0, 0},
|
||||
{0x0aab2, 0x0aab4, 0},
|
||||
{0x0aab7, 0x0aab8, 0},
|
||||
{0x0aabe, 0x0aabf, 0},
|
||||
{0x0aac1, 0x0aac1, 0},
|
||||
{0x0abe3, 0x0abea, 0},
|
||||
{0x0abec, 0x0abed, 0},
|
||||
{0x0ac00, 0x0d7a3, 2},
|
||||
{0x0d7b0, 0x0d7c6, 2},
|
||||
{0x0d7cb, 0x0d7fb, 2},
|
||||
{0x0f900, 0x0faff, 2},
|
||||
{0x0fb1e, 0x0fb1e, 0},
|
||||
{0x0fe00, 0x0fe0f, 0},
|
||||
{0x0fe10, 0x0fe19, 2},
|
||||
{0x0fe20, 0x0fe26, 0},
|
||||
{0x0fe30, 0x0fe52, 2},
|
||||
{0x0fe54, 0x0fe66, 2},
|
||||
{0x0fe68, 0x0fe6b, 2},
|
||||
{0x0ff01, 0x0ff60, 2},
|
||||
{0x0ffe0, 0x0ffe6, 2},
|
||||
{0x101fd, 0x101fd, 0},
|
||||
{0x10a01, 0x10a03, 0},
|
||||
{0x10a05, 0x10a06, 0},
|
||||
{0x10a0c, 0x10a0f, 0},
|
||||
{0x10a38, 0x10a3a, 0},
|
||||
{0x10a3f, 0x10a3f, 0},
|
||||
{0x11080, 0x11082, 0},
|
||||
{0x110b0, 0x110ba, 0},
|
||||
{0x1d165, 0x1d169, 0},
|
||||
{0x1d16d, 0x1d172, 0},
|
||||
{0x1d17b, 0x1d182, 0},
|
||||
{0x1d185, 0x1d18b, 0},
|
||||
{0x1d1aa, 0x1d1ad, 0},
|
||||
{0x1d242, 0x1d244, 0},
|
||||
{0x1f200, 0x1f200, 2},
|
||||
{0x1f210, 0x1f231, 2},
|
||||
{0x1f240, 0x1f248, 2},
|
||||
{0x20000, 0x2fffd, 2},
|
||||
{0x30000, 0x3fffd, 2},
|
||||
{0xe0100, 0xe01ef, 0}
|
||||
{0x00300, 0x0036f, 0},
|
||||
{0x00483, 0x00489, 0},
|
||||
{0x00591, 0x005bd, 0},
|
||||
{0x005bf, 0x005bf, 0},
|
||||
{0x005c1, 0x005c2, 0},
|
||||
{0x005c4, 0x005c5, 0},
|
||||
{0x005c7, 0x005c7, 0},
|
||||
{0x00610, 0x0061a, 0},
|
||||
{0x0064b, 0x0065e, 0},
|
||||
{0x00670, 0x00670, 0},
|
||||
{0x006d6, 0x006dc, 0},
|
||||
{0x006de, 0x006e4, 0},
|
||||
{0x006e7, 0x006e8, 0},
|
||||
{0x006ea, 0x006ed, 0},
|
||||
{0x00711, 0x00711, 0},
|
||||
{0x00730, 0x0074a, 0},
|
||||
{0x007a6, 0x007b0, 0},
|
||||
{0x007eb, 0x007f3, 0},
|
||||
{0x00816, 0x00819, 0},
|
||||
{0x0081b, 0x00823, 0},
|
||||
{0x00825, 0x00827, 0},
|
||||
{0x00829, 0x0082d, 0},
|
||||
{0x00900, 0x00903, 0},
|
||||
{0x0093c, 0x0093c, 0},
|
||||
{0x0093e, 0x0094e, 0},
|
||||
{0x00951, 0x00955, 0},
|
||||
{0x00962, 0x00963, 0},
|
||||
{0x00981, 0x00983, 0},
|
||||
{0x009bc, 0x009bc, 0},
|
||||
{0x009be, 0x009c4, 0},
|
||||
{0x009c7, 0x009c8, 0},
|
||||
{0x009cb, 0x009cd, 0},
|
||||
{0x009d7, 0x009d7, 0},
|
||||
{0x009e2, 0x009e3, 0},
|
||||
{0x00a01, 0x00a03, 0},
|
||||
{0x00a3c, 0x00a3c, 0},
|
||||
{0x00a3e, 0x00a42, 0},
|
||||
{0x00a47, 0x00a48, 0},
|
||||
{0x00a4b, 0x00a4d, 0},
|
||||
{0x00a51, 0x00a51, 0},
|
||||
{0x00a70, 0x00a71, 0},
|
||||
{0x00a75, 0x00a75, 0},
|
||||
{0x00a81, 0x00a83, 0},
|
||||
{0x00abc, 0x00abc, 0},
|
||||
{0x00abe, 0x00ac5, 0},
|
||||
{0x00ac7, 0x00ac9, 0},
|
||||
{0x00acb, 0x00acd, 0},
|
||||
{0x00ae2, 0x00ae3, 0},
|
||||
{0x00b01, 0x00b03, 0},
|
||||
{0x00b3c, 0x00b3c, 0},
|
||||
{0x00b3e, 0x00b44, 0},
|
||||
{0x00b47, 0x00b48, 0},
|
||||
{0x00b4b, 0x00b4d, 0},
|
||||
{0x00b56, 0x00b57, 0},
|
||||
{0x00b62, 0x00b63, 0},
|
||||
{0x00b82, 0x00b82, 0},
|
||||
{0x00bbe, 0x00bc2, 0},
|
||||
{0x00bc6, 0x00bc8, 0},
|
||||
{0x00bca, 0x00bcd, 0},
|
||||
{0x00bd7, 0x00bd7, 0},
|
||||
{0x00c01, 0x00c03, 0},
|
||||
{0x00c3e, 0x00c44, 0},
|
||||
{0x00c46, 0x00c48, 0},
|
||||
{0x00c4a, 0x00c4d, 0},
|
||||
{0x00c55, 0x00c56, 0},
|
||||
{0x00c62, 0x00c63, 0},
|
||||
{0x00c82, 0x00c83, 0},
|
||||
{0x00cbc, 0x00cbc, 0},
|
||||
{0x00cbe, 0x00cc4, 0},
|
||||
{0x00cc6, 0x00cc8, 0},
|
||||
{0x00cca, 0x00ccd, 0},
|
||||
{0x00cd5, 0x00cd6, 0},
|
||||
{0x00ce2, 0x00ce3, 0},
|
||||
{0x00d02, 0x00d03, 0},
|
||||
{0x00d3e, 0x00d44, 0},
|
||||
{0x00d46, 0x00d48, 0},
|
||||
{0x00d4a, 0x00d4d, 0},
|
||||
{0x00d57, 0x00d57, 0},
|
||||
{0x00d62, 0x00d63, 0},
|
||||
{0x00d82, 0x00d83, 0},
|
||||
{0x00dca, 0x00dca, 0},
|
||||
{0x00dcf, 0x00dd4, 0},
|
||||
{0x00dd6, 0x00dd6, 0},
|
||||
{0x00dd8, 0x00ddf, 0},
|
||||
{0x00df2, 0x00df3, 0},
|
||||
{0x00e31, 0x00e31, 0},
|
||||
{0x00e34, 0x00e3a, 0},
|
||||
{0x00e47, 0x00e4e, 0},
|
||||
{0x00eb1, 0x00eb1, 0},
|
||||
{0x00eb4, 0x00eb9, 0},
|
||||
{0x00ebb, 0x00ebc, 0},
|
||||
{0x00ec8, 0x00ecd, 0},
|
||||
{0x00f18, 0x00f19, 0},
|
||||
{0x00f35, 0x00f35, 0},
|
||||
{0x00f37, 0x00f37, 0},
|
||||
{0x00f39, 0x00f39, 0},
|
||||
{0x00f3e, 0x00f3f, 0},
|
||||
{0x00f71, 0x00f84, 0},
|
||||
{0x00f86, 0x00f87, 0},
|
||||
{0x00f90, 0x00f97, 0},
|
||||
{0x00f99, 0x00fbc, 0},
|
||||
{0x00fc6, 0x00fc6, 0},
|
||||
{0x0102b, 0x0103e, 0},
|
||||
{0x01056, 0x01059, 0},
|
||||
{0x0105e, 0x01060, 0},
|
||||
{0x01062, 0x01064, 0},
|
||||
{0x01067, 0x0106d, 0},
|
||||
{0x01071, 0x01074, 0},
|
||||
{0x01082, 0x0108d, 0},
|
||||
{0x0108f, 0x0108f, 0},
|
||||
{0x0109a, 0x0109d, 0},
|
||||
{0x01100, 0x0115f, 2},
|
||||
{0x011a3, 0x011a7, 2},
|
||||
{0x011fa, 0x011ff, 2},
|
||||
{0x0135f, 0x0135f, 0},
|
||||
{0x01712, 0x01714, 0},
|
||||
{0x01732, 0x01734, 0},
|
||||
{0x01752, 0x01753, 0},
|
||||
{0x01772, 0x01773, 0},
|
||||
{0x017b6, 0x017d3, 0},
|
||||
{0x017dd, 0x017dd, 0},
|
||||
{0x0180b, 0x0180d, 0},
|
||||
{0x018a9, 0x018a9, 0},
|
||||
{0x01920, 0x0192b, 0},
|
||||
{0x01930, 0x0193b, 0},
|
||||
{0x019b0, 0x019c0, 0},
|
||||
{0x019c8, 0x019c9, 0},
|
||||
{0x01a17, 0x01a1b, 0},
|
||||
{0x01a55, 0x01a5e, 0},
|
||||
{0x01a60, 0x01a7c, 0},
|
||||
{0x01a7f, 0x01a7f, 0},
|
||||
{0x01b00, 0x01b04, 0},
|
||||
{0x01b34, 0x01b44, 0},
|
||||
{0x01b6b, 0x01b73, 0},
|
||||
{0x01b80, 0x01b82, 0},
|
||||
{0x01ba1, 0x01baa, 0},
|
||||
{0x01c24, 0x01c37, 0},
|
||||
{0x01cd0, 0x01cd2, 0},
|
||||
{0x01cd4, 0x01ce8, 0},
|
||||
{0x01ced, 0x01ced, 0},
|
||||
{0x01cf2, 0x01cf2, 0},
|
||||
{0x01dc0, 0x01de6, 0},
|
||||
{0x01dfd, 0x01dff, 0},
|
||||
{0x020d0, 0x020f0, 0},
|
||||
{0x02329, 0x0232a, 2},
|
||||
{0x02cef, 0x02cf1, 0},
|
||||
{0x02de0, 0x02dff, 0},
|
||||
{0x02e80, 0x02e99, 2},
|
||||
{0x02e9b, 0x02ef3, 2},
|
||||
{0x02f00, 0x02fd5, 2},
|
||||
{0x02ff0, 0x02ffb, 2},
|
||||
{0x03000, 0x03029, 2},
|
||||
{0x0302a, 0x0302f, 0},
|
||||
{0x03030, 0x0303e, 2},
|
||||
{0x03041, 0x03096, 2},
|
||||
{0x03099, 0x0309a, 0},
|
||||
{0x0309b, 0x030ff, 2},
|
||||
{0x03105, 0x0312d, 2},
|
||||
{0x03131, 0x0318e, 2},
|
||||
{0x03190, 0x031b7, 2},
|
||||
{0x031c0, 0x031e3, 2},
|
||||
{0x031f0, 0x0321e, 2},
|
||||
{0x03220, 0x03247, 2},
|
||||
{0x03250, 0x032fe, 2},
|
||||
{0x03300, 0x04dbf, 2},
|
||||
{0x04e00, 0x0a48c, 2},
|
||||
{0x0a490, 0x0a4c6, 2},
|
||||
{0x0a66f, 0x0a672, 0},
|
||||
{0x0a67c, 0x0a67d, 0},
|
||||
{0x0a6f0, 0x0a6f1, 0},
|
||||
{0x0a802, 0x0a802, 0},
|
||||
{0x0a806, 0x0a806, 0},
|
||||
{0x0a80b, 0x0a80b, 0},
|
||||
{0x0a823, 0x0a827, 0},
|
||||
{0x0a880, 0x0a881, 0},
|
||||
{0x0a8b4, 0x0a8c4, 0},
|
||||
{0x0a8e0, 0x0a8f1, 0},
|
||||
{0x0a926, 0x0a92d, 0},
|
||||
{0x0a947, 0x0a953, 0},
|
||||
{0x0a960, 0x0a97c, 2},
|
||||
{0x0a980, 0x0a983, 0},
|
||||
{0x0a9b3, 0x0a9c0, 0},
|
||||
{0x0aa29, 0x0aa36, 0},
|
||||
{0x0aa43, 0x0aa43, 0},
|
||||
{0x0aa4c, 0x0aa4d, 0},
|
||||
{0x0aa7b, 0x0aa7b, 0},
|
||||
{0x0aab0, 0x0aab0, 0},
|
||||
{0x0aab2, 0x0aab4, 0},
|
||||
{0x0aab7, 0x0aab8, 0},
|
||||
{0x0aabe, 0x0aabf, 0},
|
||||
{0x0aac1, 0x0aac1, 0},
|
||||
{0x0abe3, 0x0abea, 0},
|
||||
{0x0abec, 0x0abed, 0},
|
||||
{0x0ac00, 0x0d7a3, 2},
|
||||
{0x0d7b0, 0x0d7c6, 2},
|
||||
{0x0d7cb, 0x0d7fb, 2},
|
||||
{0x0f900, 0x0faff, 2},
|
||||
{0x0fb1e, 0x0fb1e, 0},
|
||||
{0x0fe00, 0x0fe0f, 0},
|
||||
{0x0fe10, 0x0fe19, 2},
|
||||
{0x0fe20, 0x0fe26, 0},
|
||||
{0x0fe30, 0x0fe52, 2},
|
||||
{0x0fe54, 0x0fe66, 2},
|
||||
{0x0fe68, 0x0fe6b, 2},
|
||||
{0x0ff01, 0x0ff60, 2},
|
||||
{0x0ffe0, 0x0ffe6, 2},
|
||||
{0x101fd, 0x101fd, 0},
|
||||
{0x10a01, 0x10a03, 0},
|
||||
{0x10a05, 0x10a06, 0},
|
||||
{0x10a0c, 0x10a0f, 0},
|
||||
{0x10a38, 0x10a3a, 0},
|
||||
{0x10a3f, 0x10a3f, 0},
|
||||
{0x11080, 0x11082, 0},
|
||||
{0x110b0, 0x110ba, 0},
|
||||
{0x1d165, 0x1d169, 0},
|
||||
{0x1d16d, 0x1d172, 0},
|
||||
{0x1d17b, 0x1d182, 0},
|
||||
{0x1d185, 0x1d18b, 0},
|
||||
{0x1d1aa, 0x1d1ad, 0},
|
||||
{0x1d242, 0x1d244, 0},
|
||||
{0x1f200, 0x1f200, 2},
|
||||
{0x1f210, 0x1f231, 2},
|
||||
{0x1f240, 0x1f248, 2},
|
||||
{0x20000, 0x2fffd, 2},
|
||||
{0x30000, 0x3fffd, 2},
|
||||
{0xe0100, 0xe01ef, 0}
|
||||
};
|
||||
|
||||
/* Get the width of a UTF-8 character. */
|
||||
int utf8_width(char *s)
|
||||
{
|
||||
int val, low, high, cur;
|
||||
int val, low, high, cur;
|
||||
|
||||
if (UTF8_ISCONT(*s))
|
||||
return 0;
|
||||
if (UTF8_ISCONT(*s))
|
||||
return 0;
|
||||
|
||||
switch (UTF8_LENGTH(*s)) {
|
||||
case 1:
|
||||
val = s[0];
|
||||
break;
|
||||
case 2:
|
||||
val = (s[1] & 0x3f) | (s[0] & 0x1f) << 6;
|
||||
break;
|
||||
case 3:
|
||||
val = ((s[2] & 0x3f) | (s[1] & 0x3f) << 6) | (s[0] & 0x0f) << 12;
|
||||
break;
|
||||
case 4:
|
||||
val = (((s[3] & 0x3f) | (s[2] & 0x3f) << 6) |
|
||||
(s[1] & 0x3f) << 12) | (s[0] & 0x3f) << 18;
|
||||
break;
|
||||
case 5:
|
||||
val = ((((s[4] & 0x3f) | (s[3] & 0x3f) << 6) |
|
||||
(s[2] & 0x3f) << 12) | (s[1] & 0x3f) << 18) | (s[0] & 0x3f) << 24;
|
||||
break;
|
||||
case 6:
|
||||
val = (((((s[5] & 0x3f) | (s[4] & 0x3f) << 6) |
|
||||
(s[3] & 0x3f) << 12) | (s[2] & 0x3f) << 18) |
|
||||
(s[1] & 0x3f) << 24) | (s[0] & 0x3f) << 30;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
switch (UTF8_LENGTH(*s)) {
|
||||
case 1:
|
||||
val = s[0];
|
||||
break;
|
||||
case 2:
|
||||
val = (s[1] & 0x3f) | (s[0] & 0x1f) << 6;
|
||||
break;
|
||||
case 3:
|
||||
val = ((s[2] & 0x3f) | (s[1] & 0x3f) << 6) |
|
||||
(s[0] & 0x0f) << 12;
|
||||
break;
|
||||
case 4:
|
||||
val = (((s[3] & 0x3f) | (s[2] & 0x3f) << 6) |
|
||||
(s[1] & 0x3f) << 12) | (s[0] & 0x3f) << 18;
|
||||
break;
|
||||
case 5:
|
||||
val = ((((s[4] & 0x3f) | (s[3] & 0x3f) << 6) |
|
||||
(s[2] & 0x3f) << 12) | (s[1] & 0x3f) << 18) |
|
||||
(s[0] & 0x3f) << 24;
|
||||
break;
|
||||
case 6:
|
||||
val = (((((s[5] & 0x3f) | (s[4] & 0x3f) << 6) |
|
||||
(s[3] & 0x3f) << 12) | (s[2] & 0x3f) << 18) |
|
||||
(s[1] & 0x3f) << 24) | (s[0] & 0x3f) << 30;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
low = 0;
|
||||
high = sizeof(utf8_widthtab) / sizeof(utf8_widthtab[0]);
|
||||
do {
|
||||
cur = (low + high) / 2;
|
||||
if (val >= utf8_widthtab[cur].min) {
|
||||
if (val <= utf8_widthtab[cur].max)
|
||||
return utf8_widthtab[cur].width;
|
||||
else
|
||||
low = cur + 1;
|
||||
} else {
|
||||
high = cur - 1;
|
||||
}
|
||||
}
|
||||
while (low <= high);
|
||||
low = 0;
|
||||
high = sizeof(utf8_widthtab) / sizeof(utf8_widthtab[0]);
|
||||
do {
|
||||
cur = (low + high) / 2;
|
||||
if (val >= utf8_widthtab[cur].min) {
|
||||
if (val <= utf8_widthtab[cur].max)
|
||||
return utf8_widthtab[cur].width;
|
||||
else
|
||||
low = cur + 1;
|
||||
} else {
|
||||
high = cur - 1;
|
||||
}
|
||||
}
|
||||
while (low <= high);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the width of a UTF-8 string. */
|
||||
int utf8_strwidth(char *s)
|
||||
{
|
||||
int width = 0;
|
||||
int width = 0;
|
||||
|
||||
for (; s && *s; s++) {
|
||||
if (!UTF8_ISCONT(*s))
|
||||
width += utf8_width(s);
|
||||
}
|
||||
for (; s && *s; s++) {
|
||||
if (!UTF8_ISCONT(*s))
|
||||
width += utf8_width(s);
|
||||
}
|
||||
|
||||
return width;
|
||||
return width;
|
||||
}
|
||||
|
1749
src/utils.c
1749
src/utils.c
File diff suppressed because it is too large
Load Diff
114
src/vars.c
114
src/vars.c
@ -70,29 +70,29 @@ const char *datefmt_str[DATE_FORMATS];
|
||||
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
const char *monthnames[12] = {
|
||||
N_("January"),
|
||||
N_("February"),
|
||||
N_("March"),
|
||||
N_("April"),
|
||||
N_("May"),
|
||||
N_("June"),
|
||||
N_("July"),
|
||||
N_("August"),
|
||||
N_("September"),
|
||||
N_("October"),
|
||||
N_("November"),
|
||||
N_("December")
|
||||
N_("January"),
|
||||
N_("February"),
|
||||
N_("March"),
|
||||
N_("April"),
|
||||
N_("May"),
|
||||
N_("June"),
|
||||
N_("July"),
|
||||
N_("August"),
|
||||
N_("September"),
|
||||
N_("October"),
|
||||
N_("November"),
|
||||
N_("December")
|
||||
};
|
||||
|
||||
const char *daynames[8] = {
|
||||
N_("Sun"),
|
||||
N_("Mon"),
|
||||
N_("Tue"),
|
||||
N_("Wed"),
|
||||
N_("Thu"),
|
||||
N_("Fri"),
|
||||
N_("Sat"),
|
||||
N_("Sun")
|
||||
N_("Sun"),
|
||||
N_("Mon"),
|
||||
N_("Tue"),
|
||||
N_("Wed"),
|
||||
N_("Thu"),
|
||||
N_("Fri"),
|
||||
N_("Sat"),
|
||||
N_("Sun")
|
||||
};
|
||||
|
||||
/*
|
||||
@ -126,50 +126,50 @@ struct dmon_conf dmon;
|
||||
*/
|
||||
void vars_init(void)
|
||||
{
|
||||
const char *ed, *pg;
|
||||
const char *ed, *pg;
|
||||
|
||||
/* Variables for user configuration */
|
||||
conf.confirm_quit = 1;
|
||||
conf.confirm_delete = 1;
|
||||
conf.auto_save = 1;
|
||||
conf.auto_gc = 0;
|
||||
conf.periodic_save = 0;
|
||||
conf.default_panel = CAL;
|
||||
conf.compact_panels = 0;
|
||||
conf.system_dialogs = 1;
|
||||
conf.progress_bar = 1;
|
||||
strncpy(conf.output_datefmt, "%D", 3);
|
||||
conf.input_datefmt = 1;
|
||||
/* Variables for user configuration */
|
||||
conf.confirm_quit = 1;
|
||||
conf.confirm_delete = 1;
|
||||
conf.auto_save = 1;
|
||||
conf.auto_gc = 0;
|
||||
conf.periodic_save = 0;
|
||||
conf.default_panel = CAL;
|
||||
conf.compact_panels = 0;
|
||||
conf.system_dialogs = 1;
|
||||
conf.progress_bar = 1;
|
||||
strncpy(conf.output_datefmt, "%D", 3);
|
||||
conf.input_datefmt = 1;
|
||||
|
||||
datefmt_str[0] = _("mm/dd/yyyy");
|
||||
datefmt_str[1] = _("dd/mm/yyyy");
|
||||
datefmt_str[2] = _("yyyy/mm/dd");
|
||||
datefmt_str[3] = _("yyyy-mm-dd");
|
||||
datefmt_str[0] = _("mm/dd/yyyy");
|
||||
datefmt_str[1] = _("dd/mm/yyyy");
|
||||
datefmt_str[2] = _("yyyy/mm/dd");
|
||||
datefmt_str[3] = _("yyyy-mm-dd");
|
||||
|
||||
/* Default external editor and pager */
|
||||
ed = getenv("VISUAL");
|
||||
if (ed == NULL || ed[0] == '\0')
|
||||
ed = getenv("EDITOR");
|
||||
if (ed == NULL || ed[0] == '\0')
|
||||
ed = DEFAULT_EDITOR;
|
||||
conf.editor = ed;
|
||||
/* Default external editor and pager */
|
||||
ed = getenv("VISUAL");
|
||||
if (ed == NULL || ed[0] == '\0')
|
||||
ed = getenv("EDITOR");
|
||||
if (ed == NULL || ed[0] == '\0')
|
||||
ed = DEFAULT_EDITOR;
|
||||
conf.editor = ed;
|
||||
|
||||
pg = getenv("PAGER");
|
||||
if (pg == NULL || pg[0] == '\0')
|
||||
pg = DEFAULT_PAGER;
|
||||
conf.pager = pg;
|
||||
pg = getenv("PAGER");
|
||||
if (pg == NULL || pg[0] == '\0')
|
||||
pg = DEFAULT_PAGER;
|
||||
conf.pager = pg;
|
||||
|
||||
wins_set_layout(1);
|
||||
wins_set_layout(1);
|
||||
|
||||
ui_calendar_set_first_day_of_week(MONDAY);
|
||||
ui_calendar_set_first_day_of_week(MONDAY);
|
||||
|
||||
/* Pad structure to scroll text inside the appointment panel */
|
||||
apad.length = 1;
|
||||
apad.first_onscreen = 0;
|
||||
/* Pad structure to scroll text inside the appointment panel */
|
||||
apad.length = 1;
|
||||
apad.first_onscreen = 0;
|
||||
|
||||
/* Attribute definitions for color and non-color terminals */
|
||||
custom_init_attr();
|
||||
/* Attribute definitions for color and non-color terminals */
|
||||
custom_init_attr();
|
||||
|
||||
/* Start at the current date */
|
||||
ui_calendar_init_slctd_day();
|
||||
/* Start at the current date */
|
||||
ui_calendar_init_slctd_day();
|
||||
}
|
||||
|
745
src/wins.c
745
src/wins.c
File diff suppressed because it is too large
Load Diff
253
test/run-test.c
253
test/run-test.c
@ -52,181 +52,184 @@
|
||||
static int
|
||||
fork_exec(int *pfdin, int *pfdout, const char *path, char *const *arg)
|
||||
{
|
||||
int pin[2], pout[2];
|
||||
int pid;
|
||||
int pin[2], pout[2];
|
||||
int pid;
|
||||
|
||||
if (pfdin && (pipe(pin) == -1))
|
||||
return 0;
|
||||
if (pfdout && (pipe(pout) == -1))
|
||||
return 0;
|
||||
if (pfdin && (pipe(pin) == -1))
|
||||
return 0;
|
||||
if (pfdout && (pipe(pout) == -1))
|
||||
return 0;
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
if (pfdout) {
|
||||
if (dup2(pout[0], STDIN_FILENO) < 0)
|
||||
_exit(127);
|
||||
close(pout[0]);
|
||||
close(pout[1]);
|
||||
}
|
||||
if ((pid = fork()) == 0) {
|
||||
if (pfdout) {
|
||||
if (dup2(pout[0], STDIN_FILENO) < 0)
|
||||
_exit(127);
|
||||
close(pout[0]);
|
||||
close(pout[1]);
|
||||
}
|
||||
|
||||
if (pfdin) {
|
||||
if (dup2(pin[1], STDOUT_FILENO) < 0)
|
||||
_exit(127);
|
||||
close(pin[0]);
|
||||
close(pin[1]);
|
||||
}
|
||||
if (pfdin) {
|
||||
if (dup2(pin[1], STDOUT_FILENO) < 0)
|
||||
_exit(127);
|
||||
close(pin[0]);
|
||||
close(pin[1]);
|
||||
}
|
||||
|
||||
execvp(path, arg);
|
||||
_exit(127);
|
||||
} else {
|
||||
if (pfdin)
|
||||
close(pin[1]);
|
||||
if (pfdout)
|
||||
close(pout[0]);
|
||||
execvp(path, arg);
|
||||
_exit(127);
|
||||
} else {
|
||||
if (pfdin)
|
||||
close(pin[1]);
|
||||
if (pfdout)
|
||||
close(pout[0]);
|
||||
|
||||
if (pid > 0) {
|
||||
if (pfdin) {
|
||||
fcntl(pin[0], F_SETFD, FD_CLOEXEC);
|
||||
*pfdin = pin[0];
|
||||
}
|
||||
if (pfdout) {
|
||||
fcntl(pout[1], F_SETFD, FD_CLOEXEC);
|
||||
*pfdout = pout[1];
|
||||
}
|
||||
} else {
|
||||
if (pfdin)
|
||||
close(pin[0]);
|
||||
if (pfdout)
|
||||
close(pout[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return pid;
|
||||
if (pid > 0) {
|
||||
if (pfdin) {
|
||||
fcntl(pin[0], F_SETFD, FD_CLOEXEC);
|
||||
*pfdin = pin[0];
|
||||
}
|
||||
if (pfdout) {
|
||||
fcntl(pout[1], F_SETFD, FD_CLOEXEC);
|
||||
*pfdout = pout[1];
|
||||
}
|
||||
} else {
|
||||
if (pfdin)
|
||||
close(pin[0]);
|
||||
if (pfdout)
|
||||
close(pout[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* Wait for a child process to terminate. */
|
||||
static int child_wait(int *pfdin, int *pfdout, int pid)
|
||||
{
|
||||
int stat;
|
||||
int stat;
|
||||
|
||||
if (pfdin)
|
||||
close(*pfdin);
|
||||
if (pfdout)
|
||||
close(*pfdout);
|
||||
if (pfdin)
|
||||
close(*pfdin);
|
||||
if (pfdout)
|
||||
close(*pfdout);
|
||||
|
||||
waitpid(pid, &stat, 0);
|
||||
return stat;
|
||||
waitpid(pid, &stat, 0);
|
||||
return stat;
|
||||
}
|
||||
|
||||
/* Print error message and bail out. */
|
||||
static void die(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_list arg;
|
||||
|
||||
va_start(arg, format);
|
||||
fprintf(stderr, "error: ");
|
||||
vfprintf(stderr, format, arg);
|
||||
va_end(arg);
|
||||
va_start(arg, format);
|
||||
fprintf(stderr, "error: ");
|
||||
vfprintf(stderr, format, arg);
|
||||
va_end(arg);
|
||||
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Print usage message. */
|
||||
static void usage(void)
|
||||
{
|
||||
printf("usage: run-test [-h|--help] <test>...\n");
|
||||
printf("usage: run-test [-h|--help] <test>...\n");
|
||||
}
|
||||
|
||||
/* Run test with a specific name. */
|
||||
static int run_test(const char *name, int expect_failure)
|
||||
{
|
||||
char filename[BUFSIZ];
|
||||
char *arg1[3], *arg2[3];
|
||||
int pid1 = -1, pin1, pid2 = -1, pin2;
|
||||
FILE *fpin1 = NULL, *fpin2 = NULL;
|
||||
char buf1[BUFSIZ], buf2[BUFSIZ];
|
||||
int ret = 1;
|
||||
char filename[BUFSIZ];
|
||||
char *arg1[3], *arg2[3];
|
||||
int pid1 = -1, pin1, pid2 = -1, pin2;
|
||||
FILE *fpin1 = NULL, *fpin2 = NULL;
|
||||
char buf1[BUFSIZ], buf2[BUFSIZ];
|
||||
int ret = 1;
|
||||
|
||||
if (snprintf(filename, BUFSIZ, "./%s", name) >= BUFSIZ)
|
||||
die("file name too long\n");
|
||||
if (snprintf(filename, BUFSIZ, "./%s", name) >= BUFSIZ)
|
||||
die("file name too long\n");
|
||||
|
||||
if (access(filename, F_OK) != 0) {
|
||||
if (snprintf(filename, BUFSIZ, "./%s.sh", name) >= BUFSIZ)
|
||||
die("file name too long\n");
|
||||
if (access(filename, F_OK) != 0) {
|
||||
if (snprintf(filename, BUFSIZ, "./%s.sh", name) >= BUFSIZ)
|
||||
die("file name too long\n");
|
||||
|
||||
if (access(filename, F_OK) != 0)
|
||||
die("test not found: %s\n", name);
|
||||
}
|
||||
if (access(filename, F_OK) != 0)
|
||||
die("test not found: %s\n", name);
|
||||
}
|
||||
|
||||
if (access(filename, X_OK) != 0)
|
||||
die("script is not executable: %s\n", filename);
|
||||
if (access(filename, X_OK) != 0)
|
||||
die("script is not executable: %s\n", filename);
|
||||
|
||||
arg1[0] = arg2[0] = filename;
|
||||
arg1[1] = "expected";
|
||||
arg2[1] = "actual";
|
||||
arg1[2] = arg2[2] = NULL;
|
||||
arg1[0] = arg2[0] = filename;
|
||||
arg1[1] = "expected";
|
||||
arg2[1] = "actual";
|
||||
arg1[2] = arg2[2] = NULL;
|
||||
|
||||
printf("Running %s...", name);
|
||||
printf("Running %s...", name);
|
||||
|
||||
if ((pid1 = fork_exec(&pin1, NULL, *arg1, arg1)) < 0)
|
||||
die("failed to execute %s: %s\n", filename, strerror(errno));
|
||||
if ((pid1 = fork_exec(&pin1, NULL, *arg1, arg1)) < 0)
|
||||
die("failed to execute %s: %s\n", filename,
|
||||
strerror(errno));
|
||||
|
||||
if ((pid2 = fork_exec(&pin2, NULL, *arg2, arg2)) < 0)
|
||||
die("failed to execute %s: %s\n", filename, strerror(errno));
|
||||
if ((pid2 = fork_exec(&pin2, NULL, *arg2, arg2)) < 0)
|
||||
die("failed to execute %s: %s\n", filename,
|
||||
strerror(errno));
|
||||
|
||||
fpin1 = fdopen(pin1, "r");
|
||||
fpin2 = fdopen(pin2, "r");
|
||||
fpin1 = fdopen(pin1, "r");
|
||||
fpin2 = fdopen(pin2, "r");
|
||||
|
||||
while (fgets(buf1, BUFSIZ, fpin1)) {
|
||||
if (!fgets(buf2, BUFSIZ, fpin2) || strcmp(buf1, buf2) != 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (fgets(buf1, BUFSIZ, fpin1)) {
|
||||
if (!fgets(buf2, BUFSIZ, fpin2) || strcmp(buf1, buf2) != 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fgets(buf2, BUFSIZ, fpin2))
|
||||
ret = 0;
|
||||
if (fgets(buf2, BUFSIZ, fpin2))
|
||||
ret = 0;
|
||||
|
||||
if (fpin1)
|
||||
fclose(fpin1);
|
||||
if (fpin2)
|
||||
fclose(fpin2);
|
||||
if (fpin1)
|
||||
fclose(fpin1);
|
||||
if (fpin2)
|
||||
fclose(fpin2);
|
||||
|
||||
if (child_wait(&pin1, NULL, pid1) != 0)
|
||||
ret = 0;
|
||||
if (child_wait(&pin2, NULL, pid2) != 0)
|
||||
ret = 0;
|
||||
if (child_wait(&pin1, NULL, pid1) != 0)
|
||||
ret = 0;
|
||||
if (child_wait(&pin2, NULL, pid2) != 0)
|
||||
ret = 0;
|
||||
|
||||
if (expect_failure)
|
||||
ret = 1 - ret;
|
||||
if (expect_failure)
|
||||
ret = 1 - ret;
|
||||
|
||||
if (ret == 1)
|
||||
printf(" ok\n");
|
||||
else
|
||||
printf(" FAIL\n");
|
||||
if (ret == 1)
|
||||
printf(" ok\n");
|
||||
else
|
||||
printf(" FAIL\n");
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (!argv[1])
|
||||
die("no tests specified, bailing out\n");
|
||||
else if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
if (!argv[1])
|
||||
die("no tests specified, bailing out\n");
|
||||
else if (strcmp(argv[1], "-h") == 0
|
||||
|| strcmp(argv[1], "--help") == 0) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (*argv[i] == '!') {
|
||||
if (!run_test(argv[i] + 1, 1))
|
||||
return 1;
|
||||
} else {
|
||||
if (!run_test(argv[i], 0))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (*argv[i] == '!') {
|
||||
if (!run_test(argv[i] + 1, 1))
|
||||
return 1;
|
||||
} else {
|
||||
if (!run_test(argv[i], 0))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user