/*===================================================================*/
/*=========================== 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 *);
* 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>
/* 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
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;
ch = '/';
break;
}
- } while (ch != EOF && isspace(ch));
+ } while (ch != EOF && util_isspace(ch));
if (haswhite) {
lex_endtoken(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')
lex_tokench(lex, ch);
ch = lex_getch(lex);
- if (ch != '.' && !isdigit(ch))
+ if (ch != '.' && !util_isdigit(ch))
{
if (lastch != '0' || ch != 'x')
{
{
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);
/* continue digits-only */
ch = lex_getch(lex);
- while (isdigit(ch))
+ while (util_isdigit(ch))
{
lex_tokench(lex, ch);
ch = lex_getch(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);
}
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);
}
}
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)
return lex->tok.ttype;
}
- if (isdigit(ch))
+ if (util_isdigit(ch))
{
lex->tok.ttype = lex_finish_digit(lex, ch);
lex_endtoken(lex);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-
#include "gmqcc.h"
#include "lexer.h"
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);
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 */
*/
#include <string.h>
#include <stdlib.h>
-#include <ctype.h>
#include "gmqcc.h"
*/
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;
}
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;
}
#include <string.h>
#include <stdlib.h>
-#include <ctype.h>
#include "gmqcc.h"
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]
: '.'
);
* SOFTWARE.
*/
#include <string.h>
-#include <ctype.h>
#include <stdlib.h>
#include "gmqcc.h"
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;
}
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;
}