]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - conout.c
Remove trailing whitespace
[xonotic/gmqcc.git] / conout.c
index 2c9962d4a50329cc588e4f14934150c6ed35eca6..7e8cd9ad8f40a4c5768db4d52ae308184c357b42 100644 (file)
--- 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
@@ -21,6 +21,7 @@
  * SOFTWARE.
  */
 #include "gmqcc.h"
+#include <stdio.h>
 
 /*
  * isatty/STDERR_FILENO/STDOUT_FILNO
@@ -53,7 +54,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 <windows.h>
 
@@ -77,7 +78,7 @@ enum {
     MAGENTA,
     CYAN,
     GRAY,
-    WHITE
+    WHITE = GRAY
 };
 
 enum {
@@ -90,9 +91,9 @@ enum {
     WMAGENTA = WBLUE  | WRED,
     WYELLOW  = WGREEN | WRED,
     WWHITE   = WBLUE  | WGREEN | WRED
-}
+};
 
-static const ansi2win[] = {
+static const int ansi2win[] = {
     WBLACK,
     WRED,
     WGREEN,
@@ -103,20 +104,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;
 
     /* 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 +126,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 +149,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 +158,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 +168,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 +180,7 @@ static void win_fputs(char *str, FILE *h) {
         GetStdHandle(STD_ERROR_HANDLE),
         icolor
     );
+    return length;
 }
 #endif
 
@@ -209,20 +212,14 @@ 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));
+        vsnprintf(data, sizeof(data), fmt, va);
+        ln = (GMQCC_IS_DEFINE(handle)) ? win_fputs(handle, data) : fs_file_puts(handle, data);
     }
     #endif
     return ln;
@@ -234,9 +231,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 +269,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);
 }
@@ -373,6 +380,14 @@ void con_cprintmsg (void *ctx, int lvl, const char *msgtype, const char *msg, ..
 size_t compile_errors = 0;
 size_t compile_warnings = 0;
 
+size_t compile_Werrors = 0;
+static lex_ctx first_werror;
+
+void compile_show_werrors()
+{
+    con_cprintmsg((void*)&first_werror, LVL_ERROR, "first warning", "was here");
+}
+
 void vcompile_error(lex_ctx ctx, const char *msg, va_list ap)
 {
     ++compile_errors;
@@ -389,8 +404,9 @@ void compile_error(lex_ctx ctx, const char *msg, ...)
 
 bool GMQCC_WARN vcompile_warning(lex_ctx 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,16 +415,22 @@ 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);
 
+    ++compile_warnings;
     if (OPTS_WERROR(warntype)) {
-        ++compile_errors;
+        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, msgtype, fmt, ap, warn_name);
 
-    return OPTS_WERROR(warntype);
+    return OPTS_WERROR(warntype) && OPTS_FLAG(BAIL_ON_WERROR);
 }
 
 bool GMQCC_WARN compile_warning(lex_ctx ctx, int warntype, const char *fmt, ...)