Oh my god microsoft you suck
authorDale Weiler <killfieldengine@gmail.com>
Thu, 20 Jun 2013 11:20:56 +0000 (11:20 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Thu, 20 Jun 2013 11:20:56 +0000 (11:20 +0000)
gmqcc.h
lexer.c
main.c
opts.c
stat.c
util.c

diff --git a/gmqcc.h b/gmqcc.h
index b1da366..593ab81 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -305,6 +305,28 @@ void *stat_mem_allocate  (size_t, size_t, const char *);
 /*===================================================================*/
 /*=========================== util.c ================================*/
 /*===================================================================*/
+
+/*
+ * Microsoft implements against the spec versions of ctype.h. Which
+ * means what ever the current set locale is will render the actual
+ * results of say isalpha('A') wrong for what ever retarded locale
+ * is used. Simalerly these are also implemented inefficently on
+ * some toolchains and end up becoming actual library calls. Perhaps
+ * this is why tools like yacc provide their own? Regardless implementing
+ * these as functions is equally as silly, the call overhead is not
+ * justified when this could happen on every character from an input
+ * stream. We provide our own as macros for absolute inlinability.
+ */
+#define util_isupper(C) ((C) >= 'A' && (C) <= 'Z')
+#define util_islower(C) ((C) >= 'a' && (C) <= 'z')
+#define util_isdigit(C) ((C) >= '0' && (C) <= '9')
+#define util_isprint(C) ((C) >= 32  && (C) <= 126)
+#define util_isspace(C) ((C) == ' ' || (C) == '\f' || \
+                         (C) == '\n'|| (C) == '\r' || \
+                         (C) == '\t'|| (C) == '\v')
+
+#define util_isalpha(C) (util_islower(C) || util_isupper(C))
+
 bool  util_filexists     (const char *);
 bool  util_strupper      (const char *);
 bool  util_strdigit      (const char *);
diff --git a/lexer.c b/lexer.c
index 7cd7794..ac230b6 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -20,7 +20,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -388,12 +387,12 @@ static void lex_ungetch(lex_file *lex, int ch)
 /* Idents are alphanumberic, but they start with alpha or _ */
 static bool isident_start(int ch)
 {
-    return isalpha(ch) || ch == '_';
+    return util_isalpha(ch) || ch == '_';
 }
 
 static bool isident(int ch)
 {
-    return isident_start(ch) || isdigit(ch);
+    return isident_start(ch) || util_isdigit(ch);
 }
 
 /* isxdigit_only is used when we already know it's not a digit
@@ -573,7 +572,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite)
     do
     {
         ch = lex_getch(lex);
-        while (ch != EOF && isspace(ch)) {
+        while (ch != EOF && util_isspace(ch)) {
             if (ch == '\n') {
                 if (lex_try_pragma(lex))
                     continue;
@@ -671,7 +670,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite)
             ch = '/';
             break;
         }
-    } while (ch != EOF && isspace(ch));
+    } while (ch != EOF && util_isspace(ch));
 
     if (haswhite) {
         lex_endtoken(lex);
@@ -707,7 +706,7 @@ static int lex_parse_frame(lex_file *lex)
     lex_token_new(lex);
 
     ch = lex_getch(lex);
-    while (ch != EOF && ch != '\n' && isspace(ch))
+    while (ch != EOF && ch != '\n' && util_isspace(ch))
         ch = lex_getch(lex);
 
     if (ch == '\n')
@@ -929,7 +928,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch)
     lex_tokench(lex, ch);
 
     ch = lex_getch(lex);
-    if (ch != '.' && !isdigit(ch))
+    if (ch != '.' && !util_isdigit(ch))
     {
         if (lastch != '0' || ch != 'x')
         {
@@ -950,7 +949,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch)
     {
         lex_tokench(lex, ch);
         ch = lex_getch(lex);
-        while (isdigit(ch) || (ishex && isxdigit_only(ch)))
+        while (util_isdigit(ch) || (ishex && isxdigit_only(ch)))
         {
             lex_tokench(lex, ch);
             ch = lex_getch(lex);
@@ -965,7 +964,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch)
 
         /* continue digits-only */
         ch = lex_getch(lex);
-        while (isdigit(ch))
+        while (util_isdigit(ch))
         {
             lex_tokench(lex, ch);
             ch = lex_getch(lex);
@@ -1068,10 +1067,10 @@ int lex_do(lex_file *lex)
         if (!strcmp(v, "framevalue"))
         {
             ch = lex_getch(lex);
-            while (ch != EOF && isspace(ch) && ch != '\n')
+            while (ch != EOF && util_isspace(ch) && ch != '\n')
                 ch = lex_getch(lex);
 
-            if (!isdigit(ch)) {
+            if (!util_isdigit(ch)) {
                 lexerror(lex, "$framevalue requires an integer parameter");
                 return lex_do(lex);
             }
@@ -1229,7 +1228,7 @@ int lex_do(lex_file *lex)
     if (ch == '.') {
         nextch = lex_getch(lex);
         /* digits starting with a dot */
-        if (isdigit(nextch)) {
+        if (util_isdigit(nextch)) {
             lex_ungetch(lex, nextch);
             lex->tok.ttype = lex_finish_digit(lex, ch);
             lex_endtoken(lex);
@@ -1337,7 +1336,7 @@ int lex_do(lex_file *lex)
             }
         }
         else if (lex->flags.preprocessing &&
-                 ch == '-' && isdigit(nextch))
+                 ch == '-' && util_isdigit(nextch))
         {
             lex->tok.ttype = lex_finish_digit(lex, nextch);
             if (lex->tok.ttype == TOKEN_INTCONST)
@@ -1504,7 +1503,7 @@ int lex_do(lex_file *lex)
         return lex->tok.ttype;
     }
 
-    if (isdigit(ch))
+    if (util_isdigit(ch))
     {
         lex->tok.ttype = lex_finish_digit(lex, ch);
         lex_endtoken(lex);
diff --git a/main.c b/main.c
index 98de0e9..bcd9159 100644 (file)
--- a/main.c
+++ b/main.c
@@ -25,8 +25,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-
 
 #include "gmqcc.h"
 #include "lexer.h"
@@ -413,7 +411,7 @@ static bool options_parse(int argc, char **argv) {
                         con_out("option -O requires a numerical argument, or optimization name with an optional 'no-' prefix\n");
                         return false;
                     }
-                    if (isdigit(argarg[0])) {
+                    if (util_isdigit(argarg[0])) {
                         uint32_t val = (uint32_t)strtol(argarg, NULL, 10);
                         OPTS_OPTION_U32(OPTION_O) = val;
                         opts_setoptimlevel(val);
@@ -538,9 +536,9 @@ static bool progs_nextline(char **out, size_t *alen,FILE *src) {
         return false;
 
     /* start at first non-blank */
-    for (start = line; isspace(*start); ++start) {}
+    for (start = line; util_isspace(*start); ++start) {}
     /* end at the first non-blank */
-    for (end = start;  *end && !isspace(*end);  ++end)   {}
+    for (end = start; *end && !util_isspace(*end);  ++end)   {}
 
     *out = line;
     /* move the actual filename to the beginning */
diff --git a/opts.c b/opts.c
index e6ca420..38386f2 100644 (file)
--- a/opts.c
+++ b/opts.c
@@ -23,7 +23,6 @@
  */
 #include <string.h>
 #include <stdlib.h>
-#include <ctype.h>
 
 #include "gmqcc.h"
 
@@ -163,13 +162,13 @@ void opts_setoptimlevel(unsigned int level) {
  */
 static char *opts_ini_rstrip(char *s) {
     char *p = s + strlen(s);
-    while(p > s && isspace(*--p))
+    while(p > s && util_isspace(*--p))
         *p = '\0';
     return s;
 }
 
 static char *opts_ini_lskip(const char *s) {
-    while (*s && isspace(*s))
+    while (*s && util_isspace(*s))
         s++;
     return (char*)s;
 }
@@ -177,7 +176,7 @@ static char *opts_ini_lskip(const char *s) {
 static char *opts_ini_next(const char *s, char c) {
     bool last = false;
     while (*s && *s != c && !(last && *s == ';'))
-        last = !!isspace(*s), s++;
+        last = !!util_isspace(*s), s++;
 
     return (char*)s;
 }
diff --git a/stat.c b/stat.c
index 4cd82bc..3b54d6e 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -24,7 +24,6 @@
 
 #include <string.h>
 #include <stdlib.h>
-#include <ctype.h>
 
 #include "gmqcc.h"
 
@@ -613,7 +612,7 @@ static void stat_dump_mem_contents(stat_mem_block_t *memory, uint16_t cols) {
                 con_out("%c",
                     (j >= memory->size)
                         ? ' '
-                        : (isprint(((unsigned char*)(memory + 1))[j]))
+                        : (util_isprint(((unsigned char*)(memory + 1))[j]))
                             ? 0xFF & ((unsigned char*)(memory + 1)) [j]
                             : '.'
                 );
diff --git a/util.c b/util.c
index ca8f2e8..b34460d 100644 (file)
--- a/util.c
+++ b/util.c
@@ -22,7 +22,6 @@
  * SOFTWARE.
  */
 #include <string.h>
-#include <ctype.h>
 #include <stdlib.h>
 
 #include "gmqcc.h"
@@ -201,7 +200,7 @@ uint16_t util_crc16(const char *k, int len, const short clamp) {
 size_t util_strtocmd(const char *in, char *out, size_t outsz) {
     size_t sz = 1;
     for (; *in && sz < outsz; ++in, ++out, ++sz)
-        *out = (*in == '-') ? '_' : (isalpha(*in) && !isupper(*in)) ? *in + 'A' - 'a': *in;
+        *out = (*in == '-') ? '_' : (util_isalpha(*in) && !util_isupper(*in)) ? *in + 'A' - 'a': *in;
     *out = 0;
     return sz-1;
 }
@@ -209,7 +208,7 @@ size_t util_strtocmd(const char *in, char *out, size_t outsz) {
 size_t util_strtononcmd(const char *in, char *out, size_t outsz) {
     size_t sz = 1;
     for (; *in && sz < outsz; ++in, ++out, ++sz)
-        *out = (*in == '_') ? '-' : (isalpha(*in) && isupper(*in)) ? *in + 'a' - 'A' : *in;
+        *out = (*in == '_') ? '-' : (util_isalpha(*in) && util_isupper(*in)) ? *in + 'a' - 'A' : *in;
     *out = 0;
     return sz-1;
 }