diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2020-10-03 16:25:48 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2020-12-29 19:02:57 +0100 |
commit | 58f1c9a91226f4954a4799fab082f186923aa806 (patch) | |
tree | ab137478c73bcb079e3031cbc65ecc7ef37f452e /src/libdebug/debug.c | |
parent | fde7cc2ce319bf294ded54da0822672fe33b1923 (diff) |
Add libraries from Osmocom-Analog
Diffstat (limited to 'src/libdebug/debug.c')
-rw-r--r-- | src/libdebug/debug.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/libdebug/debug.c b/src/libdebug/debug.c new file mode 100644 index 0000000..deb9656 --- /dev/null +++ b/src/libdebug/debug.c @@ -0,0 +1,224 @@ +/* Simple debug functions for level and category filtering + * + * (C) 2016 by Andreas Eversberg <jolly@eversberg.eu> + * All Rights Reserved + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <errno.h> +#include <math.h> +#include <sys/ioctl.h> +#include "debug.h" + +const char *debug_level[] = { + "debug ", + "info ", + "notice ", + "error ", + NULL, +}; + +struct debug_cat { + const char *name; + const char *color; +} debug_cat[] = { + { "options", "\033[0;33m" }, + { "dsp", "\033[0;31m" }, + { "wave", "\033[1;33m" }, + { "router", "\033[1;35m" }, + { "cc", "\033[1;32m" }, + { "stderr", "\033[1;37m" }, + { NULL, NULL } +}; + +int debuglevel = DEBUG_INFO; +uint64_t debug_mask = ~0; +extern int num_kanal; + +void (*clear_console_text)(void) = NULL; +void (*print_console_text)(void) = NULL; + +int debug_limit_scroll = 0; + +void get_win_size(int *w, int *h) +{ + struct winsize win; + int rc; + + rc = ioctl(0, TIOCGWINSZ, &win); + if (rc) { + *w = 80; + *h = 25; + return; + } + + *h = win.ws_row; + *w = win.ws_col; +} + +void _printdebug(const char *file, const char __attribute__((unused)) *function, int line, int cat, int level, const char *kanal, const char *fmt, ...) +{ + char buffer[4096], *b = buffer; + int s = sizeof(buffer) - 1; + const char *p; + va_list args; + int w, h; + + if (debuglevel > level) + return; + + buffer[sizeof(buffer) - 1] = '\0'; + + /* if kanal is used, prefix the channel number */ + if (num_kanal > 1 && kanal) { + sprintf(buffer, "(chan %s) ", kanal); + b = strchr(buffer, '\0'); + s -= strlen(buffer); + } + + if (!(debug_mask & ((uint64_t)1 << cat))) + return; + + va_start(args, fmt); + vsnprintf(b, s, fmt, args); + va_end(args); + + while ((p = strchr(file, '/'))) + file = p + 1; + if (clear_console_text) + clear_console_text(); + if (debug_limit_scroll) { + get_win_size(&w, &h); + printf("\0337\033[%d;%dr\0338", debug_limit_scroll + 1, h); + } + printf("%s%s:%4d %s: %s\033[0;39m", debug_cat[cat].color, file, line, debug_level[level], buffer); + if (debug_limit_scroll) + printf("\0337\033[%d;%dr\0338", 1, h); + if (print_console_text) + print_console_text(); + fflush(stdout); +} + +const char *debug_amplitude(double level) +{ + static char text[42]; + + strcpy(text, " : "); + if (level > 1.0) + level = 1.0; + if (level < -1.0) + level = -1.0; + text[20 + (int)(level * 20)] = '*'; + + return text; +} + +#define level2db(level) (20 * log10(level)) + +const char *debug_db(double level_db) +{ + static char text[128]; + int l; + + strcpy(text, ": . : . : . : . : . : . : . : . | . : . : . : . : . : . : . : . :"); + if (level_db <= 0.0) + return text; + l = (int)round(level2db(level_db)); + if (l > 48) + return text; + if (l < -48) + return text; + text[l + 48] = '*'; + + return text; +} + +void debug_list_cat(void) +{ + int i; + + printf("Give number of debug level:\n"); + for (i = 0; debug_level[i]; i++) + printf(" %d = %s\n", i, debug_level[i]); + printf("\n"); + + printf("Give name(s) of debug category:\n"); + for (i = 0; debug_cat[i].name; i++) + printf(" %s%s\033[0;39m\n", debug_cat[i].color, debug_cat[i].name); + printf("\n"); +} + +int parse_debug_opt(const char *optarg) +{ + int i, max_level = 0; + char *dstring, *p; + + for (i = 0; debug_level[i]; i++) + max_level = i; + + dstring = strdup(optarg); + p = strsep(&dstring, ","); + for (i = 0; i < p[i]; i++) { + if (p[i] < '0' || p[i] > '9') { + fprintf(stderr, "Only digits are allowed for debug level!\n"); + return -EINVAL; + } + } + debuglevel = atoi(p); + if (debuglevel > max_level) { + fprintf(stderr, "Debug level too high, use 'list' to show available levels!\n"); + return -EINVAL; + } + if (dstring) + debug_mask = 0; + while((p = strsep(&dstring, ","))) { + for (i = 0; debug_cat[i].name; i++) { + if (!strcasecmp(p, debug_cat[i].name)) + break; + } + if (!debug_cat[i].name) { + fprintf(stderr, "Given debug category '%s' unknown, use 'list' to show available categories!\n", p); + return -EINVAL; + } + debug_mask |= ((uint64_t)1 << i); + } + + return 0; +} + +const char *debug_hex(const uint8_t *data, int len) +{ + static char *text = NULL; + char *p; + int i; + + if (text) + free(text); + p = text = calloc(1, len * 3 + 1); + for (i = 0; i < len; i++) { + sprintf(p, "%02x ", *data++); + p += 3; + } + if (text[0]) + p[-1] = '\0'; + + return text; +} + |