Always use wide characters.

This commit is contained in:
Felicity Tarnell 2014-03-08 00:30:40 +00:00
parent d239b1669b
commit 003ac6cca4
18 changed files with 546 additions and 588 deletions

View file

@ -17,71 +17,71 @@
binding_list_t bindings = TTS_TAILQ_HEAD_INITIALIZER(bindings); binding_list_t bindings = TTS_TAILQ_HEAD_INITIALIZER(bindings);
static tkey_t keys[] = { static tkey_t keys[] = {
{ KEY_BREAK, WIDE("<BREAK>") }, { KEY_BREAK, L"<BREAK>" },
{ KEY_DOWN, WIDE("<DOWN>") }, { KEY_DOWN, L"<DOWN>" },
{ KEY_UP, WIDE("<UP>") }, { KEY_UP, L"<UP>" },
{ KEY_LEFT, WIDE("<LEFT>") }, { KEY_LEFT, L"<LEFT>" },
{ KEY_RIGHT, WIDE("<RIGHT>") }, { KEY_RIGHT, L"<RIGHT>" },
{ KEY_HOME, WIDE("<HOME>") }, { KEY_HOME, L"<HOME>" },
{ KEY_BACKSPACE, WIDE("<BACKSPACE>") }, { KEY_BACKSPACE, L"<BACKSPACE>" },
{ 0x7F, WIDE("<BACKSPACE>") }, /* DEL */ { 0x7F, L"<BACKSPACE>" }, /* DEL */
{ KEY_F(0), WIDE("<F0>") }, { KEY_F(0), L"<F0>" },
{ KEY_F(1), WIDE("<F1>") }, { KEY_F(1), L"<F1>" },
{ KEY_F(2), WIDE("<F2>") }, { KEY_F(2), L"<F2>" },
{ KEY_F(3), WIDE("<F3>") }, { KEY_F(3), L"<F3>" },
{ KEY_F(4), WIDE("<F4>") }, { KEY_F(4), L"<F4>" },
{ KEY_F(5), WIDE("<F5>") }, { KEY_F(5), L"<F5>" },
{ KEY_F(6), WIDE("<F6>") }, { KEY_F(6), L"<F6>" },
{ KEY_F(7), WIDE("<F7>") }, { KEY_F(7), L"<F7>" },
{ KEY_F(8), WIDE("<F8>") }, { KEY_F(8), L"<F8>" },
{ KEY_F(9), WIDE("<F9>") }, { KEY_F(9), L"<F9>" },
{ KEY_F(10), WIDE("<F10>") }, { KEY_F(10), L"<F10>" },
{ KEY_F(11), WIDE("<F1l>") }, { KEY_F(11), L"<F1l>" },
{ KEY_F(12), WIDE("<F12>") }, { KEY_F(12), L"<F12>" },
{ KEY_F(13), WIDE("<F13>") }, { KEY_F(13), L"<F13>" },
{ KEY_F(14), WIDE("<F14>") }, { KEY_F(14), L"<F14>" },
{ KEY_F(15), WIDE("<F15>") }, { KEY_F(15), L"<F15>" },
{ KEY_F(16), WIDE("<F16>") }, { KEY_F(16), L"<F16>" },
{ KEY_F(17), WIDE("<F17>") }, { KEY_F(17), L"<F17>" },
{ KEY_F(18), WIDE("<F18>") }, { KEY_F(18), L"<F18>" },
{ KEY_F(19), WIDE("<F19>") }, { KEY_F(19), L"<F19>" },
{ KEY_F(20), WIDE("<F20>") }, { KEY_F(20), L"<F20>" },
{ KEY_F(21), WIDE("<F21>") }, { KEY_F(21), L"<F21>" },
{ KEY_F(22), WIDE("<F22>") }, { KEY_F(22), L"<F22>" },
{ KEY_F(23), WIDE("<F23>") }, { KEY_F(23), L"<F23>" },
{ KEY_F(24), WIDE("<F24>") }, { KEY_F(24), L"<F24>" },
{ KEY_NPAGE, WIDE("<NEXT>") }, { KEY_NPAGE, L"<NEXT>" },
{ KEY_PPAGE, WIDE("<PREV>") }, { KEY_PPAGE, L"<PREV>" },
{ '\001', WIDE("<CTRL-A>") }, { '\001', L"<CTRL-A>" },
{ '\002', WIDE("<CTRL-B>") }, { '\002', L"<CTRL-B>" },
{ '\003', WIDE("<CTRL-C>") }, { '\003', L"<CTRL-C>" },
{ '\004', WIDE("<CTRL-D>") }, { '\004', L"<CTRL-D>" },
{ '\005', WIDE("<CTRL-E>") }, { '\005', L"<CTRL-E>" },
{ '\006', WIDE("<CTRL-F>") }, { '\006', L"<CTRL-F>" },
{ '\007', WIDE("<CTRL-G>") }, { '\007', L"<CTRL-G>" },
{ '\010', WIDE("<CTRL-H>") }, { '\010', L"<CTRL-H>" },
{ '\011', WIDE("<CTRL-I>") }, { '\011', L"<CTRL-I>" },
{ '\011', WIDE("<TAB>") }, { '\011', L"<TAB>" },
{ '\012', WIDE("<CTRL-J>") }, { '\012', L"<CTRL-J>" },
{ '\013', WIDE("<CTRL-K>") }, { '\013', L"<CTRL-K>" },
{ '\014', WIDE("<CTRL-L>") }, { '\014', L"<CTRL-L>" },
{ '\015', WIDE("<CTRL-N>") }, { '\015', L"<CTRL-N>" },
{ '\016', WIDE("<CTRL-O>") }, { '\016', L"<CTRL-O>" },
{ '\017', WIDE("<CTRL-P>") }, { '\017', L"<CTRL-P>" },
{ '\020', WIDE("<CTRL-Q>") }, { '\020', L"<CTRL-Q>" },
{ '\021', WIDE("<CTRL-R>") }, { '\021', L"<CTRL-R>" },
{ '\022', WIDE("<CTRL-S>") }, { '\022', L"<CTRL-S>" },
{ '\023', WIDE("<CTRL-T>") }, { '\023', L"<CTRL-T>" },
{ '\024', WIDE("<CTRL-U>") }, { '\024', L"<CTRL-U>" },
{ '\025', WIDE("<CTRL-V>") }, { '\025', L"<CTRL-V>" },
{ '\026', WIDE("<CTRL-W>") }, { '\026', L"<CTRL-W>" },
{ '\027', WIDE("<CTRL-X>") }, { '\027', L"<CTRL-X>" },
{ '\030', WIDE("<CTRL-Y>") }, { '\030', L"<CTRL-Y>" },
{ '\031', WIDE("<CTRL-Z>") }, { '\031', L"<CTRL-Z>" },
{ ' ', WIDE("<SPACE>") }, { ' ', L"<SPACE>" },
{ KEY_ENTER, WIDE("<ENTER>") }, { KEY_ENTER, L"<ENTER>" },
{ KEY_BACKSPACE, WIDE("<BACKSPACE>") }, { KEY_BACKSPACE, L"<BACKSPACE>" },
{ KEY_DC, WIDE("<DELETE>") } { KEY_DC, L"<DELETE>" }
}; };
/* /*
@ -93,17 +93,17 @@ static tkey_t keys[] = {
*/ */
void void
bind_key(keyname, funcname, is_macro) bind_key(keyname, funcname, is_macro)
const WCHAR *keyname, *funcname; const wchar_t *keyname, *funcname;
{ {
tkey_t *key = NULL; tkey_t *key = NULL;
function_t *func; function_t *func;
binding_t *binding; binding_t *binding;
INT code; wint_t code;
/* Find the key and the function */ /* Find the key and the function */
if (STRLEN(keyname) > 1) { if (wcslen(keyname) > 1) {
if ((key = find_key(keyname)) == NULL) { if ((key = find_key(keyname)) == NULL) {
errbox(WIDE("Unknown key \"%"FMT_L"s\""), keyname); errbox(L"Unknown key \"%ls\"", keyname);
return; return;
} }
code = key->ky_code; code = key->ky_code;
@ -112,7 +112,7 @@ INT code;
if (!is_macro) { if (!is_macro) {
if ((func = find_func(funcname)) == NULL) { if ((func = find_func(funcname)) == NULL) {
errbox(WIDE("Unknown function \"%"FMT_L"s\""), funcname); errbox(L"Unknown function \"%ls\"", funcname);
return; return;
} }
} }
@ -122,7 +122,7 @@ INT code;
if (binding->bi_code == code) { if (binding->bi_code == code) {
if (is_macro) { if (is_macro) {
binding->bi_func = NULL; binding->bi_func = NULL;
binding->bi_macro = STRDUP(funcname); binding->bi_macro = wcsdup(funcname);
} else { } else {
free(binding->bi_macro); free(binding->bi_macro);
binding->bi_func = func; binding->bi_func = func;
@ -139,7 +139,7 @@ INT code;
binding->bi_code = code; binding->bi_code = code;
if (is_macro) if (is_macro)
binding->bi_macro = STRDUP(funcname); binding->bi_macro = wcsdup(funcname);
else else
binding->bi_func = func; binding->bi_func = func;
@ -152,13 +152,43 @@ INT code;
*/ */
tkey_t * tkey_t *
find_key(name) find_key(name)
const WCHAR *name; const wchar_t *name;
{ {
size_t i; size_t i;
for (i = 0; i < sizeof(keys) / sizeof(*keys); i++) for (i = 0; i < sizeof(keys) / sizeof(*keys); i++)
if (STRCMP(name, keys[i].ky_name) == 0) if (wcscmp(name, keys[i].ky_name) == 0)
return &keys[i]; return &keys[i];
return NULL; return NULL;
} }
void
bind_defaults(void)
{
bind_key(L"?", L"help", 0);
bind_key(L"a", L"add", 0);
bind_key(L"A", L"add-old", 0);
bind_key(L"d", L"delete", 0);
bind_key(L"u", L"undelete", 0);
bind_key(L"q", L"quit", 0);
bind_key(L"<CTRL-C>", L"quit", 0);
bind_key(L"i", L"invoice", 0);
bind_key(L"b", L"billable", 0);
bind_key(L"m", L"mark", 0);
bind_key(L"U", L"unmarkall", 0);
bind_key(L"<SPACE>", L"startstop", 0);
bind_key(L"e", L"edit-desc", 0);
bind_key(L"\\", L"edit-time", 0);
bind_key(L"<TAB>", L"showhide-inv", 0);
bind_key(L"c", L"copy", 0);
bind_key(L"+", L"add-time", 0);
bind_key(L"-", L"sub-time", 0);
bind_key(L"/", L"search", 0);
bind_key(L"$", L"sync", 0);
bind_key(L"<UP>", L"prev", 0);
bind_key(L"<DOWN>", L"next", 0);
bind_key(L":", L"execute", 0);
bind_key(L"M", L"merge", 0);
bind_key(L"r", L"interrupt", 0);
bind_key(L"R", L"interrupt", 0);
}

View file

@ -16,15 +16,15 @@
#include "tailq.h" #include "tailq.h"
typedef struct tkey { typedef struct tkey {
INT ky_code; wint_t ky_code;
const WCHAR *ky_name; const wchar_t *ky_name;
} tkey_t; } tkey_t;
typedef struct binding { typedef struct binding {
INT bi_code; wint_t bi_code;
tkey_t *bi_key; tkey_t *bi_key;
function_t *bi_func; function_t *bi_func;
WCHAR *bi_macro; wchar_t *bi_macro;
TTS_TAILQ_ENTRY(binding) bi_entries; TTS_TAILQ_ENTRY(binding) bi_entries;
} binding_t; } binding_t;
@ -32,7 +32,9 @@ typedef struct binding {
typedef TTS_TAILQ_HEAD(bindlist, binding) binding_list_t; typedef TTS_TAILQ_HEAD(bindlist, binding) binding_list_t;
extern binding_list_t bindings; extern binding_list_t bindings;
tkey_t *find_key(const WCHAR *name); void bind_defaults();
void bind_key(const WCHAR *key, const WCHAR *func, int is_macro); tkey_t *find_key(const wchar_t *name);
void bind_key(const wchar_t *key, const wchar_t *func, int is_macro);
#endif /* !TTS_BINDINGS_H */ #endif /* !TTS_BINDINGS_H */

View file

@ -14,20 +14,20 @@
#include "variable.h" #include "variable.h"
static command_t commands[] = { static command_t commands[] = {
{ WIDE("bind"), c_bind }, { L"bind", c_bind },
{ WIDE("macro"), c_macro }, { L"macro", c_macro },
{ WIDE("style"), c_style }, { L"style", c_style },
{ WIDE("set"), c_set }, { L"set", c_set },
{ } { }
}; };
command_t * command_t *
find_command(name) find_command(name)
const WCHAR *name; const wchar_t *name;
{ {
size_t i; size_t i;
for (i = 0; i < sizeof(commands) / sizeof(*commands); i++) for (i = 0; i < sizeof(commands) / sizeof(*commands); i++)
if (STRCMP(name, commands[i].cm_name) == 0) if (wcscmp(name, commands[i].cm_name) == 0)
return &commands[i]; return &commands[i];
return NULL; return NULL;
} }
@ -35,36 +35,36 @@ size_t i;
void void
c_style(argc, argv) c_style(argc, argv)
size_t argc; size_t argc;
WCHAR **argv; wchar_t **argv;
{ {
style_t *sy; style_t *sy;
WCHAR *last, *tok; wchar_t *last, *tok;
if (argc < 3 || argc > 4) { if (argc < 3 || argc > 4) {
cmderr(WIDE("Usage: style <item> <foreground> [background]")); cmderr(L"Usage: style <item> <foreground> [background]");
return; return;
} }
if (STRCMP(argv[1], WIDE("header")) == 0) if (wcscmp(argv[1], L"header") == 0)
sy = &sy_header; sy = &sy_header;
else if (STRCMP(argv[1], WIDE("status")) == 0) else if (wcscmp(argv[1], L"status") == 0)
sy = &sy_status; sy = &sy_status;
else if (STRCMP(argv[1], WIDE("entry")) == 0) else if (wcscmp(argv[1], L"entry") == 0)
sy = &sy_entry; sy = &sy_entry;
else if (STRCMP(argv[1], WIDE("selected")) == 0) else if (wcscmp(argv[1], L"selected") == 0)
sy = &sy_selected; sy = &sy_selected;
else if (STRCMP(argv[1], WIDE("running")) == 0) else if (wcscmp(argv[1], L"running") == 0)
sy = &sy_running; sy = &sy_running;
else if (STRCMP(argv[1], WIDE("date")) == 0) else if (wcscmp(argv[1], L"date") == 0)
sy = &sy_date; sy = &sy_date;
else { else {
cmderr(WIDE("Unknown style item.")); cmderr(L"Unknown style item.");
return; return;
} }
style_clear(sy); style_clear(sy);
for (tok = STRTOK(argv[2], WIDE(","), &last); tok != NULL; for (tok = wcstok(argv[2], L",", &last); tok != NULL;
tok = STRTOK(NULL, WIDE(","), &last)) { tok = wcstok(NULL, L",", &last)) {
style_add(sy, tok, argv[3]); style_add(sy, tok, argv[3]);
} }
@ -74,10 +74,10 @@ WCHAR *last, *tok;
void void
c_bind(argc, argv) c_bind(argc, argv)
size_t argc; size_t argc;
WCHAR **argv; wchar_t **argv;
{ {
if (argc != 3) { if (argc != 3) {
cmderr(WIDE("Usage: bind <key> <function>")); cmderr(L"Usage: bind <key> <function>");
return; return;
} }
@ -87,10 +87,10 @@ c_bind(argc, argv)
void void
c_macro(argc, argv) c_macro(argc, argv)
size_t argc; size_t argc;
WCHAR **argv; wchar_t **argv;
{ {
if (argc != 3) { if (argc != 3) {
cmderr(WIDE("Usage: macro <key> <def>")); cmderr(L"Usage: macro <key> <def>");
return; return;
} }
@ -100,35 +100,35 @@ c_macro(argc, argv)
void void
c_set(argc, argv) c_set(argc, argv)
size_t argc; size_t argc;
WCHAR **argv; wchar_t **argv;
{ {
variable_t *var; variable_t *var;
int val; int val;
if (argc != 3) { if (argc != 3) {
cmderr(WIDE("Usage: set <variable> <value>")); cmderr(L"Usage: set <variable> <value>");
return; return;
} }
if ((var = find_variable(argv[1])) == NULL) { if ((var = find_variable(argv[1])) == NULL) {
cmderr(WIDE("Unknown variable \"%"FMT_L"s\"."), argv[1]); cmderr(L"Unknown variable \"%ls\".", argv[1]);
return; return;
} }
switch (var->va_type) { switch (var->va_type) {
case VTYPE_BOOL: case VTYPE_BOOL:
if (STRCMP(argv[2], WIDE("true")) == 0 || if (wcscmp(argv[2], L"true") == 0 ||
STRCMP(argv[2], WIDE("yes")) == 0 || wcscmp(argv[2], L"yes") == 0 ||
STRCMP(argv[2], WIDE("on")) == 0 || wcscmp(argv[2], L"on") == 0 ||
STRCMP(argv[2], WIDE("1")) == 0) { wcscmp(argv[2], L"1") == 0) {
val = 1; val = 1;
} else if (STRCMP(argv[2], WIDE("false")) == 0 || } else if (wcscmp(argv[2], L"false") == 0 ||
STRCMP(argv[2], WIDE("no")) == 0 || wcscmp(argv[2], L"no") == 0 ||
STRCMP(argv[2], WIDE("off")) == 0 || wcscmp(argv[2], L"off") == 0 ||
STRCMP(argv[2], WIDE("0")) == 0) { wcscmp(argv[2], L"0") == 0) {
val = 0; val = 0;
} else { } else {
cmderr(WIDE("Invalid value for boolean: \"%"FMT_L"s\"."), argv[2]); cmderr(L"Invalid value for boolean: \"%ls\".", argv[2]);
return; return;
} }
@ -136,11 +136,11 @@ int val;
break; break;
case VTYPE_STRING: case VTYPE_STRING:
*(WCHAR **)var->va_addr = STRDUP(argv[2]); *(wchar_t **)var->va_addr = wcsdup(argv[2]);
break; break;
case VTYPE_INT: case VTYPE_INT:
*(int *)var->va_addr = STRTOL(argv[2], NULL, 0); *(int *)var->va_addr = wcstol(argv[2], NULL, 0);
break; break;
} }
} }

View file

@ -16,18 +16,18 @@
#include "wide.h" #include "wide.h"
typedef struct command { typedef struct command {
const WCHAR *cm_name; const wchar_t *cm_name;
void (*cm_hdl) (size_t, WCHAR **); void (*cm_hdl) (size_t, wchar_t **);
} command_t; } command_t;
command_t *find_command(const WCHAR *); command_t *find_command(const wchar_t *);
void c_bind (size_t, WCHAR **); void c_bind (size_t, wchar_t **);
void c_style (size_t, WCHAR **); void c_style (size_t, wchar_t **);
void c_set (size_t, WCHAR **); void c_set (size_t, wchar_t **);
void c_macro (size_t, WCHAR **); void c_macro (size_t, wchar_t **);
void cmderr (const WCHAR *, ...); void cmderr (const wchar_t *, ...);
void vcmderr (const WCHAR *, va_list); void vcmderr (const wchar_t *, va_list);
#endif /* !TTS_COMMANDS_H */ #endif /* !TTS_COMMANDS_H */

View file

@ -23,18 +23,18 @@ entry_t *running;
entry_t * entry_t *
entry_new(desc) entry_new(desc)
const WCHAR *desc; const wchar_t *desc;
{ {
entry_t *en; entry_t *en;
if ((en = calloc(1, sizeof(*en))) == NULL) if ((en = calloc(1, sizeof(*en))) == NULL)
return NULL; return NULL;
if (auto_nonbillable && STRSTR(desc, auto_nonbillable)) if (auto_nonbillable && wcsstr(desc, auto_nonbillable))
en->en_flags.efl_nonbillable = 1; en->en_flags.efl_nonbillable = 1;
TTS_TAILQ_INSERT_HEAD(&entries, en, en_entries); TTS_TAILQ_INSERT_HEAD(&entries, en, en_entries);
en->en_desc = STRDUP(desc); en->en_desc = wcsdup(desc);
time(&en->en_created); time(&en->en_created);
return en; return en;

View file

@ -17,7 +17,7 @@
#include "wide.h" #include "wide.h"
typedef struct entry { typedef struct entry {
WCHAR *en_desc; wchar_t *en_desc;
int en_secs; int en_secs;
time_t en_started; time_t en_started;
time_t en_created; time_t en_created;
@ -37,7 +37,7 @@ extern entry_list entries;
extern entry_t *running; extern entry_t *running;
entry_t *entry_new (const WCHAR *); entry_t *entry_new (const wchar_t *);
void entry_start (entry_t *); void entry_start (entry_t *);
void entry_stop (entry_t *); void entry_stop (entry_t *);
void entry_free (entry_t *); void entry_free (entry_t *);

View file

@ -20,30 +20,30 @@
#include "str.h" #include "str.h"
function_t funcs[] = { function_t funcs[] = {
{ WIDE("help"), khelp, WIDE("display help screen") }, { L"help", khelp, L"display help screen" },
{ WIDE("add"), kadd, WIDE("add a new entry and start the timer") }, { L"add", kadd, L"add a new entry and start the timer" },
{ WIDE("add-old"), kaddold, WIDE("add a new entry and specify its duration") }, { L"add-old", kaddold, L"add a new entry and specify its duration" },
{ WIDE("delete"), kmarkdel, WIDE("delete the current entry") }, { L"delete", kmarkdel, L"delete the current entry" },
{ WIDE("undelete"), kundel, WIDE("undelete the current entry") }, { L"undelete", kundel, L"undelete the current entry" },
{ WIDE("quit"), kquit, WIDE("exit TTS") }, { L"quit", kquit, L"exit TTS" },
{ WIDE("invoice"), kinvoiced, WIDE("toggle current entry as invoiced") }, { L"invoice", kinvoiced, L"toggle current entry as invoiced" },
{ WIDE("billable"), kbillable, WIDE("toggle current entry as billable") }, { L"billable", kbillable, L"toggle current entry as billable" },
{ WIDE("mark"), kmark, WIDE("mark the current entry") }, { L"mark", kmark, L"mark the current entry" },
{ WIDE("unmarkall"), kunmarkall, WIDE("unmark all entries") }, { L"unmarkall", kunmarkall, L"unmark all entries" },
{ WIDE("startstop"), ktoggle, WIDE("start or stop the timer") }, { L"startstop", ktoggle, L"start or stop the timer" },
{ WIDE("edit-desc"), keddesc, WIDE("edit the current entry's description") }, { L"edit-desc", keddesc, L"edit the current entry's description" },
{ WIDE("edit-time"), kedtime, WIDE("edit the current entry's duration") }, { L"edit-time", kedtime, L"edit the current entry's duration" },
{ WIDE("showhide-inv"), ktoggleinv, WIDE("show or hide invoiced entries") }, { L"showhide-inv", ktoggleinv, L"show or hide invoiced entries" },
{ WIDE("copy"), kcopy, WIDE("copy the current entry's description to a new entry") }, { L"copy", kcopy, L"copy the current entry's description to a new entry" },
{ WIDE("add-time"), kaddtime, WIDE("add time to the current entry") }, { L"add-time", kaddtime, L"add time to the current entry" },
{ WIDE("sub-time"), kdeltime, WIDE("subtract time from the current entry") }, { L"sub-time", kdeltime, L"subtract time from the current entry" },
{ WIDE("search"), ksearch, WIDE("search for an entry by name") }, { L"search", ksearch, L"search for an entry by name" },
{ WIDE("sync"), ksync, WIDE("purge all deleted entries") }, { L"sync", ksync, L"purge all deleted entries" },
{ WIDE("prev"), kup, WIDE("move to the previous entry") }, { L"prev", kup, L"move to the previous entry" },
{ WIDE("next"), kdown, WIDE("move to the next entry") }, { L"next", kdown, L"move to the next entry" },
{ WIDE("execute"), kexec, WIDE("execute a configuration command") }, { L"execute", kexec, L"execute a configuration command" },
{ WIDE("merge"), kmerge, WIDE("merge marked entries into current entry") }, { L"merge", kmerge, L"merge marked entries into current entry" },
{ WIDE("interrupt"), kint, WIDE("split current entry into new entry")}, { L"interrupt", kint, L"split current entry into new entry"},
{ } { }
}; };
@ -59,8 +59,8 @@ int ndel = 0;
} }
if (ndel) { if (ndel) {
WCHAR s[128]; wchar_t s[128];
SNPRINTF(s, WSIZEOF(s), WIDE("Purge %d deleted entries?"), ndel); swprintf(s, wsizeof(s), L"Purge %d deleted entries?", ndel);
if (yesno(s)) { if (yesno(s)) {
ksync(); ksync();
} }
@ -72,9 +72,9 @@ int ndel = 0;
void void
kadd() kadd()
{ {
WCHAR *name; wchar_t *name;
entry_t *en; entry_t *en;
name = prompt(WIDE("Description:"), NULL, NULL); name = prompt(L"Description:", NULL, NULL);
if (!name || !*name) { if (!name || !*name) {
free(name); free(name);
return; return;
@ -88,9 +88,9 @@ entry_t *en;
void void
kaddold() kaddold()
{ {
WCHAR *name; wchar_t *name;
entry_t *en; entry_t *en;
name = prompt(WIDE("Description:"), NULL, NULL); name = prompt(L"Description:", NULL, NULL);
if (!name || !*name) { if (!name || !*name) {
free(name); free(name);
@ -151,7 +151,7 @@ int nmarked = 0;
return; return;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entries to delete.")); drawstatus(L"No entries to delete.");
return; return;
} }
@ -193,7 +193,7 @@ entry_t *prev = curent;
} while (!showinv && prev->en_flags.efl_invoiced); } while (!showinv && prev->en_flags.efl_invoiced);
if (prev == NULL) { if (prev == NULL) {
drawstatus(WIDE("Already at first entry.")); drawstatus(L"Already at first entry.");
return; return;
} }
@ -215,7 +215,7 @@ entry_t *next = curent;
} while (!showinv && next->en_flags.efl_invoiced); } while (!showinv && next->en_flags.efl_invoiced);
if (next == NULL) { if (next == NULL) {
drawstatus(WIDE("Already at last entry.")); drawstatus(L"Already at last entry.");
return; return;
} }
@ -244,7 +244,7 @@ int anymarked = 0;
} }
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
@ -300,7 +300,7 @@ int anymarked = 0;
} }
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
@ -314,14 +314,14 @@ int anymarked = 0;
void void
keddesc() keddesc()
{ {
WCHAR *new; wchar_t *new;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
if ((new = prompt(WIDE("Description:"), curent->en_desc, NULL)) == NULL) if ((new = prompt(L"Description:", curent->en_desc, NULL)) == NULL)
return; return;
free(curent->en_desc); free(curent->en_desc);
@ -332,12 +332,12 @@ WCHAR *new;
void void
kedtime() kedtime()
{ {
WCHAR *new, old[64]; wchar_t *new, old[64];
time_t n; time_t n;
int h, m, s; int h, m, s;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
@ -350,13 +350,13 @@ int h, m, s;
n %= 60; n %= 60;
s = n; s = n;
SNPRINTF(old, WSIZEOF(old), WIDE("%02d:%02d:%02d"), h, m, s); swprintf(old, wsizeof(old), L"%02d:%02d:%02d", h, m, s);
if ((new = prompt(WIDE("Duration [HH:MM:SS]:"), old, NULL)) == NULL) if ((new = prompt(L"Duration [HH:MM:SS]:", old, NULL)) == NULL)
return; return;
if (!SSCANF(new, WIDE("%d:%d:%d"), &h, &m, &s)) { if (!swscanf(new, L"%d:%d:%d", &h, &m, &s)) {
free(new); free(new);
drawstatus(WIDE("Invalid duration.")); drawstatus(L"Invalid duration.");
} }
curent->en_secs = (h * 60 * 60) + (m * 60) + s; curent->en_secs = (h * 60 * 60) + (m * 60) + s;
@ -371,8 +371,7 @@ ktoggleinv()
{ {
entry_t *en = curent; entry_t *en = curent;
showinv = !showinv; showinv = !showinv;
drawstatus(WIDE("%"FMT_L"s invoiced entries."), drawstatus(L"%ls invoiced entries.", showinv ? L"Showing" : L"Hiding");
showinv ? L"Showing" : L"Hiding");
if (curent && !curent->en_flags.efl_invoiced) if (curent && !curent->en_flags.efl_invoiced)
return; return;
@ -409,7 +408,7 @@ kcopy()
entry_t *en; entry_t *en;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
@ -422,29 +421,29 @@ entry_t *en;
void void
kaddtime() kaddtime()
{ {
WCHAR *tstr; wchar_t *tstr;
int h = 0, m = 0, s = 0, secs; int h = 0, m = 0, s = 0, secs;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
if ((tstr = prompt(WIDE("Time to add ([[HH:]MM:]SS):"), NULL, NULL)) == NULL) if ((tstr = prompt(L"Time to add ([[HH:]MM:]SS):", NULL, NULL)) == NULL)
return; return;
if (!*tstr) { if (!*tstr) {
drawstatus(WIDE("")); drawstatus(L"");
free(tstr); free(tstr);
return; return;
} }
if (SSCANF(tstr, WIDE("%d:%d:%d"), &h, &m, &s) != 3) { if (swscanf(tstr, L"%d:%d:%d", &h, &m, &s) != 3) {
h = 0; h = 0;
if (SSCANF(tstr, WIDE("%d:%d"), &m, &s) != 2) { if (swscanf(tstr, L"%d:%d", &m, &s) != 2) {
m = 0; m = 0;
if (SSCANF(tstr, WIDE("%d"), &s) != 1) { if (swscanf(tstr, L"%d", &s) != 1) {
free(tstr); free(tstr);
drawstatus(WIDE("Invalid time format.")); drawstatus(L"Invalid time format.");
return; return;
} }
} }
@ -453,12 +452,12 @@ int h = 0, m = 0, s = 0, secs;
free(tstr); free(tstr);
if (m >= 60) { if (m >= 60) {
drawstatus(WIDE("Minutes cannot be more than 59.")); drawstatus(L"Minutes cannot be more than 59.");
return; return;
} }
if (s >= 60) { if (s >= 60) {
drawstatus(WIDE("Seconds cannot be more than 59.")); drawstatus(L"Seconds cannot be more than 59.");
return; return;
} }
@ -470,29 +469,29 @@ int h = 0, m = 0, s = 0, secs;
void void
kdeltime() kdeltime()
{ {
WCHAR *tstr; wchar_t *tstr;
int h = 0, m = 0, s = 0, secs; int h = 0, m = 0, s = 0, secs;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
if ((tstr = prompt(WIDE("Time to subtract, ([[HH:]MM:]SS):"), NULL, NULL)) == NULL) if ((tstr = prompt(L"Time to subtract, ([[HH:]MM:]SS):", NULL, NULL)) == NULL)
return; return;
if (!*tstr) { if (!*tstr) {
drawstatus(WIDE("")); drawstatus(L"");
free(tstr); free(tstr);
return; return;
} }
if (SSCANF(tstr, WIDE("%d:%d:%d"), &h, &m, &s) != 3) { if (swscanf(tstr, L"%d:%d:%d", &h, &m, &s) != 3) {
h = 0; h = 0;
if (SSCANF(tstr, WIDE("%d:%d"), &m, &s) != 2) { if (swscanf(tstr, L"%d:%d", &m, &s) != 2) {
m = 0; m = 0;
if (SSCANF(tstr, WIDE("%d"), &s) != 1) { if (swscanf(tstr, L"%d", &s) != 1) {
free(tstr); free(tstr);
drawstatus(WIDE("Invalid time format.")); drawstatus(L"Invalid time format.");
return; return;
} }
} }
@ -500,12 +499,12 @@ int h = 0, m = 0, s = 0, secs;
free(tstr); free(tstr);
if (m >= 60) { if (m >= 60) {
drawstatus(WIDE("Minutes cannot be more than 59.")); drawstatus(L"Minutes cannot be more than 59.");
return; return;
} }
if (s >= 60) { if (s >= 60) {
drawstatus(WIDE("Seconds cannot be more than 59.")); drawstatus(L"Seconds cannot be more than 59.");
return; return;
} }
@ -513,7 +512,7 @@ int h = 0, m = 0, s = 0, secs;
secs = s + m*60 + h*60*60; secs = s + m*60 + h*60*60;
if (curent->en_secs - secs < 0) { if (curent->en_secs - secs < 0) {
drawstatus(WIDE("Remaining time cannot be less than zero.")); drawstatus(L"Remaining time cannot be less than zero.");
return; return;
} }
@ -526,11 +525,11 @@ kmerge()
{ {
entry_t *en, *ten; entry_t *en, *ten;
int nmarked = 0; int nmarked = 0;
WCHAR pr[128]; wchar_t pr[128];
int h, m, s = 0; int h, m, s = 0;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
@ -547,7 +546,7 @@ int h, m, s = 0;
} }
if (nmarked == 0) { if (nmarked == 0) {
drawstatus(WIDE("No marked entries.")); drawstatus(L"No marked entries.");
return; return;
} }
@ -556,7 +555,7 @@ int h, m, s = 0;
m = s / 60; m = s / 60;
s %= 60; s %= 60;
SNPRINTF(pr, WSIZEOF(pr), WIDE("Merge %d marked entries [%02d:%02d:%02d] into current entry?"), swprintf(pr, wsizeof(pr), L"Merge %d marked entries [%02d:%02d:%02d] into current entry?",
nmarked, h, m, s); nmarked, h, m, s);
if (!yesno(pr)) if (!yesno(pr))
return; return;
@ -578,35 +577,35 @@ khelp()
{ {
WINDOW *hwin; WINDOW *hwin;
size_t nhelp = 0; size_t nhelp = 0;
WCHAR **help; wchar_t **help;
#define HTITLE WIDE(" TTS keys ") #define HTITLE L" TTS keys "
size_t width = 0; size_t width = 0;
size_t i; size_t i;
INT c; wint_t c;
binding_t *bi; binding_t *bi;
/* Count the number of bindings */ /* Count the number of bindings */
TTS_TAILQ_FOREACH(bi, &bindings, bi_entries) TTS_TAILQ_FOREACH(bi, &bindings, bi_entries)
nhelp++; nhelp++;
help = calloc(nhelp, sizeof(const WCHAR *)); help = calloc(nhelp, sizeof(const wchar_t *));
i = 0; i = 0;
TTS_TAILQ_FOREACH(bi, &bindings, bi_entries) { TTS_TAILQ_FOREACH(bi, &bindings, bi_entries) {
WCHAR s[128], t[16]; wchar_t s[128], t[16];
if (bi->bi_key) if (bi->bi_key)
SNPRINTF(t, WSIZEOF(t), WIDE("%"FMT_L"s"), bi->bi_key->ky_name); swprintf(t, wsizeof(t), L"%ls", bi->bi_key->ky_name);
else else
SNPRINTF(t, WSIZEOF(t), WIDE("%"FMT_L"c"), bi->bi_code); swprintf(t, wsizeof(t), L"%lc", bi->bi_code);
if (bi->bi_macro) if (bi->bi_macro)
SNPRINTF(s, WSIZEOF(s), WIDE("%-10"FMT_L"s execute macro: %"FMT_L"s"), swprintf(s, wsizeof(s), L"%-10ls execute macro: %ls",
t, bi->bi_macro); t, bi->bi_macro);
else else
SNPRINTF(s, WSIZEOF(s), WIDE("%-10"FMT_L"s %"FMT_L"s (%"FMT_L"s)"), swprintf(s, wsizeof(s), L"%-10ls %ls (%ls)",
t, bi->bi_func->fn_desc, bi->bi_func->fn_name); t, bi->bi_func->fn_desc, bi->bi_func->fn_name);
help[i] = STRDUP(s); help[i] = wcsdup(s);
i++; i++;
} }
@ -614,8 +613,8 @@ binding_t *bi;
nhelp = LINES - 6; nhelp = LINES - 6;
for (i = 0; i < nhelp; i++) for (i = 0; i < nhelp; i++)
if (STRLEN(help[i]) > width) if (wcslen(help[i]) > width)
width = STRLEN(help[i]); width = wcslen(help[i]);
hwin = newwin(nhelp + 4, width + 4, hwin = newwin(nhelp + 4, width + 4,
(LINES / 2) - ((nhelp + 2) / 2), (LINES / 2) - ((nhelp + 2) / 2),
@ -623,18 +622,18 @@ binding_t *bi;
wborder(hwin, 0, 0, 0, 0, 0, 0, 0, 0); wborder(hwin, 0, 0, 0, 0, 0, 0, 0, 0);
wattron(hwin, A_REVERSE | A_BOLD); wattron(hwin, A_REVERSE | A_BOLD);
wmove(hwin, 0, (width / 2) - (WSIZEOF(HTITLE) - 1)/2); wmove(hwin, 0, (width / 2) - (wsizeof(HTITLE) - 1)/2);
WADDSTR(hwin, HTITLE); waddwstr(hwin, HTITLE);
wattroff(hwin, A_REVERSE | A_BOLD); wattroff(hwin, A_REVERSE | A_BOLD);
for (i = 0; i < nhelp; i++) { for (i = 0; i < nhelp; i++) {
wmove(hwin, i + 2, 2); wmove(hwin, i + 2, 2);
WADDSTR(hwin, help[i]); waddwstr(hwin, help[i]);
} }
wrefresh(hwin); wrefresh(hwin);
while (WGETCH(hwin, &c) == ERR while (wget_wch(hwin, &c) == ERR
#ifdef KEY_RESIZE #ifdef KEY_RESIZE
|| (c == KEY_RESIZE) || (c == KEY_RESIZE)
#endif #endif
@ -652,7 +651,7 @@ void
kmark() kmark()
{ {
if (!curent) { if (!curent) {
drawstatus(WIDE("No entry selected.")); drawstatus(L"No entry selected.");
return; return;
} }
@ -675,11 +674,11 @@ kint()
{ {
time_t duration; time_t duration;
entry_t *en; entry_t *en;
WCHAR *name; wchar_t *name;
if (!itime) { if (!itime) {
if (!running) { if (!running) {
drawstatus(WIDE("No running entry.")); drawstatus(L"No running entry.");
return; return;
} }
@ -688,11 +687,11 @@ WCHAR *name;
} }
if (!running) { if (!running) {
drawstatus(WIDE("No running entry.")); drawstatus(L"No running entry.");
return; return;
} }
name = prompt(WIDE("Description:"), NULL, NULL); name = prompt(L"Description:", NULL, NULL);
if (!name || !*name) { if (!name || !*name) {
itime = 0; itime = 0;
@ -704,7 +703,7 @@ WCHAR *name;
duration = time(NULL) - itime; duration = time(NULL) - itime;
} else { } else {
int h, m, s; int h, m, s;
if (prduration(WIDE("Duration [HH:MM:SS]:"), &h, &m, &s) == -1) if (prduration(L"Duration [HH:MM:SS]:", &h, &m, &s) == -1)
return; return;
duration = (h * 60 * 60) + (m * 60) + s; duration = (h * 60 * 60) + (m * 60) + s;
@ -726,16 +725,16 @@ WCHAR *name;
void void
ksearch() ksearch()
{ {
static WCHAR *lastsearch; static wchar_t *lastsearch;
WCHAR *term; wchar_t *term;
entry_t *start, *cur; entry_t *start, *cur;
if (!curent) { if (!curent) {
drawstatus(WIDE("No entries.")); drawstatus(L"No entries.");
return; return;
} }
if ((term = prompt(WIDE("Search:"), NULL, NULL)) == NULL) if ((term = prompt(L"Search:", NULL, NULL)) == NULL)
return; return;
if (!*term) { if (!*term) {
@ -754,16 +753,16 @@ entry_t *start, *cur;
for (;;) { for (;;) {
cur = TTS_TAILQ_NEXT(cur, en_entries); cur = TTS_TAILQ_NEXT(cur, en_entries);
if (cur == NULL) { if (cur == NULL) {
drawstatus(WIDE("Search reached last entry, continuing from top.")); drawstatus(L"Search reached last entry, continuing from top.");
cur = TTS_TAILQ_FIRST(&entries); cur = TTS_TAILQ_FIRST(&entries);
} }
if (cur == start) { if (cur == start) {
drawstatus(WIDE("No matches.")); drawstatus(L"No matches.");
break; break;
} }
if (STRSTR(cur->en_desc, term)) { if (wcsstr(cur->en_desc, term)) {
curent = cur; curent = cur;
if (!showinv && cur->en_flags.efl_invoiced) if (!showinv && cur->en_flags.efl_invoiced)
showinv = 1; showinv = 1;
@ -776,12 +775,12 @@ entry_t *start, *cur;
void void
kexec() kexec()
{ {
WCHAR *cmd; wchar_t *cmd;
WCHAR **args; wchar_t **args;
command_t *cmds; command_t *cmds;
size_t nargs; size_t nargs;
if ((cmd = prompt(WIDE(":"), NULL, NULL)) == NULL || !*cmd) { if ((cmd = prompt(L":", NULL, NULL)) == NULL || !*cmd) {
free(cmd); free(cmd);
return; return;
} }
@ -795,7 +794,7 @@ size_t nargs;
} }
if ((cmds = find_command(args[0])) == NULL) { if ((cmds = find_command(args[0])) == NULL) {
drawstatus(WIDE("Unknown command.")); drawstatus(L"Unknown command.");
tokfree(&args); tokfree(&args);
return; return;
} }
@ -810,11 +809,11 @@ size_t nargs;
*/ */
function_t * function_t *
find_func(name) find_func(name)
const WCHAR *name; const wchar_t *name;
{ {
function_t *f; function_t *f;
for (f = funcs; f->fn_name; f++) for (f = funcs; f->fn_name; f++)
if (STRCMP(name, f->fn_name) == 0) if (wcscmp(name, f->fn_name) == 0)
return f; return f;
return NULL; return NULL;
} }

View file

@ -39,13 +39,13 @@ void kmerge(void);
void kint(void); void kint(void);
typedef struct function { typedef struct function {
const WCHAR *fn_name; const wchar_t *fn_name;
void (*fn_hdl) (void); void (*fn_hdl) (void);
const WCHAR *fn_desc; const wchar_t *fn_desc;
} function_t; } function_t;
extern function_t funcs[]; extern function_t funcs[];
function_t *find_func(const WCHAR *name); function_t *find_func(const wchar_t *name);
#endif /* !TTS_FUNCTIONS_H */ #endif /* !TTS_FUNCTIONS_H */

28
str.c
View file

@ -12,12 +12,12 @@
size_t size_t
tokenise(str, res) tokenise(str, res)
const WCHAR *str; const wchar_t *str;
WCHAR ***res; wchar_t ***res;
{ {
int ntoks = 0; int ntoks = 0;
const WCHAR *p, *q; const wchar_t *p, *q;
WCHAR *r; wchar_t *r;
*res = NULL; *res = NULL;
p = str; p = str;
@ -28,7 +28,7 @@ WCHAR *r;
int isbsl = 0; int isbsl = 0;
/* Skip leading whitespace */ /* Skip leading whitespace */
while (ISSPACE(*p)) while (iswspace(*p))
p++; p++;
/* End of string - no more arguments */ /* End of string - no more arguments */
@ -64,21 +64,21 @@ WCHAR *r;
qskip = 1; qskip = 1;
} else { } else {
/* Not quoted - just find the next whitespace */ /* Not quoted - just find the next whitespace */
while (!ISSPACE(*q) && *q) while (!iswspace(*q) && *q)
q++; q++;
} }
/* Copy the argument (which is sz bytes long) into the result array */ /* Copy the argument (which is sz bytes long) into the result array */
sz = (q - p); sz = (q - p);
*res = realloc(*res, sizeof(WCHAR *) * (ntoks + 1)); *res = realloc(*res, sizeof(wchar_t *) * (ntoks + 1));
(*res)[ntoks] = malloc(sizeof(WCHAR) * (sz + 1)); (*res)[ntoks] = malloc(sizeof(wchar_t) * (sz + 1));
MEMCPY((*res)[ntoks], p, sz); wmemcpy((*res)[ntoks], p, sz);
/* Handle \ escapes */ /* Handle \ escapes */
for (r = (*res)[ntoks]; r < ((*res)[ntoks] + sz);) { for (r = (*res)[ntoks]; r < ((*res)[ntoks] + sz);) {
if (!isbsl) { if (!isbsl) {
if (*r == '\\') { if (*r == '\\') {
MEMMOVE(r, r + 1, sz - (r - (*res)[ntoks])); wmemmove(r, r + 1, sz - (r - (*res)[ntoks]));
sz--; sz--;
isbsl = 1; isbsl = 1;
continue; continue;
@ -106,7 +106,7 @@ WCHAR *r;
if (qskip) if (qskip)
q += qskip; q += qskip;
while (ISSPACE(*q)) while (iswspace(*q))
q++; q++;
/* /*
@ -118,16 +118,16 @@ WCHAR *r;
p = q; p = q;
} }
*res = realloc(*res, sizeof(WCHAR *) * (ntoks + 1)); *res = realloc(*res, sizeof(wchar_t *) * (ntoks + 1));
(*res)[ntoks] = NULL; (*res)[ntoks] = NULL;
return ntoks; return ntoks;
} }
void void
tokfree(vec) tokfree(vec)
WCHAR ***vec; wchar_t ***vec;
{ {
WCHAR **p; wchar_t **p;
for (p = (*vec); *p; p++) for (p = (*vec); *p; p++)
free(*p); free(*p);
free(*vec); free(*vec);

4
str.h
View file

@ -15,7 +15,7 @@
#include "wide.h" #include "wide.h"
size_t tokenise(const WCHAR *, WCHAR ***result); size_t tokenise(const wchar_t *, wchar_t ***result);
void tokfree(WCHAR ***); void tokfree(wchar_t ***);
#endif /* !TTS_STR_H */ #endif /* !TTS_STR_H */

62
style.c
View file

@ -22,34 +22,34 @@ style_t sy_header = { 1, 0 },
sy_date = { 6, 0 }; sy_date = { 6, 0 };
static attrname_t attrnames[] = { static attrname_t attrnames[] = {
{ WIDE("normal"), WA_NORMAL }, { L"normal", WA_NORMAL },
{ WIDE("bold"), WA_BOLD }, { L"bold", WA_BOLD },
{ WIDE("reverse"), WA_REVERSE }, { L"reverse", WA_REVERSE },
{ WIDE("blink"), WA_BLINK }, { L"blink", WA_BLINK },
{ WIDE("dim"), WA_DIM }, { L"dim", WA_DIM },
{ WIDE("underline"), WA_UNDERLINE }, { L"underline", WA_UNDERLINE },
{ WIDE("standout"), WA_STANDOUT } { L"standout", WA_STANDOUT }
}; };
static colour_t colours[] = { static colour_t colours[] = {
{ WIDE("black"), COLOR_BLACK }, { L"black", COLOR_BLACK },
{ WIDE("red"), COLOR_RED }, { L"red", COLOR_RED },
{ WIDE("green"), COLOR_GREEN }, { L"green", COLOR_GREEN },
{ WIDE("yellow"), COLOR_YELLOW }, { L"yellow", COLOR_YELLOW },
{ WIDE("blue"), COLOR_BLUE }, { L"blue", COLOR_BLUE },
{ WIDE("magenta"), COLOR_MAGENTA }, { L"magenta", COLOR_MAGENTA },
{ WIDE("cyan"), COLOR_CYAN }, { L"cyan", COLOR_CYAN },
{ WIDE("white"), COLOR_WHITE } { L"white", COLOR_WHITE }
}; };
int int
attr_find(name, result) attr_find(name, result)
const WCHAR *name; const wchar_t *name;
attr_t *result; attr_t *result;
{ {
size_t i; size_t i;
for (i = 0; i < sizeof(attrnames) / sizeof(*attrnames); i++) { for (i = 0; i < sizeof(attrnames) / sizeof(*attrnames); i++) {
if (STRCMP(attrnames[i].an_name, name) == 0) { if (wcscmp(attrnames[i].an_name, name) == 0) {
*result = attrnames[i].an_value; *result = attrnames[i].an_value;
return 0; return 0;
} }
@ -60,12 +60,12 @@ size_t i;
int int
colour_find(name, result) colour_find(name, result)
const WCHAR *name; const wchar_t *name;
short *result; short *result;
{ {
size_t i; size_t i;
for (i = 0; i < sizeof(colours) / sizeof(*colours); i++) { for (i = 0; i < sizeof(colours) / sizeof(*colours); i++) {
if (STRCMP(colours[i].co_name, name) == 0) { if (wcscmp(colours[i].co_name, name) == 0) {
*result = colours[i].co_value; *result = colours[i].co_value;
return 0; return 0;
} }
@ -85,7 +85,7 @@ style_clear(sy)
int int
style_set(sy, fg, bg) style_set(sy, fg, bg)
style_t *sy; style_t *sy;
const WCHAR *fg, *bg; const wchar_t *fg, *bg;
{ {
sy->sy_attrs = WA_NORMAL; sy->sy_attrs = WA_NORMAL;
init_pair(sy->sy_pair, default_fg, default_bg); init_pair(sy->sy_pair, default_fg, default_bg);
@ -95,7 +95,7 @@ style_set(sy, fg, bg)
int int
style_add(sy, fg, bg) style_add(sy, fg, bg)
style_t *sy; style_t *sy;
const WCHAR *fg, *bg; const wchar_t *fg, *bg;
{ {
attr_t at; attr_t at;
short colfg, colbg = default_bg; short colfg, colbg = default_bg;
@ -119,10 +119,28 @@ apply_styles()
{ {
wbkgd(statwin, style_bg(sy_status)); wbkgd(statwin, style_bg(sy_status));
wattr_on(statwin, style_fg(sy_status), NULL); wattr_on(statwin, style_fg(sy_status), NULL);
drawstatus(WIDE("")); drawstatus(L"");
wbkgd(titwin, style_bg(sy_header)); wbkgd(titwin, style_bg(sy_header));
wattr_on(titwin, style_fg(sy_header), NULL); wattr_on(titwin, style_fg(sy_header), NULL);
drawheader(); drawheader();
} }
void
style_defaults(void)
{
init_pair(1, default_fg, default_bg);
init_pair(2, default_fg, default_bg);
init_pair(3, default_fg, default_bg);
init_pair(4, default_fg, default_bg);
init_pair(5, default_fg, default_bg);
init_pair(6, default_fg, default_bg);
style_set(&sy_header, L"reverse", NULL);
style_set(&sy_status, L"normal", NULL);
style_set(&sy_entry, L"normal", NULL);
style_set(&sy_selected, L"normal", NULL);
style_set(&sy_running, L"bold", NULL);
style_set(&sy_date, L"underline", NULL);
apply_styles();
}

15
style.h
View file

@ -20,15 +20,15 @@ typedef struct style {
} style_t; } style_t;
#define style_fg(s) (COLOR_PAIR((s).sy_pair) | (s).sy_attrs) #define style_fg(s) (COLOR_PAIR((s).sy_pair) | (s).sy_attrs)
#define style_bg(s) ((INT) ' ' | COLOR_PAIR((s).sy_pair) | ((s).sy_attrs & ~WA_UNDERLINE)) #define style_bg(s) ((wint_t) ' ' | COLOR_PAIR((s).sy_pair) | ((s).sy_attrs & ~WA_UNDERLINE))
typedef struct attrname { typedef struct attrname {
const WCHAR *an_name; const wchar_t *an_name;
attr_t an_value; attr_t an_value;
} attrname_t; } attrname_t;
typedef struct colour { typedef struct colour {
const WCHAR *co_name; const wchar_t *co_name;
short co_value; short co_value;
} colour_t; } colour_t;
@ -41,13 +41,14 @@ extern style_t sy_header,
extern short default_fg, default_bg; extern short default_fg, default_bg;
int attr_find(const WCHAR *name, attr_t *result); int attr_find (const wchar_t *name, attr_t *result);
int colour_find(const WCHAR *name, short *result); int colour_find (const wchar_t *name, short *result);
void style_clear (style_t *); void style_clear (style_t *);
int style_set(style_t *, const WCHAR *fg, const WCHAR *bg); int style_set (style_t *, const wchar_t *fg, const wchar_t *bg);
int style_add(style_t *, const WCHAR *fg, const WCHAR *bg); int style_add (style_t *, const wchar_t *fg, const wchar_t *bg);
void style_defaults (void);
void apply_styles (void); void apply_styles (void);
#endif /* !TTS_STYLE_H */ #endif /* !TTS_STYLE_H */

193
tts.c
View file

@ -82,7 +82,7 @@ entry_t *curent;
int showinv = 0; int showinv = 0;
static WCHAR *macro_text, *macro_pos; static wchar_t *macro_text, *macro_pos;
time_t itime = 0; time_t itime = 0;
@ -91,15 +91,15 @@ int delete_advance = 1;
int mark_advance = 1; int mark_advance = 1;
int bill_advance = 0; int bill_advance = 0;
int bill_increment = 0; int bill_increment = 0;
WCHAR *auto_nonbillable; wchar_t *auto_nonbillable;
variable_t variables[] = { variable_t variables[] = {
{ WIDE("delete_advance"), VTYPE_BOOL, &delete_advance }, { L"delete_advance", VTYPE_BOOL, &delete_advance },
{ WIDE("mark_advance"), VTYPE_BOOL, &mark_advance }, { L"mark_advance", VTYPE_BOOL, &mark_advance },
{ WIDE("billable_advance"), VTYPE_BOOL, &bill_advance }, { L"billable_advance", VTYPE_BOOL, &bill_advance },
{ WIDE("show_billable"), VTYPE_BOOL, &show_billable }, { L"show_billable", VTYPE_BOOL, &show_billable },
{ WIDE("auto_non_billable"), VTYPE_STRING, &auto_nonbillable }, { L"auto_non_billable", VTYPE_STRING, &auto_nonbillable },
{ WIDE("bill_increment"), VTYPE_INT, &bill_increment }, { L"bill_increment", VTYPE_INT, &bill_increment },
{ } { }
}; };
@ -242,88 +242,15 @@ struct kevent evs[2], rev;
snprintf(statfile, sizeof(statfile), "%s/%s", pw->pw_dir, STATFILE); snprintf(statfile, sizeof(statfile), "%s/%s", pw->pw_dir, STATFILE);
snprintf(rcfile, sizeof(rcfile), "%s/%s", pw->pw_dir, RCFILE); snprintf(rcfile, sizeof(rcfile), "%s/%s", pw->pw_dir, RCFILE);
initscr(); ui_init();
in_curses = 1; style_defaults();
start_color();
#ifdef HAVE_USE_DEFAULT_COLORS
use_default_colors();
#endif
cbreak();
noecho();
nonl();
nodelay(stdscr, TRUE);
pair_content(0, &default_fg, &default_bg);
refresh();
intrflush(stdscr, TRUE);
keypad(stdscr, TRUE);
leaveok(stdscr, TRUE);
titwin = newwin(1, 0, 0, 0);
intrflush(titwin, FALSE);
keypad(titwin, TRUE);
leaveok(titwin, TRUE);
statwin = newwin(1, 0, LINES - 1, 0);
intrflush(statwin, FALSE);
keypad(statwin, TRUE);
leaveok(statwin, TRUE);
listwin = newwin(LINES - 2, 0, 1, 0);
intrflush(listwin, FALSE);
keypad(listwin, TRUE);
leaveok(listwin, TRUE);
init_pair(1, default_fg, default_bg);
init_pair(2, default_fg, default_bg);
init_pair(3, default_fg, default_bg);
init_pair(4, default_fg, default_bg);
init_pair(5, default_fg, default_bg);
init_pair(6, default_fg, default_bg);
style_set(&sy_header, WIDE("reverse"), NULL);
style_set(&sy_status, WIDE("normal"), NULL);
style_set(&sy_entry, WIDE("normal"), NULL);
style_set(&sy_selected, WIDE("normal"), NULL);
style_set(&sy_running, WIDE("bold"), NULL);
style_set(&sy_date, WIDE("underline"), NULL);
apply_styles();
if (load_file(rcfile) == -1) { if (load_file(rcfile) == -1) {
endwin(); endwin();
return 1; return 1;
} }
curs_set(0); bind_defaults();
bind_key(WIDE("?"), WIDE("help"), 0);
bind_key(WIDE("a"), WIDE("add"), 0);
bind_key(WIDE("A"), WIDE("add-old"), 0);
bind_key(WIDE("d"), WIDE("delete"), 0);
bind_key(WIDE("u"), WIDE("undelete"), 0);
bind_key(WIDE("q"), WIDE("quit"), 0);
bind_key(WIDE("<CTRL-C>"), WIDE("quit"), 0);
bind_key(WIDE("i"), WIDE("invoice"), 0);
bind_key(WIDE("b"), WIDE("billable"), 0);
bind_key(WIDE("m"), WIDE("mark"), 0);
bind_key(WIDE("U"), WIDE("unmarkall"), 0);
bind_key(WIDE("<SPACE>"), WIDE("startstop"), 0);
bind_key(WIDE("e"), WIDE("edit-desc"), 0);
bind_key(WIDE("\\"), WIDE("edit-time"), 0);
bind_key(WIDE("<TAB>"), WIDE("showhide-inv"), 0);
bind_key(WIDE("c"), WIDE("copy"), 0);
bind_key(WIDE("+"), WIDE("add-time"), 0);
bind_key(WIDE("-"), WIDE("sub-time"), 0);
bind_key(WIDE("/"), WIDE("search"), 0);
bind_key(WIDE("$"), WIDE("sync"), 0);
bind_key(WIDE("<UP>"), WIDE("prev"), 0);
bind_key(WIDE("<DOWN>"), WIDE("next"), 0);
bind_key(WIDE(":"), WIDE("execute"), 0);
bind_key(WIDE("M"), WIDE("merge"), 0);
bind_key(WIDE("r"), WIDE("interrupt"), 0);
bind_key(WIDE("R"), WIDE("interrupt"), 0);
/* /*
* Make sure we can save (even if it's an empty file or nothing has * Make sure we can save (even if it's an empty file or nothing has
@ -333,7 +260,7 @@ struct kevent evs[2], rev;
save(); save();
drawheader(); drawheader();
drawstatus(WIDE("")); drawstatus(L"");
if (!TTS_TAILQ_EMPTY(&entries)) { if (!TTS_TAILQ_EMPTY(&entries)) {
curent = TTS_TAILQ_FIRST(&entries); curent = TTS_TAILQ_FIRST(&entries);
@ -343,7 +270,7 @@ struct kevent evs[2], rev;
} }
for (;;) { for (;;) {
INT c; wint_t c;
binding_t *bi; binding_t *bi;
#ifdef USE_DARWIN_POWER #ifdef USE_DARWIN_POWER
struct timespec timeout; struct timespec timeout;
@ -399,7 +326,7 @@ struct kevent evs[2], rev;
continue; continue;
#endif #endif
drawstatus(WIDE("")); drawstatus(L"");
TTS_TAILQ_FOREACH(bi, &bindings, bi_entries) { TTS_TAILQ_FOREACH(bi, &bindings, bi_entries) {
if (bi->bi_code != c) if (bi->bi_code != c)
@ -413,7 +340,7 @@ struct kevent evs[2], rev;
goto next; goto next;
} }
drawstatus(WIDE("Unknown command.")); drawstatus(L"Unknown command.");
next: ; next: ;
} }
@ -421,7 +348,7 @@ struct kevent evs[2], rev;
break; break;
if (time(NULL) - laststatus >= 2) if (time(NULL) - laststatus >= 2)
drawstatus(WIDE("")); drawstatus(L"");
if (time(NULL) - lastsave > 60) if (time(NULL) - lastsave > 60)
save(); save();
@ -437,7 +364,7 @@ load()
{ {
FILE *f; FILE *f;
char input[4096]; char input[4096];
WCHAR line[4096]; wchar_t line[4096];
entry_t *en; entry_t *en;
TTS_TAILQ_FOREACH(en, &entries, en_entries) TTS_TAILQ_FOREACH(en, &entries, en_entries)
@ -447,40 +374,40 @@ entry_t *en;
if (errno == ENOENT) if (errno == ENOENT)
return 0; return 0;
errbox(WIDE("Can't read %s: %s"), statfile, strerror(errno)); errbox(L"Can't read %s: %s", statfile, strerror(errno));
exit(1); exit(1);
} }
if (fgets(input, sizeof(input), f) == NULL) { if (fgets(input, sizeof(input), f) == NULL) {
errbox(WIDE("Can't read %s: %s"), statfile, strerror(errno)); errbox(L"Can't read %s: %s", statfile, strerror(errno));
fclose(f); fclose(f);
exit(1); exit(1);
} }
MBSTOWCS(line, input, WSIZEOF(line)); mbstowcs(line, input, wsizeof(line));
if (STRCMP(line, WIDE("#%RT/TTS V1\n"))) { if (wcscmp(line, L"#%RT/TTS V1\n")) {
errbox(WIDE("Can't read %s: invalid magic signature"), statfile); errbox(L"Can't read %s: invalid magic signature", statfile);
fclose(f); fclose(f);
exit(1); exit(1);
} }
while (fgets(input, sizeof(input), f)) { while (fgets(input, sizeof(input), f)) {
unsigned long cre, secs; unsigned long cre, secs;
WCHAR flags[10], desc[4096], *p; wchar_t flags[10], desc[4096], *p;
entry_t *en; entry_t *en;
int i; int i;
MBSTOWCS(line, input, WSIZEOF(line)); mbstowcs(line, input, wsizeof(line));
if (SSCANF(line, WIDE("#%%showinv %d\n"), &i) == 1) { if (swscanf(line, L"#%%showinv %d\n", &i) == 1) {
showinv = i ? 1 : 0; showinv = i ? 1 : 0;
continue; continue;
} }
if (SSCANF(line, WIDE("%lu %lu %9"FMT_L"[in-] %4095"FMT_L"[^\n]\n"), if (swscanf(line, L"%lu %lu %9l[in-] %4095l[^\n]\n",
&cre, &secs, flags, desc) != 4) { &cre, &secs, flags, desc) != 4) {
errbox(WIDE("Can't read %s: invalid entry format"), statfile); errbox(L"Can't read %s: invalid entry format", statfile);
fclose(f); fclose(f);
exit(1); exit(1);
} }
@ -502,7 +429,7 @@ entry_t *en;
break; break;
default: default:
errbox(WIDE("Can't read %s: invalid flag"), statfile); errbox(L"Can't read %s: invalid flag", statfile);
fclose(f); fclose(f);
exit(1); exit(1);
} }
@ -510,7 +437,7 @@ entry_t *en;
} }
if (ferror(f)) { if (ferror(f)) {
errbox(WIDE("Can't read %s: %s"), statfile, strerror(errno)); errbox(L"Can't read %s: %s", statfile, strerror(errno));
fclose(f); fclose(f);
exit(1); exit(1);
} }
@ -530,31 +457,31 @@ entry_t *en;
snprintf(p, sizeof(p), "%s_", statfile); snprintf(p, sizeof(p), "%s_", statfile);
if ((fd = open(p, O_WRONLY | O_CREAT, 0600)) == -1) { if ((fd = open(p, O_WRONLY | O_CREAT, 0600)) == -1) {
errbox(WIDE("%s_: %s"), statfile, strerror(errno)); errbox(L"%s_: %s", statfile, strerror(errno));
endwin(); endwin();
exit(1); exit(1);
} }
if ((f = fdopen(fd, "w")) == NULL) { if ((f = fdopen(fd, "w")) == NULL) {
errbox(WIDE("%s: %s"), p, strerror(errno)); errbox(L"%s: %s", p, strerror(errno));
endwin(); endwin();
exit(1); exit(1);
} }
if (FPRINTF(f, WIDE("#%%RT/TTS V1\n")) == -1) { if (fwprintf(f, L"#%%RT/TTS V1\n") == -1) {
fclose(f); fclose(f);
unlink(p); unlink(p);
errbox(WIDE("%s: write error (header): %s"), p, strerror(errno)); errbox(L"%s: write error (header): %s", p, strerror(errno));
endwin(); endwin();
exit(1); exit(1);
} }
if (FPRINTF(f, WIDE("#%%showinv %d\n"), showinv) == -1) { if (fwprintf(f, L"#%%showinv %d\n", showinv) == -1) {
fclose(f); fclose(f);
unlink(p); unlink(p);
errbox(WIDE("%s: write error (showinv): %s"), p, strerror(errno)); errbox(L"%s: write error (showinv): %s", p, strerror(errno));
endwin(); endwin();
exit(1); exit(1);
} }
@ -563,7 +490,7 @@ entry_t *en;
char flags[10], *fp = flags, wdesc[4096] = {}; char flags[10], *fp = flags, wdesc[4096] = {};
time_t n; time_t n;
WCSTOMBS(wdesc, en->en_desc, sizeof(wdesc)); wcstombs(wdesc, en->en_desc, sizeof(wdesc));
memset(flags, 0, sizeof(flags)); memset(flags, 0, sizeof(flags));
if (en->en_flags.efl_invoiced) if (en->en_flags.efl_invoiced)
@ -575,11 +502,11 @@ entry_t *en;
if (en->en_started) if (en->en_started)
n += time(NULL) - en->en_started; n += time(NULL) - en->en_started;
if (FPRINTF(f, WIDE("%lu %lu %s %s\n"), if (fwprintf(f, L"%lu %lu %s %s\n",
(unsigned long) en->en_created, (unsigned long) en->en_created,
(unsigned long) n, (unsigned long) n,
*flags ? flags : "-", wdesc) == -1) { *flags ? flags : "-", wdesc) == -1) {
errbox(WIDE("%s: write error (entry): %s"), p, strerror(errno)); errbox(L"%s: write error (entry): %s", p, strerror(errno));
fclose(f); fclose(f);
unlink(p); unlink(p);
endwin(); endwin();
@ -589,14 +516,14 @@ entry_t *en;
if (fclose(f) == EOF) { if (fclose(f) == EOF) {
unlink(p); unlink(p);
errbox(WIDE("%s: write error (closing): %s"), p, strerror(errno)); errbox(L"%s: write error (closing): %s", p, strerror(errno));
endwin(); endwin();
exit(1); exit(1);
} }
if (rename(p, statfile) == -1) { if (rename(p, statfile) == -1) {
unlink(p); unlink(p);
errbox(WIDE("%s: rename: %s"), statfile, strerror(errno)); errbox(L"%s: rename: %s", statfile, strerror(errno));
endwin(); endwin();
exit(1); exit(1);
} }
@ -618,7 +545,7 @@ history_t *hi;
void void
hist_add(hi, text) hist_add(hi, text)
history_t *hi; history_t *hi;
const WCHAR *text; const wchar_t *text;
{ {
histent_t *hent; histent_t *hent;
@ -628,7 +555,7 @@ histent_t *hent;
if ((hent = calloc(1, sizeof(*hent))) == NULL) if ((hent = calloc(1, sizeof(*hent))) == NULL)
return; return;
if ((hent->he_text = STRDUP(text)) == NULL) { if ((hent->he_text = wcsdup(text)) == NULL) {
free(hent); free(hent);
return; return;
} }
@ -643,11 +570,11 @@ histent_t *hent;
variable_t * variable_t *
find_variable(name) find_variable(name)
WCHAR const *name; wchar_t const *name;
{ {
variable_t *v; variable_t *v;
for (v = variables; v->va_name; v++) for (v = variables; v->va_name; v++)
if (STRCMP(name, v->va_name) == 0) if (wcscmp(name, v->va_name) == 0)
return v; return v;
return NULL; return NULL;
} }
@ -656,7 +583,7 @@ static char *curfile;
static int lineno, nerr; static int lineno, nerr;
void void
cmderr(const WCHAR *msg, ...) cmderr(const wchar_t *msg, ...)
{ {
va_list ap; va_list ap;
@ -667,16 +594,16 @@ va_list ap;
void void
vcmderr(msg, ap) vcmderr(msg, ap)
const WCHAR *msg; const wchar_t *msg;
va_list ap; va_list ap;
{ {
nerr++; nerr++;
if (curfile) { if (curfile) {
WCHAR s[1024]; wchar_t s[1024];
char t[1024]; char t[1024];
VSNPRINTF(s, WSIZEOF(t), msg, ap); vswprintf(s, wsizeof(t), msg, ap);
WCSTOMBS(t, s, sizeof(t)); wcstombs(t, s, sizeof(t));
if (in_curses) { if (in_curses) {
endwin(); endwin();
@ -718,13 +645,13 @@ char input[1024];
while (fgets(input, sizeof(input), s)) { while (fgets(input, sizeof(input), s)) {
size_t nargs; size_t nargs;
WCHAR **args; wchar_t **args;
command_t *cmds; command_t *cmds;
WCHAR line[1024]; wchar_t line[1024];
++lineno; ++lineno;
MBSTOWCS(line, input, WSIZEOF(line)); mbstowcs(line, input, wsizeof(line));
if (line[0] == '#') if (line[0] == '#')
continue; continue;
@ -736,7 +663,7 @@ char input[1024];
} }
if ((cmds = find_command(args[0])) == NULL) { if ((cmds = find_command(args[0])) == NULL) {
cmderr(WIDE("Unknown command \"%"FMT_L"s\"."), args[0]); cmderr(L"Unknown command \"%ls\".", args[0]);
nerr++; nerr++;
tokfree(&args); tokfree(&args);
continue; continue;
@ -766,7 +693,7 @@ prompt_sleep(sleeptime)
* subtract the time spent sleeping, in case they forgot to turn off * subtract the time spent sleeping, in case they forgot to turn off
* the timer. * the timer.
*/ */
WCHAR pr[128]; wchar_t pr[128];
int h, m, s = 0; int h, m, s = 0;
/* Only prompt if an entry is running */ /* Only prompt if an entry is running */
@ -781,8 +708,8 @@ int h, m, s = 0;
m = s / 60; m = s / 60;
s %= 60; s %= 60;
SNPRINTF(pr, WSIZEOF(pr), swprintf(pr, wsizeof(pr),
WIDE("Remove %02d:%02d:%02d time asleep from running entry?"), L"Remove %02d:%02d:%02d time asleep from running entry?",
h, m, s); h, m, s);
if (!yesno(pr)) if (!yesno(pr))
@ -798,7 +725,7 @@ int h, m, s = 0;
void void
input_macro(s) input_macro(s)
WCHAR *s; wchar_t *s;
{ {
free(macro_text); free(macro_text);
macro_text = macro_pos = NULL; macro_text = macro_pos = NULL;
@ -806,12 +733,12 @@ input_macro(s)
if (!s) if (!s)
return; return;
macro_text = macro_pos = STRDUP(s); macro_text = macro_pos = wcsdup(s);
} }
int int
input_char(c) input_char(c)
WCHAR *c; wchar_t *c;
{ {
if (macro_pos) { if (macro_pos) {
if (*macro_pos) { if (*macro_pos) {
@ -822,5 +749,5 @@ input_char(c)
macro_text = macro_pos = NULL; macro_text = macro_pos = NULL;
} }
return GETCH(c); return get_wch(c);
} }

6
tts.h
View file

@ -29,7 +29,7 @@ extern int delete_advance;
extern int mark_advance; extern int mark_advance;
extern int bill_advance; extern int bill_advance;
extern int bill_increment; extern int bill_increment;
extern WCHAR *auto_nonbillable; extern wchar_t *auto_nonbillable;
/* /*
* Global state. * Global state.
@ -49,7 +49,7 @@ int save(void);
#define NHIST 50 #define NHIST 50
typedef struct histent { typedef struct histent {
WCHAR *he_text; wchar_t *he_text;
TTS_TAILQ_ENTRY(histent) he_entries; TTS_TAILQ_ENTRY(histent) he_entries;
} histent_t; } histent_t;
typedef TTS_TAILQ_HEAD(hentlist, histent) hentlist_t; typedef TTS_TAILQ_HEAD(hentlist, histent) hentlist_t;
@ -60,7 +60,7 @@ typedef struct history {
} history_t; } history_t;
history_t *hist_new(void); history_t *hist_new(void);
void hist_add(history_t *, WCHAR const *); void hist_add(history_t *, wchar_t const *);
extern history_t *searchhist; extern history_t *searchhist;
extern history_t *prompthist; extern history_t *prompthist;

210
ui.c
View file

@ -18,6 +18,46 @@
WINDOW *titwin, *statwin, *listwin; WINDOW *titwin, *statwin, *listwin;
int in_curses; int in_curses;
void
ui_init(void)
{
initscr();
in_curses = 1;
start_color();
#ifdef HAVE_USE_DEFAULT_COLORS
use_default_colors();
#endif
cbreak();
noecho();
nonl();
nodelay(stdscr, TRUE);
pair_content(0, &default_fg, &default_bg);
refresh();
intrflush(stdscr, TRUE);
keypad(stdscr, TRUE);
leaveok(stdscr, TRUE);
titwin = newwin(1, 0, 0, 0);
intrflush(titwin, FALSE);
keypad(titwin, TRUE);
leaveok(titwin, TRUE);
statwin = newwin(1, 0, LINES - 1, 0);
intrflush(statwin, FALSE);
keypad(statwin, TRUE);
leaveok(statwin, TRUE);
listwin = newwin(LINES - 2, 0, 1, 0);
intrflush(listwin, FALSE);
keypad(listwin, TRUE);
leaveok(listwin, TRUE);
curs_set(0);
}
/* /*
* Move the cursor to the next entry after an operation like mark or deleted. * Move the cursor to the next entry after an operation like mark or deleted.
* If there are no suitable entries after this one, move it backwards instead. * If there are no suitable entries after this one, move it backwards instead.
@ -70,24 +110,24 @@ entry_t *en;
void void
drawheader() drawheader()
{ {
WCHAR title[64]; wchar_t title[64];
SNPRINTF(title, WSIZEOF(title), WIDE("TTS %s - Type '?' for help"), swprintf(title, wsizeof(title), L"TTS %s - Type '?' for help",
tts_version); tts_version);
wmove(titwin, 0, 0); wmove(titwin, 0, 0);
WADDSTR(titwin, title); waddwstr(titwin, title);
if (itime > 0) { if (itime > 0) {
WCHAR str[128]; wchar_t str[128];
int h, m, s; int h, m, s;
time_t passed = time(NULL) - itime; time_t passed = time(NULL) - itime;
time_to_hms(passed, h, m, s); time_to_hms(passed, h, m, s);
SNPRINTF(str, WSIZEOF(str), WIDE(" *** MARK INTERRUPT: %02d:%02d:%02d ***"), swprintf(str, wsizeof(str), L" *** MARK INTERRUPT: %02d:%02d:%02d ***",
h, m, s); h, m, s);
wattron(titwin, A_BOLD); wattron(titwin, A_BOLD);
WADDSTR(titwin, str); waddwstr(titwin, str);
wattroff(titwin, A_BOLD); wattroff(titwin, A_BOLD);
} }
wclrtoeol(titwin); wclrtoeol(titwin);
@ -96,21 +136,21 @@ WCHAR title[64];
void void
vdrawstatus(msg, ap) vdrawstatus(msg, ap)
const WCHAR *msg; const wchar_t *msg;
va_list ap; va_list ap;
{ {
WCHAR s[1024]; wchar_t s[1024];
VSNPRINTF(s, WSIZEOF(s), msg, ap); vswprintf(s, wsizeof(s), msg, ap);
wmove(statwin, 0, 0); wmove(statwin, 0, 0);
WADDSTR(statwin, s); waddwstr(statwin, s);
wclrtoeol(statwin); wclrtoeol(statwin);
wrefresh(statwin); wrefresh(statwin);
time(&laststatus); time(&laststatus);
} }
void void
drawstatus(const WCHAR *msg, ...) drawstatus(const wchar_t *msg, ...)
{ {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
@ -120,10 +160,10 @@ va_list ap;
int int
yesno(msg) yesno(msg)
const WCHAR *msg; const wchar_t *msg;
{ {
WINDOW *pwin; WINDOW *pwin;
INT c; wint_t c;
pwin = newwin(1, COLS, LINES - 1, 0); pwin = newwin(1, COLS, LINES - 1, 0);
keypad(pwin, TRUE); keypad(pwin, TRUE);
@ -133,8 +173,8 @@ INT c;
wbkgd(pwin, style_bg(sy_status)); wbkgd(pwin, style_bg(sy_status));
wmove(pwin, 0, 0); wmove(pwin, 0, 0);
WADDSTR(pwin, msg); waddwstr(pwin, msg);
WADDSTR(pwin, WIDE(" [y/N]? ")); waddwstr(pwin, L" [y/N]? ");
wattroff(pwin, A_BOLD); wattroff(pwin, A_BOLD);
while (input_char(&c) == ERR while (input_char(&c) == ERR
@ -151,13 +191,13 @@ INT c;
return (c == 'Y' || c == 'y') ? 1 : 0; return (c == 'Y' || c == 'y') ? 1 : 0;
} }
WCHAR * wchar_t *
prompt(msg, def, hist) prompt(msg, def, hist)
const WCHAR *msg, *def; const wchar_t *msg, *def;
history_t *hist; history_t *hist;
{ {
WINDOW *pwin; WINDOW *pwin;
WCHAR input[256]; wchar_t input[256];
size_t pos = 0; size_t pos = 0;
histent_t *histpos = NULL; histent_t *histpos = NULL;
@ -166,8 +206,8 @@ histent_t *histpos = NULL;
memset(input, 0, sizeof(input)); memset(input, 0, sizeof(input));
if (def) { if (def) {
STRNCPY(input, def, WSIZEOF(input) - 1); wcsncpy(input, def, wsizeof(input) - 1);
pos = STRLEN(input); pos = wcslen(input);
} }
pwin = newwin(1, COLS, LINES - 1, 0); pwin = newwin(1, COLS, LINES - 1, 0);
@ -178,17 +218,17 @@ histent_t *histpos = NULL;
wattron(pwin, A_BOLD); wattron(pwin, A_BOLD);
wmove(pwin, 0, 0); wmove(pwin, 0, 0);
WADDSTR(pwin, msg); waddwstr(pwin, msg);
wattroff(pwin, A_BOLD); wattroff(pwin, A_BOLD);
curs_set(1); curs_set(1);
for (;;) { for (;;) {
INT c; wint_t c;
wmove(pwin, 0, STRLEN(msg) + 1); wmove(pwin, 0, wcslen(msg) + 1);
WADDSTR(pwin, input); waddwstr(pwin, input);
wclrtoeol(pwin); wclrtoeol(pwin);
wmove(pwin, 0, STRLEN(msg) + 1 + pos); wmove(pwin, 0, wcslen(msg) + 1 + pos);
wrefresh(pwin); wrefresh(pwin);
if (input_char(&c) == ERR) if (input_char(&c) == ERR)
@ -203,21 +243,21 @@ histent_t *histpos = NULL;
case 0x7F: case 0x7F:
case 0x08: case 0x08:
if (pos) { if (pos) {
if (pos == STRLEN(input)) if (pos == wcslen(input))
input[--pos] = 0; input[--pos] = 0;
else { else {
int i = STRLEN(input); int i = wcslen(input);
pos--; pos--;
MEMCPY(input + pos, input + pos + 1, STRLEN(input) - pos); wmemcpy(input + pos, input + pos + 1, wcslen(input) - pos);
input[i] = 0; input[i] = 0;
} }
} }
break; break;
case KEY_DC: case KEY_DC:
if (pos < STRLEN(input)) { if (pos < wcslen(input)) {
int i = STRLEN(input); int i = wcslen(input);
MEMCPY(input + pos, input + pos + 1, STRLEN(input) - pos); wmemcpy(input + pos, input + pos + 1, wcslen(input) - pos);
input[i] = 0; input[i] = 0;
} }
break; break;
@ -228,7 +268,7 @@ histent_t *histpos = NULL;
break; break;
case KEY_RIGHT: case KEY_RIGHT:
if (pos < STRLEN(input)) if (pos < wcslen(input))
pos++; pos++;
break; break;
@ -239,7 +279,7 @@ histent_t *histpos = NULL;
case KEY_END: case KEY_END:
case 0x05: /* ^E */ case 0x05: /* ^E */
pos = STRLEN(input); pos = wcslen(input);
break; break;
case 0x07: /* ^G */ case 0x07: /* ^G */
@ -273,8 +313,8 @@ histent_t *histpos = NULL;
} }
STRNCPY(input, histpos->he_text, WSIZEOF(input) - 1); wcsncpy(input, histpos->he_text, wsizeof(input) - 1);
pos = STRLEN(input); pos = wcslen(input);
break; break;
case KEY_DOWN: case KEY_DOWN:
@ -290,13 +330,13 @@ histent_t *histpos = NULL;
histpos = TTS_TAILQ_NEXT(histpos, he_entries); histpos = TTS_TAILQ_NEXT(histpos, he_entries);
STRNCPY(input, histpos->he_text, WSIZEOF(input) - 1); wcsncpy(input, histpos->he_text, wsizeof(input) - 1);
pos = STRLEN(input); pos = wcslen(input);
break; break;
default: default:
if (pos != STRLEN(input)) { if (pos != wcslen(input)) {
MEMMOVE(input + pos + 1, input + pos, STRLEN(input) - pos); wmemmove(input + pos + 1, input + pos, wcslen(input) - pos);
input[pos++] = c; input[pos++] = c;
} else { } else {
input[pos++] = c; input[pos++] = c;
@ -313,11 +353,11 @@ end: ;
wtouchln(statwin, 0, 1, 1); wtouchln(statwin, 0, 1, 1);
wrefresh(statwin); wrefresh(statwin);
hist_add(hist, input); hist_add(hist, input);
return STRDUP(input); return wcsdup(input);
} }
void void
errbox(const WCHAR *msg, ...) errbox(const wchar_t *msg, ...)
{ {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
@ -327,19 +367,19 @@ va_list ap;
void void
verrbox(msg, ap) verrbox(msg, ap)
const WCHAR *msg; const wchar_t *msg;
va_list ap; va_list ap;
{ {
WCHAR text[4096]; wchar_t text[4096];
WINDOW *ewin; WINDOW *ewin;
#define ETITLE WIDE(" Error ") #define ETITLE L" Error "
#define ECONT WIDE(" <OK> ") #define ECONT L" <OK> "
int width; int width;
INT c; wint_t c;
VSNPRINTF(text, WSIZEOF(text), msg, ap); vswprintf(text, wsizeof(text), msg, ap);
width = STRLEN(text); width = wcslen(text);
ewin = newwin(6, width + 4, ewin = newwin(6, width + 4,
(LINES / 2) - ((1 + 2)/ 2), (LINES / 2) - ((1 + 2)/ 2),
@ -348,19 +388,19 @@ INT c;
wborder(ewin, 0, 0, 0, 0, 0, 0, 0, 0); wborder(ewin, 0, 0, 0, 0, 0, 0, 0, 0);
wattron(ewin, A_REVERSE | A_BOLD); wattron(ewin, A_REVERSE | A_BOLD);
wmove(ewin, 0, (width / 2) - (WSIZEOF(ETITLE) - 1)/2); wmove(ewin, 0, (width / 2) - (wsizeof(ETITLE) - 1)/2);
WADDSTR(ewin, ETITLE); waddwstr(ewin, ETITLE);
wattroff(ewin, A_REVERSE | A_BOLD); wattroff(ewin, A_REVERSE | A_BOLD);
wmove(ewin, 2, 2); wmove(ewin, 2, 2);
WADDSTR(ewin, text); waddwstr(ewin, text);
wattron(ewin, A_REVERSE | A_BOLD); wattron(ewin, A_REVERSE | A_BOLD);
wmove(ewin, 4, (width / 2) - ((WSIZEOF(ECONT) - 1) / 2)); wmove(ewin, 4, (width / 2) - ((wsizeof(ECONT) - 1) / 2));
WADDSTR(ewin, ECONT); waddwstr(ewin, ECONT);
wattroff(ewin, A_REVERSE | A_BOLD); wattroff(ewin, A_REVERSE | A_BOLD);
for (;;) { for (;;) {
if (WGETCH(ewin, &c) == ERR) if (wget_wch(ewin, &c) == ERR)
continue; continue;
if (c == '\r') if (c == '\r')
break; break;
@ -391,7 +431,7 @@ chtype oldbg;
for (; en; en = TTS_TAILQ_NEXT(en, en_entries)) { for (; en; en = TTS_TAILQ_NEXT(en, en_entries)) {
time_t n; time_t n;
int h, s, m; int h, s, m;
WCHAR flags[10], stime[16], *p; wchar_t flags[10], stime[16], *p;
attr_t attrs = WA_NORMAL; attr_t attrs = WA_NORMAL;
if (!showinv && en->en_flags.efl_invoiced) if (!showinv && en->en_flags.efl_invoiced)
@ -401,7 +441,7 @@ chtype oldbg;
if (lastday != entry_day(en)) { if (lastday != entry_day(en)) {
struct tm *lt; struct tm *lt;
WCHAR lbl[128]; wchar_t lbl[128];
time_t itime = entry_time_for_day(entry_day(en), 1, 0), time_t itime = entry_time_for_day(entry_day(en), 1, 0),
ntime = entry_time_for_day(entry_day(en), 0, 0), ntime = entry_time_for_day(entry_day(en), 0, 0),
btime = entry_time_for_day(entry_day(en), 2, bill_increment); btime = entry_time_for_day(entry_day(en), 2, bill_increment);
@ -409,7 +449,7 @@ chtype oldbg;
hn, mn, sn, hn, mn, sn,
hb, mb, sb, hb, mb, sb,
ht, mt, st; ht, mt, st;
WCHAR hdrtext[256]; wchar_t hdrtext[256];
time_to_hms(itime, hi, mi, si); time_to_hms(itime, hi, mi, si);
time_to_hms(ntime, hn, mn, sn); time_to_hms(ntime, hn, mn, sn);
@ -432,24 +472,24 @@ chtype oldbg;
lastday = entry_day(en); lastday = entry_day(en);
lt = localtime(&lastday); lt = localtime(&lastday);
STRFTIME(lbl, WSIZEOF(lbl), WIDE("%A, %d %B %Y"), lt); wcsftime(lbl, wsizeof(lbl), L"%A, %d %B %Y", lt);
if (show_billable) if (show_billable)
SNPRINTF(hdrtext, WSIZEOF(hdrtext), swprintf(hdrtext, wsizeof(hdrtext),
WIDE("%-30"FMT_L"s [I:%02d:%02d:%02d / " L"%-30ls [I:%02d:%02d:%02d / "
"N:%02d:%02d:%02d / T:%02d:%02d:%02d / " L"N:%02d:%02d:%02d / T:%02d:%02d:%02d / "
"B:%02d:%02d:%02d]"), L"B:%02d:%02d:%02d]",
lbl, hi, mi, si, hn, mn, sn, ht, mt, st, lbl, hi, mi, si, hn, mn, sn, ht, mt, st,
hb, mb, sb); hb, mb, sb);
else else
SNPRINTF(hdrtext, WSIZEOF(hdrtext), swprintf(hdrtext, wsizeof(hdrtext),
WIDE("%-30"FMT_L"s [I:%02d:%02d:%02d / " L"%-30ls [I:%02d:%02d:%02d / "
"N:%02d:%02d:%02d / T:%02d:%02d:%02d]"), L"N:%02d:%02d:%02d / T:%02d:%02d:%02d]",
lbl, hi, mi, si, hn, mn, sn, ht, mt, st); lbl, hi, mi, si, hn, mn, sn, ht, mt, st);
wattr_on(listwin, style_fg(sy_date), NULL); wattr_on(listwin, style_fg(sy_date), NULL);
wbkgdset(listwin, style_bg(sy_date)); wbkgdset(listwin, style_bg(sy_date));
wmove(listwin, cline, 0); wmove(listwin, cline, 0);
WADDSTR(listwin, hdrtext); waddwstr(listwin, hdrtext);
wclrtoeol(listwin); wclrtoeol(listwin);
wattr_off(listwin, style_fg(sy_date), NULL); wattr_off(listwin, style_fg(sy_date), NULL);
wbkgdset(listwin, oldbg); wbkgdset(listwin, oldbg);
@ -494,9 +534,9 @@ chtype oldbg;
wattr_on(listwin, attrs, NULL); wattr_on(listwin, attrs, NULL);
if (en == curent) { if (en == curent) {
WADDSTR(listwin, WIDE(" -> ")); waddwstr(listwin, L" -> ");
} else } else
WADDSTR(listwin, WIDE(" ")); waddwstr(listwin, L" ");
n = en->en_secs; n = en->en_secs;
if (en->en_started) if (en->en_started)
@ -507,9 +547,9 @@ chtype oldbg;
n %= 60; n %= 60;
s = n; s = n;
SNPRINTF(stime, WSIZEOF(stime), WIDE("%02d:%02d:%02d%c "), swprintf(stime, wsizeof(stime), L"%02d:%02d:%02d%c ",
h, m, s, (itime && (en == running)) ? '*' : ' '); h, m, s, (itime && (en == running)) ? '*' : ' ');
WADDSTR(listwin, stime); waddwstr(listwin, stime);
memset(flags, 0, sizeof(flags)); memset(flags, 0, sizeof(flags));
p = flags; p = flags;
@ -535,13 +575,13 @@ chtype oldbg;
*p++ = ' '; *p++ = ' ';
if (*flags) { if (*flags) {
WCHAR s[10]; wchar_t s[10];
SNPRINTF(s, WSIZEOF(s), WIDE("%-5"FMT_L"s "), flags); swprintf(s, wsizeof(s), L"%-5ls ", flags);
WADDSTR(listwin, s); waddwstr(listwin, s);
} else } else
WADDSTR(listwin, WIDE(" ")); waddwstr(listwin, L" ");
WADDSTR(listwin, en->en_desc); waddwstr(listwin, en->en_desc);
wclrtoeol(listwin); wclrtoeol(listwin);
wbkgdset(listwin, oldbg); wbkgdset(listwin, oldbg);
wattr_off(listwin, attrs, NULL); wattr_off(listwin, attrs, NULL);
@ -563,27 +603,27 @@ chtype oldbg;
int int
prduration(pr, hh, mm, ss) prduration(pr, hh, mm, ss)
WCHAR *pr; wchar_t *pr;
int *hh, *mm, *ss; int *hh, *mm, *ss;
{ {
WCHAR *tstr; wchar_t *tstr;
int h, m, s; int h, m, s;
if ((tstr = prompt(pr, WIDE("00:00:00"), NULL)) == NULL) if ((tstr = prompt(pr, L"00:00:00", NULL)) == NULL)
return -1; return -1;
if (!*tstr) { if (!*tstr) {
drawstatus(WIDE("No duration entered")); drawstatus(L"No duration entered");
free(tstr); free(tstr);
return -1; return -1;
} }
if (SSCANF(tstr, WIDE("%d:%d:%d"), &h, &m, &s) != 3) { if (swscanf(tstr, L"%d:%d:%d", &h, &m, &s) != 3) {
h = 0; h = 0;
if (SSCANF(tstr, WIDE("%d:%d"), &m, &s) != 2) { if (swscanf(tstr, L"%d:%d", &m, &s) != 2) {
m = 0; m = 0;
if (SSCANF(tstr, WIDE("%d"), &s) != 1) { if (swscanf(tstr, L"%d", &s) != 1) {
free(tstr); free(tstr);
drawstatus(WIDE("Invalid time format.")); drawstatus(L"Invalid time format.");
return -1; return -1;
} }
} }
@ -592,12 +632,12 @@ int h, m, s;
free(tstr); free(tstr);
if (m >= 60) { if (m >= 60) {
drawstatus(WIDE("Minutes cannot be more than 59.")); drawstatus(L"Minutes cannot be more than 59.");
return -1; return -1;
} }
if (s >= 60) { if (s >= 60) {
drawstatus(WIDE("Seconds cannot be more than 59.")); drawstatus(L"Seconds cannot be more than 59.");
return -1; return -1;
} }

17
ui.h
View file

@ -21,17 +21,18 @@ extern WINDOW *titwin, *statwin, *listwin;
extern int in_curses; extern int in_curses;
extern int showinv; extern int showinv;
void cursadvance(void); void ui_init (void);
void drawstatus (const WCHAR *msg, ...); void cursadvance (void);
void vdrawstatus (const WCHAR *msg, va_list); void drawstatus (const wchar_t *msg, ...);
void vdrawstatus (const wchar_t *msg, va_list);
void drawheader (void); void drawheader (void);
void drawentries (void); void drawentries (void);
WCHAR *prompt (WCHAR const *, WCHAR const *, history_t *); wchar_t *prompt (wchar_t const *, wchar_t const *, history_t *);
int prduration (WCHAR *prompt, int *h, int *m, int *s); int prduration (wchar_t *prompt, int *h, int *m, int *s);
int yesno (WCHAR const *); int yesno (wchar_t const *);
void errbox (WCHAR const *, ...); void errbox (wchar_t const *, ...);
void verrbox (WCHAR const *, va_list); void verrbox (wchar_t const *, va_list);
#endif /* !TTS_UI_H */ #endif /* !TTS_UI_H */

View file

@ -14,7 +14,7 @@
#include "wide.h" #include "wide.h"
typedef struct variable { typedef struct variable {
WCHAR const *va_name; wchar_t const *va_name;
int va_type; int va_type;
void *va_addr; void *va_addr;
} variable_t; } variable_t;
@ -23,6 +23,6 @@ typedef struct variable {
#define VTYPE_BOOL 2 #define VTYPE_BOOL 2
#define VTYPE_STRING 3 #define VTYPE_STRING 3
variable_t *find_variable(const WCHAR *name); variable_t *find_variable(const wchar_t *name);
#endif /* !TTS_VARIABLE_H */ #endif /* !TTS_VARIABLE_H */

70
wide.h
View file

@ -11,74 +11,14 @@
#ifndef TTS_WIDE_H #ifndef TTS_WIDE_H
#define TTS_WIDE_H #define TTS_WIDE_H
#include <wchar.h>
#include "config.h" #include "config.h"
#include "tts_curses.h" #include "tts_curses.h"
#ifdef HAVE_CURSES_ENHANCED #define wsizeof(s) (sizeof(s) / sizeof(wchar_t))
# include <wchar.h>
# define WPFX(x) wcs##x int input_char(wchar_t *);
# define WIDE(x) L##x void input_macro(wchar_t *);
# define ISX(x) isw##x
# define WCHAR wchar_t
# define FMT_L "l"
# define SNPRINTF swprintf
# define VSNPRINTF vswprintf
# define SSCANF swscanf
# define MEMCPY wmemcpy
# define MEMMOVE wmemmove
# define MBSTOWCS mbstowcs
# define WCSTOMBS wcstombs
# define FPRINTF fwprintf
# define STRTOK wcstok
# define GETCH get_wch
# define WGETCH wget_wch
# define ADDSTR addwstr
# define WADDSTR waddwstr
# define INT wint_t
#else
# define WPFX(x) str##x
# define WIDE(x) x
# define ISX(x) is##x
# define WCHAR char
# define FMT_L
# define SNPRINTF snprintf
# define VSNPRINTF vsnprintf
# define SSCANF sscanf
# define MEMCPY memcpy
# define MEMMOVE memmove
# define MBSTOWCS strncpy
# define WCSTOMBS strncpy
# define FPRINTF fprintf
# define STRTOK strtok_r
# define ADDSTR addstr
# define WADDSTR waddstr
# define INT int
# define NEED_TTS_WGETCH
extern int tts_wgetch(WINDOW *, int *);
# define WGETCH tts_wgetch
# define GETCH(c) tts_wgetch(stdscr,c)
#endif
#define STRLEN WPFX(len)
#define STRCMP WPFX(cmp)
#define STRNCMP WPFX(ncmp)
#define STRCPY WPFX(cpy)
#define STRNCPY WPFX(ncpy)
#define STRSTR WPFX(str)
#define STRFTIME WPFX(ftime)
#define STRDUP WPFX(dup)
#define STRTOL WPFX(tol)
#define ISSPACE ISX(space)
#define WSIZEOF(s) (sizeof(s) / sizeof(WCHAR))
int input_char(WCHAR *);
void input_macro(WCHAR *);
#endif /* !TTS_WIDE_H */ #endif /* !TTS_WIDE_H */