X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=x5%2Fkhatus.c;h=ee96d60619c2af06a7d85f22ee5b2ee4a66827fe;hb=a6b13fa2d61136a971b2ebbf6eadb943002fa9d5;hp=ea63fa10e46571cb8014d541a9b78c849c0b958f;hpb=6626f8ba5e80ea4f84ff1d96e890e49f4b80c857;p=khatus.git diff --git a/x5/khatus.c b/x5/khatus.c index ea63fa1..ee96d60 100644 --- a/x5/khatus.c +++ b/x5/khatus.c @@ -15,9 +15,9 @@ #include "bsdtimespec.h" -#define debug(args...) {fprintf(stderr, "[debug] " args); fflush(stderr);} -#define info( args...) {fprintf(stderr, "[info] " args); fflush(stderr);} -#define error(args...) {fprintf(stderr, "[error] " args); fflush(stderr);} +#define debug(args...) if (cfg->log_level >= Debug) {fprintf(stderr, "[debug] " args); fflush(stderr);} +#define info( args...) if (cfg->log_level >= Info ) {fprintf(stderr, "[info] " args); fflush(stderr);} +#define error(args...) if (cfg->log_level >= Error) {fprintf(stderr, "[error] " args); fflush(stderr);} #define fatal(args...) {fprintf(stderr, "[fatal] " args); exit(EXIT_FAILURE);} #define usage(args...) {print_usage(); fatal("[usage] " args);} @@ -28,6 +28,13 @@ static const int errlen = sizeof(ERRMSG) - 1; char *argv0; +typedef enum LogLevel { + Nothing, + Error, + Info, + Debug +} LogLevel; + /* TODO: Convert fifo list to fifo array. */ typedef struct Fifo Fifo; struct Fifo { @@ -48,6 +55,7 @@ struct Config { int fifo_count; int total_width; int output_to_x_root_window; + LogLevel log_level; } defaults = { .interval = 1, .separator = "|", @@ -55,58 +63,60 @@ struct Config { .fifo_count = 0, .total_width = 0, .output_to_x_root_window = 0, + .log_level = Info, }; void -fifo_print_one(Fifo *f) +fifo_print_one(Fifo *f, Config *cfg) { - debug( - "Fifo " - "{" - " name = %s," - " fd = %d," - " width = %d," - " last_read = %d," - " ttl = %d," - " pos = %d," - " next = %p," - " }\n", - f->name, - f->fd, - f->width, - f->last_read, - f->ttl, - f->pos, - f->next + info("Fifo " + "{" + " name = %s," + " fd = %d," + " width = %d," + " last_read = %d," + " ttl = %d," + " pos = %d," + " next = %p," + " }\n", + f->name, + f->fd, + f->width, + f->last_read, + f->ttl, + f->pos, + f->next ); } void -fifo_print_all(Fifo *head) +fifo_print_all(Fifo *head, Config *cfg) { for (Fifo *f = head; f; f = f->next) { - fifo_print_one(f); + fifo_print_one(f, cfg); } } void -config_print(Config *c) +config_print(Config *cfg) { - debug( - "Config " - "{" - " interval = %d," - " separator = %s," - " fifo_count = %d," - " total_width = %d," - " fifos = ..." - " }\n", - c->interval, - c->separator, - c->fifo_count, - c->total_width + info( + "Config " + "{" + " interval = %d," + " separator = %s," + " fifo_count = %d," + " total_width = %d," + " log_level = %d," + " fifos = ..." + " }\n", + cfg->interval, + cfg->separator, + cfg->fifo_count, + cfg->total_width, + cfg->log_level ); - fifo_print_all(c->fifos); + fifo_print_all(cfg->fifos, cfg); } int @@ -123,26 +133,31 @@ print_usage() { assert(argv0); fprintf( - stderr, - "\n" - "Usage: %s [OPTION ...] SPEC [SPEC ...]\n" - "\n" - " SPEC = FILE_PATH DATA_WIDTH DATA_TTL\n" - " FILE_PATH = string\n" - " DATA_WIDTH = int (* (positive) number of characters *)\n" - " DATA_TTL = int (* (positive) number of seconds *)\n" - " OPTION = -i INTERVAL\n" - " | -s SEPARATOR\n" - " SEPARATOR = string\n" - " INTERVAL = int (* (positive) number of seconds *)\n" - "\n", - argv0 + stderr, + "\n" + "Usage: %s [OPTION ...] SPEC [SPEC ...]\n" + "\n" + " SPEC = FILE_PATH DATA_WIDTH DATA_TTL\n" + " FILE_PATH = string\n" + " DATA_WIDTH = int (* (positive) number of characters *)\n" + " DATA_TTL = int (* (positive) number of seconds *)\n" + " OPTION = -i INTERVAL\n" + " | -s SEPARATOR\n" + " | -x (* Output to X root window *)\n" + " | -l LOG_LEVEL\n" + " SEPARATOR = string\n" + " INTERVAL = int (* (positive) number of seconds *)\n" + " LOG_LEVEL = int (* %d through %d *)\n" + "\n", + argv0, + Nothing, + Debug ); fprintf( - stderr, - "Example: %s -i 1 /dev/shm/khatus/khatus_sensor_x 4 10\n" - "\n", - argv0 + stderr, + "Example: %s -i 1 /dev/shm/khatus/khatus_sensor_x 4 10\n" + "\n", + argv0 ); } @@ -151,50 +166,67 @@ void opts_parse_any(Config *, int, char *[], int); /* For mutually-recursive ca void parse_opts_opt_i(Config *cfg, int argc, char *argv[], int i) { - if (i < argc) { - char *param = argv[i++]; + char *param; - if (is_pos_num(param)) { - cfg->interval = atoi(param); - opts_parse_any(cfg, argc, argv, i); - } else { - usage("Option -i parameter is invalid: \"%s\"\n", param); - } - } else { + if (i >= argc) usage("Option -i parameter is missing.\n"); - } + param = argv[i++]; + if (!is_pos_num(param)) + usage("Option -i parameter is invalid: \"%s\"\n", param); + cfg->interval = atoi(param); + opts_parse_any(cfg, argc, argv, i); } void parse_opts_opt_s(Config *cfg, int argc, char *argv[], int i) { - if (i < argc) { - cfg->separator = calloc((strlen(argv[i]) + 1), sizeof(char)); - strcpy(cfg->separator, argv[i]); - opts_parse_any(cfg, argc, argv, ++i); - } else { + if (i >= argc) usage("Option -s parameter is missing.\n"); - } + cfg->separator = calloc((strlen(argv[i]) + 1), sizeof(char)); + strcpy(cfg->separator, argv[i]); + opts_parse_any(cfg, argc, argv, ++i); +} + +void +parse_opts_opt_l(Config *cfg, int argc, char *argv[], int i) +{ + char *param; + int log_level; + + if (i >= argc) + usage("Option -l parameter is missing.\n"); + param = argv[i++]; + if (!is_pos_num(param)) + usage("Option -l parameter is invalid: \"%s\"\n", param); + log_level = atoi(param); + if (log_level > Debug) + usage("Option -l value (%d) exceeds maximum (%d)\n", log_level, Debug); + cfg->log_level = log_level; + opts_parse_any(cfg, argc, argv, i); } void parse_opts_opt(Config *cfg, int argc, char *argv[], int i) { switch (argv[i][1]) { - case 'i': - /* TODO: Generic set_int */ - parse_opts_opt_i(cfg, argc, argv, ++i); - break; - case 's': - /* TODO: Generic set_str */ - parse_opts_opt_s(cfg, argc, argv, ++i); - break; - case 'x': - cfg->output_to_x_root_window = 1; - opts_parse_any(cfg, argc, argv, ++i); - break; - default : - usage("Option \"%s\" is invalid\n", argv[i]); + case 'i': + /* TODO: Generic set_int */ + parse_opts_opt_i(cfg, argc, argv, ++i); + break; + case 's': + /* TODO: Generic set_str */ + parse_opts_opt_s(cfg, argc, argv, ++i); + break; + case 'x': + cfg->output_to_x_root_window = 1; + opts_parse_any(cfg, argc, argv, ++i); + break; + case 'l': + /* TODO: Generic set_int */ + parse_opts_opt_l(cfg, argc, argv, ++i); + break; + default : + usage("Option \"%s\" is invalid\n", argv[i]); } } @@ -236,11 +268,11 @@ opts_parse_any(Config *cfg, int argc, char *argv[], int i) { if (i < argc) { switch (argv[i][0]) { - case '-': - parse_opts_opt(cfg, argc, argv, i); - break; - default : - parse_opts_spec(cfg, argc, argv, i); + case '-': + parse_opts_opt(cfg, argc, argv, i); + break; + default : + parse_opts_spec(cfg, argc, argv, i); } } } @@ -277,7 +309,7 @@ fifo_read_error(Fifo *f, char *buf) } void -fifo_read_one(Fifo *f, char *buf) +fifo_read_one(Fifo *f, char *buf, Config *cfg) { ssize_t current; ssize_t total; @@ -344,13 +376,13 @@ fifo_read_all(Config *cfg, char *buf) for (Fifo *f = cfg->fifos; f; f = f->next) { if (FD_ISSET(f->fd, &fds)) { debug("reading: %s\n", f->name); - fifo_read_one(f, buf); + fifo_read_one(f, buf, cfg); } } } void -snooze(struct timespec *t) +snooze(struct timespec *t, Config *cfg) { struct timespec remainder; int result; @@ -360,9 +392,9 @@ snooze(struct timespec *t) if (result < 0) { if (errno == EINTR) { info( - "nanosleep interrupted. Remainder: " - "{ tv_sec = %ld, tv_nsec = %ld }", - remainder.tv_sec, remainder.tv_nsec); + "nanosleep interrupted. Remainder: " + "{ tv_sec = %ld, tv_nsec = %ld }", + remainder.tv_sec, remainder.tv_nsec); /* No big deal if we occasionally sleep less, * so not attempting to correct after an interruption. */ @@ -473,7 +505,7 @@ main(int argc, char *argv[]) */ timespecsub(&ti, &td, &tc); debug("snooze YES\n"); - snooze(&tc); + snooze(&tc, cfg); } else debug("snooze NO\n"); }