@ -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 ;
}