]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - conout.c
Minifi README
[xonotic/gmqcc.git] / conout.c
index f89d68c13ec10b2b71e681f60f007f3f0d0f61bd..0ee110b8f584c483da389f141d2a7f888955f6b1 100644 (file)
--- a/conout.c
+++ b/conout.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013
+ * Copyright (C) 2012, 2013, 2014, 2015
  *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+#include <stdio.h>
 #include "gmqcc.h"
 
-/*
- * isatty/STDERR_FILENO/STDOUT_FILNO
- * + some other things likewise.
- */
-#ifndef _WIN32
-#   include <unistd.h>
-#else
-#   include <io.h>
-    /*
-     * 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.h>
-
-/*
- * 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 +45,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,18 +55,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));
-        platform_vsnprintf(data, sizeof(data), fmt, va);
-        ln = (GMQCC_IS_DEFINE(handle)) ? win_fputs(handle, data) : fs_file_puts(handle, data);
-    }
-    #endif
-    return ln;
+    return vfprintf(handle, fmt, va);
 }
 
 /**********************************************************************
@@ -229,9 +64,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) {
@@ -251,36 +86,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();
 }
 
 /*
@@ -288,10 +94,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) {
@@ -306,20 +113,20 @@ 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;
 }
 
 /*
@@ -335,10 +142,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);
@@ -374,8 +181,7 @@ void con_cprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg,
     va_end  (va);
 }
 
-#ifndef QCVM_EXECUTOR
-/* 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;
@@ -440,4 +246,3 @@ bool GMQCC_WARN compile_warning(lex_ctx_t ctx, int warntype, const char *fmt, ..
     va_end(ap);
     return r;
 }
-#endif