Oh my god microsoft you suck

This commit is contained in:
Dale Weiler 2013-06-20 11:20:56 +00:00
parent 82fd7fcf68
commit 6db2e69f9a
6 changed files with 44 additions and 28 deletions

22
gmqcc.h
View file

@ -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 *);

27
lexer.c
View file

@ -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);

8
main.c
View file

@ -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 */

7
opts.c
View file

@ -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;
}

3
stat.c
View file

@ -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]
: '.'
);

5
util.c
View file

@ -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;
}