X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=conout.c;h=93c1ff832a9cabb70dcfe5c09fcb044cf6f9b1ed;hp=3fca6ef76fbdd8a576e85beaec822e700581e704;hb=6f749d61b1688752bb902efd635f55d584ad7087;hpb=0f0a458cc44130ed02161f7fb492372ffa9a00d9 diff --git a/conout.c b/conout.c index 3fca6ef..93c1ff8 100644 --- a/conout.c +++ b/conout.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 + * Copyright (C) 2012, 2013 * Dale Weiler * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -53,7 +53,7 @@ typedef struct { * Doing colored output on windows is fucking stupid. The linux way is * the real way. So we emulate it on windows :) */ -#ifdef _MSC_VER +#ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include @@ -77,7 +77,7 @@ enum { MAGENTA, CYAN, GRAY, - WHITE + WHITE = GRAY }; enum { @@ -90,9 +90,9 @@ enum { WMAGENTA = WBLUE | WRED, WYELLOW = WGREEN | WRED, WWHITE = WBLUE | WGREEN | WRED -} +}; -static const ansi2win[] = { +static const int ansi2win[] = { WBLACK, WRED, WGREEN, @@ -103,20 +103,19 @@ static const ansi2win[] = { WWHITE }; -static void win_fputs(char *str, FILE *h) { +static int win_fputs(FILE *h, const char *str) { /* state for translate */ int acolor; int wcolor; int icolor; - int state; - int place; + int state = 0; /* attributes */ int intense = -1; int colors[] = {-1, -1 }; int colorpos = 1; - + int length = 0; CONSOLE_SCREEN_BUFFER_INFO cinfo; GetConsoleScreenBufferInfo ( (GMQCC_IS_STDOUT(h)) ? @@ -126,9 +125,9 @@ static void win_fputs(char *str, FILE *h) { icolor = cinfo.wAttributes; while (*str) { - if (*str == '\e') - state = '\e'; - else if (state == '\e' && *str == '[') + if (*str == '\x1B') + state = '\x1B'; + else if (state == '\x1B' && *str == '[') state = '['; else if (state == '[') { if (*str != 'm') { @@ -149,7 +148,7 @@ static void win_fputs(char *str, FILE *h) { intense = WBLACK; wcolor = icolor; } - else if (BLACK < acolor && acolor <= WHITE) + else if (BLACK <= acolor && acolor <= WHITE) wcolor = ansi2win[acolor - 30]; else if (acolor == 90) { /* special gray really white man */ @@ -158,7 +157,7 @@ static void win_fputs(char *str, FILE *h) { } SetConsoleTextAttribute ( - (h == stdout) ? + (GMQCC_IS_STDOUT(h)) ? GetStdHandle(STD_OUTPUT_HANDLE) : GetStdHandle(STD_ERROR_HANDLE), @@ -168,8 +167,10 @@ static void win_fputs(char *str, FILE *h) { state = -1; } } else { - fputc(*str, h); + fs_file_write(str, 1, 1, stdout); + length ++; } + str++; } /* restore */ SetConsoleTextAttribute( @@ -178,6 +179,7 @@ static void win_fputs(char *str, FILE *h) { GetStdHandle(STD_ERROR_HANDLE), icolor ); + return length; } #endif @@ -195,7 +197,7 @@ static con_t console; * NOTE: This prevents colored output to piped stdout/err via isatty * checks. */ -static void con_enablecolor() { +static void con_enablecolor(void) { if (console.handle_err == stderr || console.handle_err == stdout) console.color_err = !!(isatty(STDERR_FILENO)); if (console.handle_out == stderr || console.handle_out == stdout) @@ -209,20 +211,18 @@ static void con_enablecolor() { */ static int con_write(FILE *handle, const char *fmt, va_list va) { int ln; - #ifndef _MSC_VER + #ifndef _WIN32 ln = vfprintf(handle, fmt, va); #else { - char *data = NULL; - ln = _vscprintf(fmt, va); - data = malloc(ln + 1); - data[ln] = 0; - vsprintf(data, fmt, va); - if (GMQCC_IS_DEFINE(handle)) - ln = win_fputs(data, handle); - else - ln = fputs(data, handle); - free(data); + char data[4096]; + memset(data, 0, sizeof(data)); +#ifdef _MSC_VER + vsnprintf_s(data, sizeof(data), sizeof(data), fmt, va); +#else + vsnprintf(data, sizeof(data), fmt, va); +#endif + ln = (GMQCC_IS_DEFINE(handle)) ? win_fputs(handle, data) : fs_file_puts(handle, data); } #endif return ln; @@ -234,9 +234,9 @@ static int con_write(FILE *handle, const char *fmt, va_list va) { void con_close() { if (!GMQCC_IS_DEFINE(console.handle_err)) - fclose(console.handle_err); + fs_file_close(console.handle_err); if (!GMQCC_IS_DEFINE(console.handle_out)) - fclose(console.handle_out); + fs_file_close(console.handle_out); } void con_color(int state) { @@ -272,23 +272,33 @@ void con_reset() { int con_change(const char *out, const char *err) { con_close(); + if (!out) out = (const char *)((!console.handle_out) ? stdout : console.handle_out); + if (!err) err = (const char *)((!console.handle_err) ? stderr : console.handle_err); + if (GMQCC_IS_DEFINE(out)) { console.handle_out = GMQCC_IS_STDOUT(out) ? stdout : stderr; con_enablecolor(); - } else if (!(console.handle_out = fopen(out, "w"))) return 0; + } else if (!(console.handle_out = fs_file_open(out, "w"))) return 0; if (GMQCC_IS_DEFINE(err)) { console.handle_err = GMQCC_IS_STDOUT(err) ? stdout : stderr; con_enablecolor(); - } else if (!(console.handle_err = fopen(err, "w"))) return 0; - - /* no buffering */ - setvbuf(console.handle_out, NULL, _IONBF, 0); - setvbuf(console.handle_err, NULL, _IONBF, 0); + } else if (!(console.handle_err = fs_file_open(err, "w"))) return 0; return 1; } +/* + * Defaultizer because stdio.h shouldn't be used anywhere except here + * and inside file.c To prevent mis-match of wrapper-interfaces. + */ +FILE *con_default_out() { + return (console.handle_out = stdout); +} +FILE *con_default_err() { + return (console.handle_err = stderr); +} + int con_verr(const char *fmt, va_list va) { return con_write(console.handle_err, fmt, va); } @@ -317,12 +327,13 @@ int con_out(const char *fmt, ...) { return ln; } +#ifndef QCVM_EXECUTOR /* * Utility console message writes for lexer contexts. These will allow * for reporting of file:line based on lexer context, These are used * heavily in the parser/ir/ast. */ -void con_vprintmsg_c(int level, const char *name, size_t line, const char *msgtype, const char *msg, va_list ap, const char *condname) { +static void con_vprintmsg_c(int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap, const char *condname) { /* color selection table */ static int sel[] = { CON_WHITE, @@ -336,9 +347,9 @@ void con_vprintmsg_c(int level, const char *name, size_t line, const char *msgty int (*vprint)(const char *, va_list) = (err) ? &con_verr : &con_vout; if (color) - print("\033[0;%dm%s:%d: \033[0;%dm%s: \033[0m", CON_CYAN, name, (int)line, sel[level], msgtype); + print("\033[0;%dm%s:%d:%d: \033[0;%dm%s: \033[0m", CON_CYAN, name, (int)line, (int)column, sel[level], msgtype); else - print("%s:%d: %s: ", name, (int)line, msgtype); + print("%s:%d:%d: %s: ", name, (int)line, (int)column, msgtype); vprint(msg, ap); if (condname) @@ -347,22 +358,22 @@ void con_vprintmsg_c(int level, const char *name, size_t line, const char *msgty print("\n"); } -void con_vprintmsg(int level, const char *name, size_t line, const char *msgtype, const char *msg, va_list ap) { - con_vprintmsg_c(level, name, line, msgtype, msg, ap, NULL); +void con_vprintmsg(int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap) { + con_vprintmsg_c(level, name, line, column, msgtype, msg, ap, NULL); } -void con_printmsg(int level, const char *name, size_t line, const char *msgtype, const char *msg, ...) { +void con_printmsg(int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, ...) { va_list va; va_start(va, msg); - con_vprintmsg(level, name, line, msgtype, msg, va); + con_vprintmsg(level, name, line, column, msgtype, msg, va); va_end (va); } -void con_cvprintmsg(void *ctx, int lvl, const char *msgtype, const char *msg, va_list ap) { - con_vprintmsg(lvl, ((lex_ctx*)ctx)->file, ((lex_ctx*)ctx)->line, msgtype, msg, ap); +void con_cvprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, va_list ap) { + con_vprintmsg(lvl, ctx.file, ctx.line, ctx.column, msgtype, msg, ap); } -void con_cprintmsg (void *ctx, int lvl, const char *msgtype, const char *msg, ...) { +void con_cprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, ...) { va_list va; va_start(va, msg); con_cvprintmsg(ctx, lvl, msgtype, msg, va); @@ -370,16 +381,23 @@ void con_cprintmsg (void *ctx, int lvl, const char *msgtype, const char *msg, .. } /* General error interface */ -size_t compile_errors = 0; +size_t compile_errors = 0; size_t compile_warnings = 0; +size_t compile_Werrors = 0; +static lex_ctx_t first_werror; + +void compile_show_werrors() +{ + con_cprintmsg(first_werror, LVL_ERROR, "first warning", "was here"); +} -void vcompile_error(lex_ctx ctx, const char *msg, va_list ap) +void vcompile_error(lex_ctx_t ctx, const char *msg, va_list ap) { ++compile_errors; - con_cvprintmsg((void*)&ctx, LVL_ERROR, "error", msg, ap); + con_cvprintmsg(ctx, LVL_ERROR, "error", msg, ap); } -void compile_error(lex_ctx ctx, const char *msg, ...) +void compile_error(lex_ctx_t ctx, const char *msg, ...) { va_list ap; va_start(ap, msg); @@ -387,10 +405,11 @@ void compile_error(lex_ctx ctx, const char *msg, ...) va_end(ap); } -bool GMQCC_WARN vcompile_warning(lex_ctx ctx, int warntype, const char *fmt, va_list ap) +bool GMQCC_WARN vcompile_warning(lex_ctx_t ctx, int warntype, const char *fmt, va_list ap) { - int lvl = LVL_WARNING; - char warn_name[1024]; + const char *msgtype = "warning"; + int lvl = LVL_WARNING; + char warn_name[1024]; if (!OPTS_WARN(warntype)) return false; @@ -399,19 +418,25 @@ bool GMQCC_WARN vcompile_warning(lex_ctx ctx, int warntype, const char *fmt, va_ warn_name[1] = 'W'; (void)util_strtononcmd(opts_warn_list[warntype].name, warn_name+2, sizeof(warn_name)-2); - if (opts.werror) { - ++compile_errors; + ++compile_warnings; + if (OPTS_WERROR(warntype)) { + if (!compile_Werrors) + first_werror = ctx; + ++compile_Werrors; + msgtype = "Werror"; + if (OPTS_FLAG(BAIL_ON_WERROR)) { + msgtype = "error"; + ++compile_errors; + } lvl = LVL_ERROR; } - else - ++compile_warnings; - con_vprintmsg_c(lvl, ctx.file, ctx.line, (opts.werror ? "error" : "warning"), fmt, ap, warn_name); + con_vprintmsg_c(lvl, ctx.file, ctx.line, ctx.column, msgtype, fmt, ap, warn_name); - return opts.werror; + return OPTS_WERROR(warntype) && OPTS_FLAG(BAIL_ON_WERROR); } -bool GMQCC_WARN compile_warning(lex_ctx ctx, int warntype, const char *fmt, ...) +bool GMQCC_WARN compile_warning(lex_ctx_t ctx, int warntype, const char *fmt, ...) { bool r; va_list ap; @@ -420,3 +445,4 @@ bool GMQCC_WARN compile_warning(lex_ctx ctx, int warntype, const char *fmt, ...) va_end(ap); return r; } +#endif