From 1d5a5d9d69d5a3a41c204b75320611e4471dc437 Mon Sep 17 00:00:00 2001 From: Rexy712 Date: Mon, 10 Dec 2018 11:19:15 -0800 Subject: [PATCH] Refactored how operations are carried out --- include/common.h | 9 +-- include/restore.h | 3 +- src/cmd.c | 3 +- src/restore.c | 22 +----- src/rexbacklight.c | 180 ++++++++++++++++++++++++++------------------- 5 files changed, 113 insertions(+), 104 deletions(-) diff --git a/include/common.h b/include/common.h index d509161..c751fa0 100644 --- a/include/common.h +++ b/include/common.h @@ -40,11 +40,6 @@ #define IO_ERROR_READ "read" #define IO_ERROR_WRITE "write to" -void io_error(const char* error, const char* type, const char* name); -void io_error_2(const char* error, const char* type, const char* name, const char* name2); -void io_error_3(const char* error, const char* type, const char* name, const char* name2, const char* name3); - - extern int return_value; struct string_array{ @@ -53,7 +48,11 @@ struct string_array{ }; void free_string_array(struct string_array* s); +void io_error(const char* error, const char* type, const char* name); +void io_error_2(const char* error, const char* type, const char* name, const char* name2); +void io_error_3(const char* error, const char* type, const char* name, const char* name2, const char* name3); void mem_error(void); + _Noreturn void version(void); _Noreturn void usage(int exit_val); diff --git a/include/restore.h b/include/restore.h index edfa464..9d230c7 100644 --- a/include/restore.h +++ b/include/restore.h @@ -25,8 +25,7 @@ #include "cmd.h" void save_restore_file(struct string_array* devices); -void all_restore(void); -int individual_restore(struct arg_values* curr, RJP_value** root, int* try_restore); +int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore); RJP_value* find_matching_json_device(const char* name, RJP_value* root); RJP_value* read_restore_file(const char* file); diff --git a/src/cmd.c b/src/cmd.c index 3dceeca..522fe72 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -69,7 +69,7 @@ #define SET_DESC "set backlight device to specified value" #define INC_DESC "increase backlight device by specified value" #define DEC_DESC "decrease backlight device by specified value" -#define RESTORE_DESC "reassign previously saved backlight values" +#define RESTORE_DESC "reassign previously saved device values" int strcmp_handle_null(const char* one, const char* two){ if(!one) @@ -119,7 +119,6 @@ struct cmd_arg rexbacklight_args[] = { }; #endif //XBACKLIGHT_COMPAT_OPTIONS - int rexbacklight_args_length = sizeof(rexbacklight_args) / sizeof(rexbacklight_args[0]); //Clean up a cmd_arg struct diff --git a/src/restore.c b/src/restore.c index 32c2fa7..868808f 100644 --- a/src/restore.c +++ b/src/restore.c @@ -92,8 +92,8 @@ RJP_value* find_matching_json_device(const char* name, RJP_value* root){ return NULL; } -//run restore on individual device -int individual_restore(struct arg_values* curr, RJP_value** root, int* try_restore){ +//convert a restoration operation to a set operation +int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore){ if(!*root && *try_restore){ char* tmp = restore_file(); *root = read_restore_file(tmp); @@ -113,24 +113,6 @@ int individual_restore(struct arg_values* curr, RJP_value** root, int* try_resto return 1; } -//run restore on all devices -void all_restore(void){ - char* rfil = restore_file(); - RJP_value* root = read_restore_file(rfil); - free(rfil); - if(!root) - return; - struct arg_values tmp = {.next = NULL, - .fade_duration = 0, - .fade_steps = 1, - .operation = OP_SET}; - for(RJP_value* curr = rjp_get_member(root);curr;curr = rjp_next_member(curr)){ - tmp.device = rjp_member_name(curr); - tmp.delta = rjp_value_dfloat(curr); - individual_device_op(&tmp); - } - rjp_free_value(root); -} void save_restore_file(struct string_array* devices){ RJP_value* root = rjp_init_json(); for(size_t i = 0;i < devices->size;++i){ diff --git a/src/rexbacklight.c b/src/rexbacklight.c index 1afa458..f4b226a 100644 --- a/src/rexbacklight.c +++ b/src/rexbacklight.c @@ -35,12 +35,13 @@ #include "restore.h" #endif -//name of the program being run so that we print the correct name in the usage #ifdef REXBACKLIGHT //This is where backlight devices can be found in sysfs const char* device_dir(void){return "/sys/class/backlight/";} +//name of the program being run so that we print the correct name in the usage const char* executable_name(void){return "rexbacklight";} +//location of the restore file in the home directory const char* restore_file_suffix(void){return "/.config/rexbacklight.json";} #elif defined(REXLEDCTL) //This is where led devices can be found in sysfs @@ -53,6 +54,7 @@ const char* restore_file_suffix(void){return "/.config/rexledctl.json";} const char* brightness_file(void){return "brightness";} const char* max_brightness_file(void){return "max_brightness";} + //Get a list of led/backlight devices in sysfs struct string_array get_device_sources(void){ DIR* fd; @@ -77,6 +79,7 @@ struct string_array get_device_sources(void){ for(arr.size = 0;(dir = readdir(fd));){ int slen; + //ignore '.' and '..' if(!strncmp(dir->d_name, ".", 1) || !strncmp(dir->d_name, "..", 2)){ continue; } @@ -135,11 +138,13 @@ float get_brightness(const char* file){ fclose(bright); return atof(buff); } +//return milliseconds since last boot double get_time(void){ struct timespec t; clock_gettime(CLOCK_BOOTTIME, &t); return ((t.tv_sec * 1000.0) + (t.tv_nsec * 0.0000001)); } +//sleep thread for milliseconds void sleep_for(double time){ DEBUG_PRINT("sleeping for %lf milliseconds\n", time); struct timespec ts; @@ -149,11 +154,10 @@ void sleep_for(double time){ } //update brightness incrementally over requested millisecond time interval - void fade_out(struct arg_values* arg, int iv, int fv){ FILE* fd; double start, end; - double tdelta = 0; //amount of time that has passed in ms + double tdelta = 0; //amount of time that has passed in ms float value = iv; //current value to write to file double step_delta = (double)arg->fade_duration / arg->fade_steps; double step_inc = step_delta; @@ -198,89 +202,115 @@ void fade_out(struct arg_values* arg, int iv, int fv){ } //Write value to device files -void do_assignment(struct arg_values* arg, const char* device){ - int start = get_brightness(brightness_file()); - int out = process_op(arg, 0, start, get_brightness(max_brightness_file())); - fade_out(arg, start, out); -} - -//Run get operation -void do_get(const char* device){ - float curr, max; - curr = get_brightness(brightness_file()); - max = get_brightness(max_brightness_file()); - if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){ - fprintf(stdout, "%s", device); - }else{ - fprintf(stdout, "%-25s %.2f\n", device, curr / max * 100); - } -} - -//Run list operation -void do_list(struct string_array* names){ - for(int i = 0;i < names->size;++i) - fprintf(stdout, "%s\n", names->list[i]); -} - -int individual_device_op(struct arg_values* curr){ - if(chdir(curr->device)){ - io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), curr->device); - return RETVAL_INVALID_DIR; - } - switch(curr->operation){ - case OP_SET: - case OP_INC: - case OP_DEC: - do_assignment(curr, curr->device); - break; - case OP_GET: - do_get(curr->device); - break; - case OP_LIST: - printf("%s\n", curr->device); - break; - } - if(chdir(device_dir())){ - io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); - return RETVAL_INTERNAL_ERROR; +int do_assignment(struct arg_values* args){ + for(;args;args = args->next){ + if(chdir(args->device)){ + io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device); + return_value = RETVAL_INVALID_DIR; + continue; + } + int start = get_brightness(brightness_file()); + int out = process_op(args, 0, start, get_brightness(max_brightness_file())); + fade_out(args, start, out); + if(chdir(device_dir())){ + io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); + return RETVAL_INVALID_DIR; + } } return return_value; } +//Run get operation +int do_get(struct arg_values* args){ + for(;args;args = args->next){ + float curr, max; + if(chdir(args->device)){ + io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device); + return_value = RETVAL_INVALID_DIR; + continue; + } + curr = get_brightness(brightness_file()); + max = get_brightness(max_brightness_file()); + if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){ + fprintf(stdout, "%s", args->device); + }else{ + fprintf(stdout, "%-25s %.2f\n", args->device, curr / max * 100); + } + if(chdir(device_dir())){ + io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); + return RETVAL_INVALID_DIR; + } + } + return return_value; +} +//Run list operation +void do_list(struct arg_values* args){ + for(;args;args = args->next){ + printf("%s\n", args->device); + } +} + +//move next arg in src list to next arg in dest list +void extract_next_arg(struct arg_values* dest, struct arg_values* src){ + dest->next = src->next; + src->next = src->next->next; + dest->next->next = NULL; +} + #ifdef ENABLE_RESTORE_FILE -//If devices were specified, this function will run -void individual_device_loop(struct arg_values* a){ - struct arg_values* curr; +//convert all restore operations to set operations +void prep_restore(struct arg_values* a){ RJP_value* root = 0; int try_restore = 1; - for(curr = a->next;curr;curr = curr->next){ - if(curr->operation == OP_RESTORE){ - if(!individual_restore(curr, &root, &try_restore)) - continue; - } - return_value = individual_device_op(curr); - if(return_value == RETVAL_INTERNAL_ERROR){ - rjp_free_value(root); - return; - } + for(struct arg_values* curr = a;curr;curr = curr->next){ + restore_to_delta(curr, &root, &try_restore); } rjp_free_value(root); } #else -//If devices were specified, this function will run -void individual_device_loop(struct arg_values* a){ - struct arg_values* curr; - int try_restore = 1; - for(curr = a->next;curr;curr = curr->next){ - return_value = individual_device_op(curr); - if(return_value == RETVAL_INTERNAL_ERROR) - return; - } -} +#define prep_restore(x) #endif +//remove all args in src which have the specified operation and append them to dest +struct arg_values* extract_operation(int operation, struct arg_values* dest, struct arg_values* src){ + struct arg_values* curr_dest = dest; + dest->next = NULL; + for(struct arg_values* curr_src = src;curr_src->next;){ + if(curr_src->next->operation & operation){ + extract_next_arg(curr_dest, curr_src); + curr_dest = curr_dest->next; + }else{ + curr_src = curr_src->next; + } + } + return curr_dest; +} +//If devices were specified, this function will run +void run_device_operations(struct arg_values* a){ + struct arg_values* curr; + struct arg_values current_op_args = {0}; + //list + extract_operation(OP_LIST, ¤t_op_args, a); + do_list(current_op_args.next); + free_cmd_args(¤t_op_args); + + //get + extract_operation(OP_GET, ¤t_op_args, a); + return_value = do_get(current_op_args.next); + free_cmd_args(¤t_op_args); + + //assignment + curr = extract_operation(OP_RESTORE, ¤t_op_args, a); + prep_restore(current_op_args.next); + extract_operation(OP_SET | OP_INC | OP_DEC, curr, a); + return_value = do_assignment(current_op_args.next); + free_cmd_args(¤t_op_args); + +} + +//If a global operation is requested, run this to fill arg with all devices, each with the global operation void populate_args(struct arg_values* arg, struct string_array* devices){ struct arg_values* curr = arg; for(size_t i = 0;i < devices->size;++i){ @@ -295,6 +325,8 @@ void populate_args(struct arg_values* arg, struct string_array* devices){ curr->next = NULL; arg->num_values = devices->size; } + + int main(int argc, char** argv){ struct arg_values args; //A linked list of devices and the requested settings. @@ -344,12 +376,10 @@ int main(int argc, char** argv){ } //Run selected operation - if(args.next){ - individual_device_loop(&args); - }else{ + if(!args.next){ populate_args(&args, &device_names); - individual_device_loop(&args); } + run_device_operations(&args); #ifdef ENABLE_RESTORE_FILE save_restore_file(&device_names); #endif