bump to version 0.2
- better recognition of invalid config files - general polish of error messages - hkd follows the rule of silence - when using -v the correct key names are shown - commands in config files can be multiline (using \\n)
This commit is contained in:
parent
344887c925
commit
1ba688f975
4
hkd.1
4
hkd.1
@ -89,10 +89,6 @@ This is a valid config file example
|
|||||||
.PP
|
.PP
|
||||||
Known bugs are:
|
Known bugs are:
|
||||||
.IP -
|
.IP -
|
||||||
Commands in the config file cannot be multiline
|
|
||||||
.IP -
|
|
||||||
Invalid config files are not detected properly, or at least not explicitly
|
|
||||||
.IP -
|
|
||||||
Child processes
|
Child processes
|
||||||
are waited at program exit possibly causing the process tree to hang as there is
|
are waited at program exit possibly causing the process tree to hang as there is
|
||||||
no real child process control
|
no real child process control
|
||||||
|
181
hkd.c
181
hkd.c
@ -228,8 +228,8 @@ int is_empty (const char *s);
|
|||||||
/* hotkey list operations */
|
/* hotkey list operations */
|
||||||
void hotkey_list_add (struct hotkey_list_e *, struct key_buffer *, char *, int);
|
void hotkey_list_add (struct hotkey_list_e *, struct key_buffer *, char *, int);
|
||||||
void hotkey_list_destroy (struct hotkey_list_e *);
|
void hotkey_list_destroy (struct hotkey_list_e *);
|
||||||
|
void hotkey_list_append_command (struct hotkey_list_e *, char *);
|
||||||
|
|
||||||
// TODO: use getopts() to parse command line options
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* Handle SIGINT */
|
/* Handle SIGINT */
|
||||||
@ -414,6 +414,10 @@ void int_handler (int signum)
|
|||||||
{
|
{
|
||||||
switch (signum) {
|
switch (signum) {
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
|
if (dead) {
|
||||||
|
fprintf(stderr, red("an error occured, exiting\n"));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
if (vflag)
|
if (vflag)
|
||||||
printf(yellow("Received interrupt signal, exiting gracefully...\n"));
|
printf(yellow("Received interrupt signal, exiting gracefully...\n"));
|
||||||
dead = 1;
|
dead = 1;
|
||||||
@ -437,7 +441,7 @@ void exec_command (char *command)
|
|||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
/* Some other error */
|
/* Some other error */
|
||||||
fprintf(stderr, "Could not parse, %s is not valid", command);
|
fprintf(stderr, "Could not parse, %s is not valid\n", command);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,6 +604,20 @@ void hotkey_list_add (struct hotkey_list_e *head, struct key_buffer *kb, char *c
|
|||||||
hotkey_list = tmp;
|
hotkey_list = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hotkey_list_append_command (struct hotkey_list_e *head, char *cmd)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
if (!head)
|
||||||
|
return;
|
||||||
|
while (head->next)
|
||||||
|
head = head->next;
|
||||||
|
tmp = realloc(head->command, sizeof(head->command) + strlen(cmd) + 1);
|
||||||
|
if (!tmp)
|
||||||
|
die("realloc in hotkey_list_append_command()");
|
||||||
|
head->command = tmp;
|
||||||
|
strcat(head->command, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
void parse_config_file (void)
|
void parse_config_file (void)
|
||||||
{
|
{
|
||||||
wordexp_t result = {0};
|
wordexp_t result = {0};
|
||||||
@ -650,15 +668,18 @@ void parse_config_file (void)
|
|||||||
die("could not open any config files, check the log for more details");
|
die("could not open any config files, check the log for more details");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iscmd = 0;
|
||||||
struct key_buffer kb;
|
struct key_buffer kb;
|
||||||
for (int linenum = 1;; linenum++) {
|
for (int linenum = 1;; linenum++) {
|
||||||
int fuzzy = 0, tmp;
|
int fuzzy = 0, tmp;
|
||||||
char * linebegin = NULL;
|
char * linebegin = NULL;
|
||||||
char *line = NULL, *keys = NULL, *command = NULL;
|
char *line = NULL, *keys = NULL, *command = NULL;
|
||||||
size_t linelen = 0;
|
size_t linelen = 0;
|
||||||
|
|
||||||
if (getline(&line, &linelen, fd) == -1)
|
if (getline(&line, &linelen, fd) == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
linelen = strlen(line);
|
||||||
if (linelen < 2)
|
if (linelen < 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -671,72 +692,106 @@ void parse_config_file (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip comments and blank lines
|
// Skip comments and blank lines
|
||||||
if (line[0] == '#' || !line[0]) {
|
if (line[0] == '#' || !line[0])
|
||||||
free(linebegin);
|
goto parse_end_free;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (size_t i = 1; i < linelen; i++) {
|
for (size_t i = 1; i < linelen; i++) {
|
||||||
if (line[i] == '#')
|
if (line[i] == '#')
|
||||||
line[i] = '\0';
|
line[i] = '\0';
|
||||||
}
|
}
|
||||||
|
if (!iscmd) {
|
||||||
// TODO: multiline commands, ending with "\\n"
|
if (line[0] != '-' && line[0] != '*') {
|
||||||
if (line[0] == '*')
|
fprintf(stderr, red("Error at line %d: "
|
||||||
fuzzy = 1;
|
"Hotkey definitions must start with '*' or '-'\n"), linenum);
|
||||||
line = &line[1];
|
|
||||||
linelen--;
|
|
||||||
// Remove leading spaces
|
|
||||||
while (isspace(line[0]) && linelen > 1) {
|
|
||||||
line = &line[1];
|
|
||||||
linelen--;
|
|
||||||
}
|
|
||||||
keys = strtok(line, ":");
|
|
||||||
command = strtok(NULL, ":");
|
|
||||||
if (!command || !keys) {
|
|
||||||
fprintf(stderr, "Error at line %d:"
|
|
||||||
"No command or keys specified\n", linenum);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove whitespaces in keys
|
|
||||||
tmp = strlen(keys);
|
|
||||||
for (int i = 0; i < tmp; i++) {
|
|
||||||
if (isspace(keys[i])) {
|
|
||||||
memmove(&line[i], &line[i + 1], --tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove leading and trailing spaces in command
|
|
||||||
tmp = strlen(command);
|
|
||||||
while (isspace(command[0]) && tmp > 1) {
|
|
||||||
command = &command[1];
|
|
||||||
tmp--;
|
|
||||||
}
|
|
||||||
tmp = strlen(command) - 1;
|
|
||||||
while (isspace(command[tmp]))
|
|
||||||
command[tmp--] = '\0';
|
|
||||||
|
|
||||||
// Check if keys and command are not blank
|
|
||||||
if (is_empty(keys) || is_empty(command)) {
|
|
||||||
fprintf(stderr, red("Error at line %d: "
|
|
||||||
"command or keys not present\n"), linenum);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
key_buffer_reset(&kb);
|
|
||||||
char *k = strtok(keys, ",");
|
|
||||||
unsigned short kc;
|
|
||||||
do {
|
|
||||||
if (!(kc = key_to_code(k))) {
|
|
||||||
fprintf(stderr, "Error at line %d:"
|
|
||||||
"%s is not a valid key", linenum, k);
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
key_buffer_add(&kb, kc);
|
|
||||||
} while ((k = strtok(NULL, ",")));
|
if (line[0] == '*')
|
||||||
hotkey_list_add(hotkey_list, &kb, command, fuzzy);
|
fuzzy = 1;
|
||||||
hotkey_size_mask |= 1 << (kb.size - 1);
|
line = &line[1];
|
||||||
key_buffer_reset(&kb);
|
linelen--;
|
||||||
|
// Remove leading spaces
|
||||||
|
while (isspace(line[0]) && linelen > 1) {
|
||||||
|
line = &line[1];
|
||||||
|
linelen--;
|
||||||
|
}
|
||||||
|
keys = strtok(line, ":");
|
||||||
|
command = strtok(NULL, ":");
|
||||||
|
if (!command || !keys) {
|
||||||
|
fprintf(stderr, red("Error at line %d: "
|
||||||
|
"No command or keys specified\n"), linenum);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// Check if keys and command are not blank
|
||||||
|
if (is_empty(keys) || is_empty(command)) {
|
||||||
|
fprintf(stderr, red("Error at line %d: "
|
||||||
|
"command or keys not present\n"), linenum);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove whitespaces in keys
|
||||||
|
tmp = strlen(keys);
|
||||||
|
for (int i = 0; i < tmp; i++) {
|
||||||
|
if (isspace(keys[i]))
|
||||||
|
memmove(&line[i], &line[i + 1], --tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove leading and trailing spaces in command
|
||||||
|
tmp = strlen(command);
|
||||||
|
while (isspace(command[0]) && tmp > 1) {
|
||||||
|
command = &command[1];
|
||||||
|
tmp--;
|
||||||
|
}
|
||||||
|
for (tmp = strlen(command) - 1; isspace(command[tmp]); tmp--) {
|
||||||
|
if (isblank(command[tmp]))
|
||||||
|
command[tmp] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command[strlen(command) - 2] == '\\') {
|
||||||
|
iscmd = 1;
|
||||||
|
} else {
|
||||||
|
iscmd = 0;
|
||||||
|
tmp = strlen(command) - 1;
|
||||||
|
while (isspace(command[tmp]))
|
||||||
|
command[tmp--] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
key_buffer_reset(&kb);
|
||||||
|
char *k = strtok(keys, ",");
|
||||||
|
unsigned short kc;
|
||||||
|
do {
|
||||||
|
if (!(kc = key_to_code(k))) {
|
||||||
|
fprintf(stderr, red("Error at line %d: "
|
||||||
|
"%s is not a valid key"), linenum, k);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
key_buffer_add(&kb, kc);
|
||||||
|
} while ((k = strtok(NULL, ",")));
|
||||||
|
hotkey_list_add(hotkey_list, &kb, command, fuzzy);
|
||||||
|
hotkey_size_mask |= 1 << (kb.size - 1);
|
||||||
|
key_buffer_reset(&kb);
|
||||||
|
} else {
|
||||||
|
for (tmp = strlen(line) - 1; isspace(line[tmp]); tmp--) {
|
||||||
|
if (isblank(line[tmp]))
|
||||||
|
line[tmp] = '\0';
|
||||||
|
}
|
||||||
|
linelen = strlen(line);
|
||||||
|
|
||||||
|
// if line is blank skip
|
||||||
|
if (is_empty(line))
|
||||||
|
goto parse_end_free;
|
||||||
|
|
||||||
|
if (line[linelen - 2] == '\\') {
|
||||||
|
iscmd = 1;
|
||||||
|
} else {
|
||||||
|
iscmd = 0;
|
||||||
|
while (isspace(line[linelen - 1]))
|
||||||
|
line[--linelen] = '\0';
|
||||||
|
}
|
||||||
|
hotkey_list_append_command(hotkey_list, line);
|
||||||
|
}
|
||||||
|
parse_end_free:
|
||||||
|
free(linebegin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user