/* This file is part of Eclat. Copyright (C) 2012-2015 Sergey Poznyakoff. Eclat 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, or (at your option) any later version. Eclat 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 Eclat. If not, see . */ #include "libeclat.h" #include #include const char *program_name; struct debug_category debug_category[LIBECLAT_DBG_MAX]; int debug_avail; void set_program_name(const char *arg) { program_name = strrchr(arg, '/'); if (!program_name) program_name = arg; else program_name++; } void vdiag(grecs_locus_t const *locus, const char *qual, const char *fmt, va_list ap) { if (program_name) fprintf(stderr, "%s: ", program_name); if (locus) { if (locus->beg.col == 0) fprintf(stderr, "%s:%u", locus->beg.file, locus->beg.line); else if (strcmp(locus->beg.file, locus->end.file)) fprintf(stderr, "%s:%u.%u-%s:%u.%u", locus->beg.file, locus->beg.line, locus->beg.col, locus->end.file, locus->end.line, locus->end.col); else if (locus->beg.line != locus->end.line) fprintf(stderr, "%s:%u.%u-%u.%u", locus->beg.file, locus->beg.line, locus->beg.col, locus->end.line, locus->end.col); else fprintf(stderr, "%s:%u.%u-%u", locus->beg.file, locus->beg.line, locus->beg.col, locus->end.col); fprintf(stderr, ": "); } if (qual) fprintf(stderr, "%s: ", qual); vfprintf(stderr, fmt, ap); fputc('\n', stderr); } void diag(grecs_locus_t const *locus, const char *qual, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vdiag(locus, qual, fmt, ap); va_end(ap); } void die(int status, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vdiag(NULL, NULL, fmt, ap); va_end(ap); exit(status); } void err(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vdiag(NULL, NULL, fmt, ap); va_end(ap); } void warn(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vdiag(NULL, "warning", fmt, ap); va_end(ap); } void debug_printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vdiag(NULL, "debug", fmt, ap); va_end(ap); } static struct debug_category * find_category(const char *arg, size_t len) { struct debug_category *dp; for (dp = debug_category; dp < debug_category + debug_avail; dp++) if (dp->length == len && memcmp(dp->name, arg, len) == 0) return dp; return NULL; } int parse_debug_level(const char *arg) { unsigned long lev; char *p; size_t len = strcspn(arg, "."); struct debug_category *dp; if (arg[len] == 0) { lev = strtoul(arg, &p, 10); if (*p == 0) { for (dp = debug_category; dp < debug_category + debug_avail; dp++) dp->level = lev; return 0; } } dp = find_category(arg, len); if (!dp) return -1; p = (char*) arg + len; if (*p == 0) lev = 100; else if (*p != '.') return -1; else { lev = strtoul(p + 1, &p, 10); if (*p) return -1; } dp->level = lev; return 0; } int debug_register(char *name) { if (debug_avail >= LIBECLAT_DBG_MAX) die(EX_SOFTWARE, "no more debug slots available"); debug_category[debug_avail].name = grecs_strdup(name); debug_category[debug_avail].length = strlen(name); debug_category[debug_avail].level = 0; return debug_avail++; }