/* * SPL - The SPL Programming Language * Copyright (C) 2004, 2005 Clifford Wolf * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * report.c: Functions for error-reporting */ #include #include #include #include #include "spl.h" #include "compat.h" spl_report_func *spl_report = spl_report_func_stderr; void spl_set_report_func(spl_report_func *f) { spl_report = f; } char *spl_report_type2txt(int type) { static char retbuf[100]; int i = 0; i += snprintf(retbuf+i, sizeof(retbuf)-i, "SPL"); if ( type & SPL_REPORT_DEBUG ) i += snprintf(retbuf+i, sizeof(retbuf)-i, " Debug"); else { if ( (type & 0x000f) == SPL_REPORT_ASSEMBLER ) i += snprintf(retbuf+i, sizeof(retbuf)-i, " Assembler"); if ( (type & 0x000f) == SPL_REPORT_COMPILER ) i += snprintf(retbuf+i, sizeof(retbuf)-i, " Compiler"); if ( (type & 0x000f) == SPL_REPORT_LEXER ) i += snprintf(retbuf+i, sizeof(retbuf)-i, " Lexer"); if ( (type & 0x000f) == SPL_REPORT_RUNTIME ) i += snprintf(retbuf+i, sizeof(retbuf)-i, " Runtime"); if ( (type & 0x000f) == SPL_REPORT_RESTORE ) i += snprintf(retbuf+i, sizeof(retbuf)-i, " Restore"); if ( type & SPL_REPORT_WARNING ) i += snprintf(retbuf+i, sizeof(retbuf)-i, " Warning"); else i += snprintf(retbuf+i, sizeof(retbuf)-i, " Error"); } return retbuf; } void spl_report_file(FILE *f, int type, void *desc, const char *fmt, va_list ap) { char *msg; my_vasprintf(&msg, fmt, ap); fprintf(f, "%s: %s", spl_report_type2txt(type), msg); free(msg); if ( (type & 0x000f) == SPL_REPORT_RUNTIME && desc && (type & SPL_REPORT_DEBUG) == 0) { struct spl_task *task = desc; if ((type & SPL_REPORT_WARNING) == 0) task->goterr = 1; spl_backtrace(task, f); } } char *spl_report_string(int type, void *desc, const char *fmt, va_list ap) { #if !defined USEWIN32API && !defined USECYGWINAPI && !defined USEMACOSXAPI && !defined USEBSDAPI && !defined USEIRIXAPI char *bp; size_t size; FILE *stream; stream = open_memstream(&bp, &size); spl_report_file(stream, type, desc, fmt, ap); fclose(stream); return bp; #else FILE *tempfile = tmpfile(); spl_report_file(tempfile, type, desc, fmt, ap); size_t size = ftell(tempfile); char *bp = malloc(size + 1); rewind(tempfile); fread(bp, size, 1, tempfile); bp[size] = 0; fclose(tempfile); return bp; #endif } void spl_report_func_stderr(int type, void *desc, const char *fmt, ...) { va_list ap; va_start(ap, fmt); spl_report_file(stderr, type, desc, fmt, ap); fflush(stderr); va_end(ap); } void spl_report_func_stdout(int type, void *desc, const char *fmt, ...) { va_list ap; va_start(ap, fmt); spl_report_file(stdout, type, desc, fmt, ap); fflush(stderr); va_end(ap); }