Preprocessor is cool

This commit is contained in:
rexy712 2018-01-18 15:17:58 -08:00
parent e4b58545b5
commit b8df3dc3ed

View File

@ -24,6 +24,23 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#define OP_INC 1
#define OP_DEC 2
#define OP_SET 4
#define OP_GET 128
#define OP_NONE 0
#define GET_LONG_OPT "--get"
#define GET_SHORT_OPT "-g"
#define FADE_LONG_OPT "--fade"
#define FADE_SHORT_OPT "-f"
#define DEVICE_LONG_OPT "--device"
#define DEVICE_SHORT_OPT "-d"
#define HELP_LONG_OPT "--help"
#define HELP_SHORT_OPT "-h"
#define CHECK_OPTION(opt, arg) (!strcmp(opt##_LONG_OPT, arg) || !strcmp(opt##_SHORT_OPT, arg))
//This is where backlight devices can be found in sysfs //This is where backlight devices can be found in sysfs
static const char* backlight_dir = "/sys/class/backlight/"; static const char* backlight_dir = "/sys/class/backlight/";
@ -170,11 +187,6 @@ int process_arg(char* arg, float min, float current, float max){
return current; return current;
} }
#define OP_INC 1
#define OP_DEC 2
#define OP_SET 4
#define OP_GET 128
#define OP_NONE 0
struct arg_values{ struct arg_values{
struct arg_values* next; struct arg_values* next;
@ -198,49 +210,57 @@ void free_cmd_args(struct arg_values* a){
free(a->next); free(a->next);
} }
#define CHECK_NEXT_ARG(rval) \
do{ \
if(i == argc - 1){ \
fprintf(stderr, "Missing argument to '%s'\n\n", argv[i]); \
free_cmd_args(&ret); \
usage(rval); \
} \
}while(0)
#define UNRECOGNIZED_OPTION(rval) \
do{ \
fprintf(stderr, "Unrecognized command line option '%s'\n\n", argv[i]); \
free_cmd_args(&ret); \
usage(rval); \
}while(0);
struct arg_values process_cmd_args(int argc, char** argv){ struct arg_values process_cmd_args(int argc, char** argv){
struct arg_values ret = {0}; struct arg_values ret = {0};
struct arg_values* curr = &ret; struct arg_values* curr = &ret;
//Skip argv[0] //Skip argv[0]
for(int i = 1;i < argc;i++){ for(int i = 1;i < argc;i++){
if(!strncmp(argv[i], "--", 2)){
if(!strcmp(argv[i] + 2, "get")){
curr->operation |= OP_GET;
continue;
}else if(!strcmp(argv[i] + 2, "fade")){ //Check for switches
if(i == argc){ if(CHECK_OPTION(GET, argv[i])){
fprintf(stderr, "Missing argument to %s\n\n", argv[i]); curr->operation |= OP_GET;
free_cmd_args(&ret); continue;
usage(-5);
}
curr->fade_duration = strtol(argv[++i], NULL, 0);
continue;
}
else if(!strcmp(argv[i] + 2, "device")){ }else if(CHECK_OPTION(FADE, argv[i])){
if(i == argc){ CHECK_NEXT_ARG(-5);
fprintf(stderr, "Missing argument to %s\n\n", argv[i]); curr->fade_duration = strtol(argv[++i], NULL, 0);
free_cmd_args(&ret); continue;
usage(-5);
}
curr->next = calloc(1, sizeof(struct arg_values));
curr = curr->next;
curr->device = argv[++i];
continue;
}
else if(!strcmp(argv[i] + 2, "help")){
free_cmd_args(&ret);
usage(0);
}
else{
fprintf(stderr, "Unrecognized command line option '%s'\n\n", argv[i]);
free_cmd_args(&ret);
usage(-5);
}
} }
else if(CHECK_OPTION(DEVICE, argv[i])){
CHECK_NEXT_ARG(-5);
curr->next = calloc(1, sizeof(struct arg_values));
curr = curr->next;
curr->device = argv[++i];
continue;
}
else if(CHECK_OPTION(HELP, argv[i])){
free_cmd_args(&ret);
usage(0);
}
//If we get a '-' followed by not a number, it's not a known option
else if(argv[i][1] < '0' || argv[i][1] > '9'){
UNRECOGNIZED_OPTION(-4);
}
//If we get a '-' followed by a number, it's a decrement request
else{ else{
switch(argv[i][0]){ switch(argv[i][0]){
case '=': case '=':
@ -253,24 +273,26 @@ struct arg_values process_cmd_args(int argc, char** argv){
curr->operation = OP_INC; curr->operation = OP_INC;
break; break;
default: default:
fprintf(stderr, "Unrecognized command line option '%s'\n\n", argv[i]); UNRECOGNIZED_OPTION(-4);
free_cmd_args(&ret);
usage(-5);
} }
curr->delta = atof(&argv[i][1]); curr->delta = atof(&argv[i][1]);
} }
} }
//If there isn't an operation defined in the global context and there is no specified device, there's nothing to do
if(!ret.operation){ if(!ret.operation){
if(!ret.next){ if(!ret.next){
fprintf(stderr, "No operation requested!\n\n"); fprintf(stderr, "No operation requested!\n\n");
usage(-1); usage(-1);
} }
//if there is a device specified, make sure each one has a requested operation
for(curr = ret.next;curr;curr = curr->next){ for(curr = ret.next;curr;curr = curr->next){
if(!curr->operation){ if(!curr->operation){
fprintf(stderr, "No operation requested for device %s!\n\n", curr->device); fprintf(stderr, "No operation requested for device '%s'!\n\n", curr->device);
usage(-1); usage(-1);
} }
} }
//If there is a globally defined operation, apply it to the devices with no operation request
}else{ }else{
for(curr = ret.next;curr;curr = curr->next){ for(curr = ret.next;curr;curr = curr->next){
if(!curr->operation) if(!curr->operation)
@ -279,6 +301,8 @@ struct arg_values process_cmd_args(int argc, char** argv){
} }
return ret; return ret;
} }
#undef CHECK_OPTION
#undef UNRECOGNIZED_OPTION
//argv[1] shall be [+-=]<percentage>|min|max|off //argv[1] shall be [+-=]<percentage>|min|max|off
int main(int argc, char** argv){ int main(int argc, char** argv){