X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=conout.c;h=9d0659b4b691c3a9f44fb1b011af5f514b608cf2;hp=aedff4da20b32e036fefd64ef4e3e0085d365546;hb=dc510baf4f2c8aeec289abf4abd81596c9fe7a8c;hpb=216330a7e27ad50d67b12ca76ba00f1c557913d7 diff --git a/conout.c b/conout.c index aedff4d..9d0659b 100644 --- a/conout.c +++ b/conout.c @@ -1,191 +1,17 @@ -/* - * Copyright (C) 2012, 2013 - * Dale Weiler - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ +#include #include "gmqcc.h" -/* - * isatty/STDERR_FILENO/STDOUT_FILNO - * + some other things likewise. - */ -#ifndef _WIN32 -# include -#else -# include - /* - * Windows and it's posix underscore bullshit. We simply fix this - * with yay, another macro :P - */ -# define isatty _isatty -#endif - -#define GMQCC_IS_STDOUT(X) ((FILE*)((void*)X) == stdout) -#define GMQCC_IS_STDERR(X) ((FILE*)((void*)X) == stderr) +#define GMQCC_IS_STDOUT(X) ((X) == stdout) +#define GMQCC_IS_STDERR(X) ((X) == stderr) #define GMQCC_IS_DEFINE(X) (GMQCC_IS_STDERR(X) || GMQCC_IS_STDOUT(X)) typedef struct { FILE *handle_err; FILE *handle_out; - - int color_err; - int color_out; + int color_err; + int color_out; } con_t; -/* - * Doing colored output on windows is fucking stupid. The linux way is - * the real way. So we emulate it on windows :) - */ -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include - -/* - * Windows doesn't have constants for FILENO, sadly but the docs tell - * use the constant values. - */ -#undef STDERR_FILENO -#undef STDOUT_FILENO -#define STDERR_FILENO 2 -#define STDOUT_FILENO 1 - -enum { - RESET = 0, - BOLD = 1, - BLACK = 30, - RED, - GREEN, - YELLOW, - BLUE, - MAGENTA, - CYAN, - GRAY, - WHITE = GRAY -}; - -enum { - WBLACK, - WBLUE, - WGREEN = 2, - WRED = 4, - WINTENSE = 8, - WCYAN = WBLUE | WGREEN, - WMAGENTA = WBLUE | WRED, - WYELLOW = WGREEN | WRED, - WWHITE = WBLUE | WGREEN | WRED -}; - -static const int ansi2win[] = { - WBLACK, - WRED, - WGREEN, - WYELLOW, - WBLUE, - WMAGENTA, - WCYAN, - WWHITE -}; - -static int win_fputs(FILE *h, const char *str) { - /* state for translate */ - int acolor = 0; - int wcolor = 0; - int icolor = 0; - 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)) ? - GetStdHandle(STD_OUTPUT_HANDLE) : - GetStdHandle(STD_ERROR_HANDLE), &cinfo - ); - icolor = cinfo.wAttributes; - - while (*str) { - if (*str == '\x1B') - state = '\x1B'; - else if (state == '\x1B' && *str == '[') - state = '['; - else if (state == '[') { - if (*str != 'm') { - colors[colorpos] = *str; - colorpos--; - } else { - int find; - int mult; - for (find = colorpos + 1, acolor = 0, mult = 1; find < 2; find++) { - acolor += (colors[find] - 48) * mult; - mult *= 10; - } - - /* convert to windows color */ - if (acolor == BOLD) - intense = WINTENSE; - else if (acolor == RESET) { - intense = WBLACK; - wcolor = icolor; - } - else if (BLACK <= acolor && acolor <= WHITE) - wcolor = ansi2win[acolor - 30]; - else if (acolor == 90) { - /* special gray really white man */ - wcolor = WWHITE; - intense = WBLACK; - } - - SetConsoleTextAttribute ( - (GMQCC_IS_STDOUT(h)) ? - GetStdHandle(STD_OUTPUT_HANDLE) : - GetStdHandle(STD_ERROR_HANDLE), - - wcolor | intense | (icolor & 0xF0) - ); - colorpos = 1; - state = -1; - } - } else { - fs_file_write(str, 1, 1, stdout); - length ++; - } - str++; - } - /* restore */ - SetConsoleTextAttribute( - (GMQCC_IS_STDOUT(h)) ? - GetStdHandle(STD_OUTPUT_HANDLE) : - GetStdHandle(STD_ERROR_HANDLE), - icolor - ); - return length; -} -#endif - -/* - * We use standard files as default. These can be changed at any time - * with con_change(F, F) - */ static con_t console; /* @@ -197,10 +23,8 @@ static con_t console; * checks. */ 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) - console.color_out = !!(isatty(STDOUT_FILENO)); + console.color_err = util_isatty(console.handle_err); + console.color_out = util_isatty(console.handle_out); } /* @@ -209,22 +33,7 @@ static void con_enablecolor(void) { * step. */ static int con_write(FILE *handle, const char *fmt, va_list va) { - int ln; - #ifndef _WIN32 - ln = vfprintf(handle, fmt, va); - #else - { - 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; + return vfprintf(handle, fmt, va); } /********************************************************************** @@ -233,9 +42,9 @@ static int con_write(FILE *handle, const char *fmt, va_list va) { void con_close() { if (!GMQCC_IS_DEFINE(console.handle_err)) - fs_file_close(console.handle_err); + fclose(console.handle_err); if (!GMQCC_IS_DEFINE(console.handle_out)) - fs_file_close(console.handle_out); + fclose(console.handle_out); } void con_color(int state) { @@ -255,36 +64,7 @@ void con_init() { void con_reset() { con_close(); - con_init (); -} - -/* - * This is clever, say you want to change the console to use two - * files for out/err. You pass in two strings, it will properly - * close the existing handles (if they're not std* handles) and - * open them. Now say you want TO use stdout and stderr, this - * allows you to do that so long as you cast them to (char*). - * Say you need stdout for out, but want a file for error, you can - * do this too, just cast the stdout for (char*) and stick to a - * string for the error file. - */ -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 = 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 = fs_file_open(err, "w"))) return 0; - - return 1; + con_init(); } /* @@ -292,10 +72,11 @@ int con_change(const char *out, const char *err) { * and inside file.c To prevent mis-match of wrapper-interfaces. */ FILE *con_default_out() { - return (console.handle_out = stdout); + return console.handle_out = stdout; } + FILE *con_default_err() { - return (console.handle_err = stderr); + return console.handle_err = stderr; } int con_verr(const char *fmt, va_list va) { @@ -310,23 +91,22 @@ int con_vout(const char *fmt, va_list va) { * to be used. */ int con_err(const char *fmt, ...) { - va_list va; - int ln = 0; + va_list va; + int ln = 0; va_start(va, fmt); con_verr(fmt, va); - va_end (va); - return ln; + va_end(va); + return ln; } int con_out(const char *fmt, ...) { - va_list va; - int ln = 0; + va_list va; + int ln = 0; va_start(va, fmt); con_vout(fmt, va); - va_end (va); - return ln; + va_end (va); + 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 @@ -340,10 +120,10 @@ static void con_vprintmsg_c(int level, const char *name, size_t line, size_t col CON_RED }; - int err = !!(level == LVL_ERROR); - int color = (err) ? console.color_err : console.color_out; - int (*print) (const char *, ...) = (err) ? &con_err : &con_out; - int (*vprint)(const char *, va_list) = (err) ? &con_verr : &con_vout; + int err = !!(level == LVL_ERROR); + int color = (err) ? console.color_err : console.color_out; + int (*print) (const char *, ...) = (err) ? &con_err : &con_out; + int (*vprint)(const char *, va_list) = (err) ? &con_verr : &con_vout; if (color) print("\033[0;%dm%s:%d:%d: \033[0;%dm%s: \033[0m", CON_CYAN, name, (int)line, (int)column, sel[level], msgtype); @@ -379,7 +159,7 @@ void con_cprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, va_end (va); } -/* General error interface */ +/* General error interface: TODO seperate as part of the compiler front-end */ size_t compile_errors = 0; size_t compile_warnings = 0; size_t compile_Werrors = 0; @@ -444,4 +224,3 @@ bool GMQCC_WARN compile_warning(lex_ctx_t ctx, int warntype, const char *fmt, .. va_end(ap); return r; } -#endif