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