bump to version 0.3

bug fixes, check commits for details
implemented new parser, altough it adds some lines it lowers the comlexity and
it should be faster especially for bigger config files
xkbcommon
Alessandro Mauri 4 years ago
parent 0507be14b6
commit 9871f375ed
  1. 289
      hkd.c
  2. 2
      makefile

289
hkd.c

@ -20,6 +20,7 @@
/* Value defines */ /* Value defines */
#define FILE_NAME_MAX_LENGTH 255 #define FILE_NAME_MAX_LENGTH 255
#define KEY_BUFFER_SIZE 16 #define KEY_BUFFER_SIZE 16
#define BLOCK_SIZE 512
/* ANSI colors escape codes */ /* ANSI colors escape codes */
#define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_RED "\x1b[31m"
@ -224,11 +225,9 @@ void parse_config_file (void);
void update_descriptors_list (int **, int *); void update_descriptors_list (int **, int *);
int prepare_epoll (int *, int, int); int prepare_epoll (int *, int, int);
unsigned short key_to_code (char *); unsigned short key_to_code (char *);
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 *);
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
@ -612,24 +611,25 @@ 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};
FILE *fd; FILE *fd;
int remaining = 0;
char block[BLOCK_SIZE + 1] = {0};
char *bb = NULL;
// 0: normal, 1: skip line 2: get directive 3: get keys 4: get command 5: output
int state = 0;
char *keys = NULL;
char *cmd = NULL;
int alloc_tmp = 0, alloc_size = 0;
int fuzzy = 0;
struct key_buffer kb;
int i_tmp = 0, done = 0;
char *cp_tmp = NULL;
unsigned short us_tmp = 0;
if (ext_config_file) { if (ext_config_file) {
switch (wordexp(ext_config_file, &result, 0)) { switch (wordexp(ext_config_file, &result, 0)) {
case 0: case 0:
@ -675,131 +675,160 @@ void parse_config_file (void)
if (!fd) if (!fd)
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");
} }
while (!done) {
int iscmd = 0; memset(block, 0, BLOCK_SIZE);
struct key_buffer kb; remaining = fread(block, sizeof(char), BLOCK_SIZE, fd);
for (int linenum = 1;; linenum++) { if (!remaining)
int fuzzy = 0, tmp;
char * linebegin = NULL;
char *line = NULL, *keys = NULL, *command = NULL;
size_t linelen = 0;
if (getline(&line, &linelen, fd) == -1)
break; break;
bb = block;
linelen = strlen(line); while (remaining > 0) {
if (linelen < 2) switch (state) {
continue; // First state
case 0:
linebegin = line; // remove whitespaces
while (isblank(*bb) && remaining > 0)
// Remove leading spaces bb++, remaining--;
while (isspace(line[0]) && linelen > 1) { if (remaining <= 0)
line = &line[1]; break;
linelen--; // get state
} switch (*bb) {
case '\n':
// Skip comments and blank lines case '#':
if (line[0] == '#' || !line[0]) state = 1;
goto parse_end_free; break;
case '\0':
for (size_t i = 1; i < linelen; i++) { done = 1;
if (line[i] == '#') break;
line[i] = '\0'; default:
} state = 2;
if (!iscmd) { break;
if (line[0] != '-' && line[0] != '*') {
fprintf(stderr, red("Error at line %d: "
"Hotkey definitions must start with '*' or '-'\n"), linenum);
exit(EXIT_FAILURE);
} }
break;
if (line[0] == '*') // Skip line (comment)
case 1:
while (*bb != '\n' && remaining > 0)
bb++, remaining--;
bb++, remaining--;
if (remaining > 0)
state = 0;
break;
// Get compairson method
case 2:
switch (*bb) {
case '-':
fuzzy = 0;
break;
case '*':
fuzzy = 1; fuzzy = 1;
line = &line[1]; break;
linelen--; default:
// Remove leading spaces die("invalid line")
while (isspace(line[0]) && linelen > 1) { break;
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 bb++, remaining--;
if (is_empty(keys) || is_empty(command)) { state = 3;
fprintf(stderr, red("Error at line %d: " break;
"command or keys not present\n"), linenum); // Get keys
exit(EXIT_FAILURE); case 3:
if (!keys) {
if (!(keys = malloc(alloc_size = (sizeof(char) * 64))))
die("malloc for keys in parse_config_file()");
memset(keys, 0, alloc_size);
alloc_tmp = 0;
} else if (alloc_tmp >= alloc_size) {
if (!(keys = realloc(keys, alloc_size *= 2)))
die("realloc for keys in parse_config_file()");
memset(&keys[alloc_size / 2], 0, alloc_size / 2);
}
for (; remaining > 0 &&
(bb[alloc_tmp] != ':' && bb[alloc_tmp] != '\n') &&
alloc_tmp < alloc_size;
remaining--, alloc_tmp++);
if (remaining <= 0 || alloc_tmp == alloc_size) {
strncat(keys, bb, alloc_tmp);
bb += alloc_tmp;
break;
} else if (bb[alloc_tmp] == ':') {
strncat(keys, bb, alloc_tmp);
bb += alloc_tmp + 1;
remaining--;
state = 4;
break;
} else {
die("no command");
} }
break;
// Remove whitespaces in keys // Get command
tmp = strlen(keys); case 4:
for (int i = 0; i < tmp; i++) { if (!cmd) {
if (isspace(keys[i])) if (!(cmd = malloc(alloc_size = (sizeof(char) * 128))))
memmove(&line[i], &line[i + 1], --tmp); die("malloc for cmd in parse_config_file()");
memset(cmd, 0, alloc_size);
alloc_tmp = 0;
} else if (alloc_tmp >= alloc_size) {
if (!(cmd = realloc(cmd, alloc_size *= 2)))
die("realloc for cmd in parse_config_file()");
memset(&cmd[alloc_size / 2], 0, alloc_size / 2);
}
for (; remaining > 0 &&
bb[alloc_tmp] != '\n' &&
alloc_tmp < alloc_size;
remaining--, alloc_tmp++);
if (remaining <= 0 || alloc_tmp == alloc_size) {
strncat(cmd, bb, alloc_tmp);
bb += alloc_tmp;
break;
} else {
strncat(cmd, bb, alloc_tmp);
if (!(bb[alloc_tmp - 1] == '\\'))
state = 5;
bb += alloc_tmp + 1;
remaining--;
break;
} }
break;
// Remove leading and trailing spaces in command case 5:
tmp = strlen(command); i_tmp = strlen(keys);
while (isspace(command[0]) && tmp > 1) { for (int i = 0; i < i_tmp; i++) {
command = &command[1]; if (isblank(keys[i])) {
tmp--; memmove(&keys[i], &keys[i + 1], --i_tmp);
keys[i_tmp] = '\0';
} }
for (tmp = strlen(command) - 1; isspace(command[tmp]); tmp--) {
if (isblank(command[tmp]))
command[tmp] = '\0';
} }
cp_tmp = strtok(keys, ",");
if(!cp_tmp)
die("no keys");
do {
if (!(us_tmp = key_to_code(cp_tmp)))
die("key not valid");
key_buffer_add(&kb, us_tmp);
} while ((cp_tmp = strtok(NULL, ",")));
if (command[strlen(command) - 2] == '\\') { cp_tmp = cmd;
iscmd = 1; while (isblank(*cp_tmp))
} else { cp_tmp++;
iscmd = 0;
tmp = strlen(command) - 1;
while (isspace(command[tmp]))
command[tmp--] = '\0';
}
key_buffer_reset(&kb); hotkey_list_add(hotkey_list, &kb, cp_tmp, fuzzy);
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); hotkey_size_mask |= 1 << (kb.size - 1);
key_buffer_reset(&kb); // DO STUFF
} 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 key_buffer_reset(&kb);
if (is_empty(line)) free(keys);
goto parse_end_free; free(cmd);
cp_tmp = keys = cmd = NULL;
i_tmp = state = 0;
break;
default:
die("unknown state in parse_config_file");
break;
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);
} }
} }
@ -811,13 +840,3 @@ unsigned short key_to_code (char *key)
} }
return 0; return 0;
} }
int is_empty (const char *s)
{
while (*s != '\0') {
if (!isspace((unsigned char)*s))
return 0;
s++;
}
return 1;
}

@ -1,6 +1,6 @@
CC = gcc CC = gcc
CFLAGS = -Wall -Werror -pedantic --std=c99 -O2 CFLAGS = -Wall -Werror -pedantic --std=c99 -O2
VERSION = 0.2 VERSION = 0.3
PREFIX = /usr/local PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man MANPREFIX = ${PREFIX}/share/man

Loading…
Cancel
Save