# DO NOT DELETE
+pak.o: gmqcc.h opts.def
+ansi.o: gmqcc.h opts.def
util.o: gmqcc.h opts.def
+stat.o: gmqcc.h opts.def
fs.o: gmqcc.h opts.def
conout.o: gmqcc.h opts.def
opts.o: gmqcc.h opts.def
-pak.o: gmqcc.h opts.def
-stat.o: gmqcc.h opts.def
test.o: gmqcc.h opts.def
main.o: gmqcc.h opts.def lexer.h
lexer.o: gmqcc.h opts.def lexer.h
--- /dev/null
+/*
+ * Copyright (C) 2012, 2013
+ * Dale Weiler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include <string.h>
+#include <stdlib.h>
+
+#include "gmqcc.h"
+
+int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg) {
+ return vsnprintf(buffer, bytes, format, arg);
+}
+
+int platform_sscanf(const char *str, const char *format, ...) {
+ int rt;
+ va_list va;
+
+ va_start(va, format);
+ rt = vsscanf(str, format, va);
+ va_end (va);
+
+ return rt;
+}
+
+const struct tm *platform_localtime(const time_t *timer) {
+ return localtime(timer);
+}
+
+const char *platform_ctime(const time_t *timer) {
+ return ctime(timer);
+}
+
+char *platform_strncat(char *dest, const char *src, size_t num) {
+ return strncat(dest, src, num);
+}
+
+const char *platform_tmpnam(char *str) {
+ return tmpnam(str);
+}
+
+const char *platform_getenv(char *var) {
+ return getenv(var);
+}
+
+int platform_snprintf(char *src, size_t bytes, const char *format, ...) {
+ int rt;
+ va_list va;
+
+ va_start(va, format);
+ rt = vsnprintf(src, bytes, format, va);
+ va_end(va);
+
+ return rt;
+}
+
+char *platform_strcat(char *dest, const char *src) {
+ return strcat(dest, src);
+}
+
+char *platform_strncpy(char *dest, const char *src, size_t num) {
+ return strncpy(dest, src, num);
+}
+
+const char *platform_strerror(int err) {
+ return strerror(err);
+}
if (!e) {
if (pos + 6 >= bufsize)
goto full;
- util_strncpy(buf + pos, "(null)", 6);
+ platform_strncpy(buf + pos, "(null)", 6);
return pos + 6;
}
switch (e->vtype) {
case TYPE_VARIANT:
- util_strncpy(buf + pos, "(variant)", 9);
+ platform_strncpy(buf + pos, "(variant)", 9);
return pos + 9;
case TYPE_FIELD:
if (pos + 1 >= bufsize)
goto full;
buf[pos++] = '[';
- pos += util_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->count);
+ pos += platform_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->count);
if (pos + 1 >= bufsize)
goto full;
buf[pos++] = ']';
typelen = strlen(typestr);
if (pos + typelen >= bufsize)
goto full;
- util_strncpy(buf + pos, typestr, typelen);
+ platform_strncpy(buf + pos, typestr, typelen);
return pos + typelen;
}
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
- util_strncpy(name, self->name, namelen);
+ platform_strncpy(name, self->name, namelen);
array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count);
array->ir_values[0] = v;
for (ai = 1; ai < array->expression.count; ++ai) {
- util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
+ platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
array->ir_values[ai] = ir_builder_create_field(ir, name, vtype);
if (!array->ir_values[ai]) {
mem_d(name);
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
- util_strncpy(name, self->name, namelen);
+ platform_strncpy(name, self->name, namelen);
self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
self->ir_values[0] = v;
for (ai = 1; ai < self->expression.count; ++ai) {
- util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
+ platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
self->ir_values[ai] = ir_builder_create_global(ir, name, vtype);
if (!self->ir_values[ai]) {
mem_d(name);
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
- util_strncpy(name, self->name, namelen);
+ platform_strncpy(name, self->name, namelen);
self->ir_values[0] = v;
for (ai = 1; ai < self->expression.count; ++ai) {
- util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
+ platform_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
self->ir_values[ai] = ir_function_create_local(func, name, vtype, param);
if (!self->ir_values[ai]) {
compile_error(ast_ctx(self), "internal_error: ir_builder_create_global failed on `%s`", name);
{
char data[4096];
memset(data, 0, sizeof(data));
-#ifdef _MSC_VER
- vsnprintf_s(data, sizeof(data), sizeof(data), fmt, va);
-#else
- vsnprintf(data, sizeof(data), fmt, va);
-#endif
+ platform_vsnprintf(data, sizeof(data), fmt, va);
ln = (GMQCC_IS_DEFINE(handle)) ? win_fputs(handle, data) : fs_file_puts(handle, data);
}
#endif
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
- printf(": %s\n", util_strerror(err));
+ printf(": %s\n", platform_strerror(err));
}
static void qcvmerror(qc_program_t *prog, const char *fmt, ...)
}
#define read_data(hdrvar, progvar, reserved) \
- if (fs_file_seek(file, header.hdrvar.offset, SEEK_SET) != 0) { \
+ if (fs_file_seek(file, header.hdrvar.offset, SEEK_SET) != 0) { \
loaderror("seek failed"); \
goto error; \
} \
- if (fs_file_read ( \
+ if (fs_file_read ( \
vec_add(prog->progvar, header.hdrvar.length + reserved), \
sizeof(*prog->progvar), \
header.hdrvar.length, \
qcany_t str;
CheckArgs(1);
num = GetArg(0);
- util_snprintf(buffer, sizeof(buffer), "%g", num->_float);
+ platform_snprintf(buffer, sizeof(buffer), "%g", num->_float);
str.string = prog_tempstring(prog, buffer);
Return(str);
return 0;
qcany_t str;
CheckArgs(1);
num = GetArg(0);
- util_snprintf(buffer, sizeof(buffer), "'%g %g %g'", num->vector[0], num->vector[1], num->vector[2]);
+ platform_snprintf(buffer, sizeof(buffer), "'%g %g %g'", num->vector[0], num->vector[1], num->vector[2]);
str.string = prog_tempstring(prog, buffer);
Return(str);
return 0;
qcany_t str;
CheckArgs(1);
num = GetArg(0);
- util_snprintf(buffer, sizeof(buffer), "%i", num->_int);
+ platform_snprintf(buffer, sizeof(buffer), "%i", num->_int);
str.string = prog_tempstring(prog, buffer);
Return(str);
return 0;
arg->vector[2] = 0;
switch (main_params[i].vtype) {
case TYPE_VECTOR:
-#ifdef _MSC_VER
- (void)sscanf_s(main_params[i].value, " %f %f %f ",
- &arg->vector[0],
- &arg->vector[1],
- &arg->vector[2]);
-#else
- (void)sscanf(main_params[i].value, " %f %f %f ",
- &arg->vector[0],
- &arg->vector[1],
- &arg->vector[2]);
-#endif
+ (void)platform_sscanf(main_params[i].value, " %f %f %f ",
+ &arg->vector[0],
+ &arg->vector[1],
+ &arg->vector[2]);
break;
case TYPE_FLOAT:
arg->_float = atof(main_params[i].value);
if (translate) {
char name[32];
- util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(fold->parser->translated++));
+ platform_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(fold->parser->translated++));
out = ast_value_new(parser_ctx(fold->parser), name, TYPE_STRING);
out->expression.flags |= AST_FLAG_INCLUDE_DEF; /* def needs to be included for translatables */
} else
if (!dir)
return NULL;
- util_strncpy(dir->dd_name, name, strlen(name));
+ platform_strncpy(dir->dd_name, name, strlen(name));
return dir;
}
if (*dir->dd_name) {
size_t n = strlen(dir->dd_name);
if ((dirname = (char*)mem_a(n + 5) /* 4 + 1 */)) {
- util_strncpy(dirname, dir->dd_name, n);
- util_strncpy(dirname + n, "\\*.*", 4); /* 4 + 1 */
+ platform_strncpy(dirname, dir->dd_name, n);
+ platform_strncpy(dirname + n, "\\*.*", 4); /* 4 + 1 */
}
} else {
if (!(dirname = util_strdup("\\*.*")))
return NULL;
if ((data = (struct dirent*)mem_a(sizeof(struct dirent)))) {
- util_strncpy(data->d_name, info.cFileName, FILENAME_MAX - 1);
+ platform_strncpy(data->d_name, info.cFileName, FILENAME_MAX - 1);
data->d_name[FILENAME_MAX - 1] = '\0'; /* terminate */
data->d_namlen = strlen(data->d_name);
}
/* __DATE__ */
static char *ftepp_predef_date(lex_file *context) {
- struct tm *itime = NULL;
- time_t rtime;
- char *value = (char*)mem_a(82);
- /* 82 is enough for strftime but we also have " " in our string */
+ const struct tm *itime = NULL;
+ char *value = (char*)mem_a(82);
+ time_t rtime;
(void)context;
- /* get time */
time (&rtime);
-
-#ifdef _MSC_VER
- localtime_s(itime, &rtime);
-#else
- itime = localtime(&rtime);
-#endif
-
+ itime = platform_localtime(&rtime);
strftime(value, 82, "\"%b %d %Y\"", itime);
return value;
/* __TIME__ */
static char *ftepp_predef_time(lex_file *context) {
- struct tm *itime = NULL;
- time_t rtime;
- char *value = (char*)mem_a(82);
- /* 82 is enough for strftime but we also have " " in our string */
+ const struct tm *itime = NULL;
+ char *value = (char*)mem_a(82);
+ time_t rtime;
(void)context;
- /* get time */
time (&rtime);
-
-#ifdef _MSC_VER
- localtime_s(itime, &rtime);
-#else
- itime = localtime(&rtime);
-#endif
-
+ itime = platform_localtime(&rtime);
strftime(value, 82, "\"%X\"", itime);
return value;
static char *ftepp_predef_file(lex_file *context) {
size_t length = strlen(context->name) + 3; /* two quotes and a terminator */
char *value = (char*)mem_a(length);
- util_snprintf(value, length, "\"%s\"", context->name);
+ platform_snprintf(value, length, "\"%s\"", context->name);
return value;
}
/* __TIMESTAMP__ */
static char *ftepp_predef_timestamp(lex_file *context) {
struct stat finfo;
- char *find;
+ const char *find;
char *value;
size_t size;
-#ifdef _MSC_VER
- char buffer[64];
-#endif
+
if (stat(context->name, &finfo))
return util_strdup("\"<failed to determine timestamp>\"");
- /*
- * ctime and its fucking annoying newline char, no worries, we're
- * professionals here.
- */
-
-#ifndef _MSC_VER
- find = ctime(&finfo.st_mtime);
-#else
- ctime_s(buffer, sizeof(buffer), &finfo.st_mtime);
- find = buffer;
-#endif
-
+ find = platform_ctime(&finfo.st_mtime);
value = (char*)mem_a(strlen(find) + 1);
memcpy(&value[1], find, (size = strlen(find)) - 1);
if (resetline && !ftepp->in_macro) {
char lineno[128];
- util_snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline));
+ platform_snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline));
ftepp_out(ftepp, lineno, false);
}
ftepp_out(ftepp, "\n#pragma file(", false);
ftepp_out(ftepp, ctx.file, false);
- util_snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1));
+ platform_snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1));
ftepp_out(ftepp, lineno, false);
/* skip the line */
minor[2] = '"';
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
ftepp_add_define(ftepp, NULL, "__STD_GMQCC__");
- util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
- util_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
+ platform_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
+ platform_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCCX) {
ftepp_add_define(ftepp, NULL, "__STD_QCCX__");
- util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
- util_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
+ platform_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
+ platform_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) {
ftepp_add_define(ftepp, NULL, "__STD_QCC__");
/* 1.0 */
#ifndef GMQCC_HDR
#define GMQCC_HDR
#include <stdarg.h>
+#include <time.h> /* TODO: remove this? */
#include <stdio.h> /* TODO: remove this */
/*
void util_seed(uint32_t);
uint32_t util_rand(void);
-/*
- * String functions (formatting, copying, concatenating, errors). These are wrapped
- * to use the MSVC _safe_ versions when using MSVC, plus some implementations of
- * these are non-conformant or don't exist such as asprintf and snprintf, which are
- * not supported in C90, but do exist in C99.
- */
-int util_vasprintf(char **ret, const char *fmt, va_list);
-int util_asprintf (char **ret, const char *fmt, ...);
-int util_snprintf (char *src, size_t bytes, const char *format, ...);
-char *util_strcat (char *dest, const char *src);
-char *util_strncpy (char *dest, const char *src, size_t num);
-const char *util_strerror (int num);
+int util_vasprintf(char **ret, const char *fmt, va_list);
+int util_asprintf (char **ret, const char *fmt, ...);
/*
* A flexible vector implementation: all vector pointers contain some
struct dirent *fs_dir_read (DIR *);
+int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg);
+int platform_sscanf(const char *str, const char *format, ...);
+const struct tm *platform_localtime(const time_t *timer);
+const char *platform_ctime(const time_t *timer);
+char *platform_strncat(char *dest, const char *src, size_t num);
+const char *platform_tmpnam(char *str);
+const char *platform_getenv(char *var);
+int platform_snprintf(char *src, size_t bytes, const char *format, ...);
+char *platform_strcat(char *dest, const char *src);
+char *platform_strncpy(char *dest, const char *src, size_t num);
+const char *platform_strerror(int err);
+
/*===================================================================*/
/*=========================== correct.c =============================*/
/*===================================================================*/
LIBS += -lm
#objects
-OBJ_C = main.o lexer.o parser.o fs.o stat.o util.o code.o ast.o ir.o conout.o ftepp.o opts.o utf8.o correct.o fold.o intrin.o
-OBJ_P = util.o fs.o conout.o opts.o pak.o stat.o
-OBJ_T = test.o util.o opts.o conout.o fs.o stat.o
-OBJ_X = exec-standalone.o util.o opts.o conout.o fs.o stat.o
+OBJ_C = main.o ansi.o util.o stat.o fs.o lexer.o parser.o code.o ast.o ir.o conout.o ftepp.o opts.o utf8.o correct.o fold.o intrin.o
+OBJ_P = pak.o ansi.o util.o stat.o fs.o conout.o opts.o pak.o
+OBJ_T = test.o ansi.o util.o stat.o fs.o opts.o conout.o
+OBJ_X = exec-standalone.o ansi.o util.o stat.o fs.o opts.o conout.o
#gource flags
GOURCEFLAGS = \
char buffer[1024];
char stype [1024];
- util_snprintf(buffer, sizeof(buffer), "__builtin_%s", name);
- util_snprintf(stype, sizeof(stype), "<%s>", type_name[vtype]);
+ platform_snprintf(buffer, sizeof(buffer), "__builtin_%s", name);
+ platform_snprintf(stype, sizeof(stype), "<%s>", type_name[vtype]);
*value = ast_value_new(intrin_ctx(intrin), buffer, TYPE_FUNCTION);
(*value)->intrinsic = true;
ir_value *global;
char name[128];
- util_snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparam_protos)));
+ platform_snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparam_protos)));
global = ir_value_var(name, store_global, TYPE_VECTOR);
vec_push(ir->extparam_protos, global);
#define IND_BUFSZ 1024
-#ifdef _MSC_VER
-# define strncat(dst, src, sz) strncat_s(dst, sz, src, _TRUNCATE)
-#endif
-
static const char *qc_opname(int op)
{
if (op < 0) return "<INVALID>";
return;
}
oprintf("%sfunction %s\n", ind, f->name);
- strncat(ind, "\t", IND_BUFSZ-1);
+ platform_strncat(ind, "\t", IND_BUFSZ-1);
if (vec_size(f->locals))
{
oprintf("%s%i locals:\n", ind, (int)vec_size(f->locals));
{
size_t i;
oprintf("%s:%s\n", ind, b->label);
- strncat(ind, "\t", IND_BUFSZ-1);
+ platform_strncat(ind, "\t", IND_BUFSZ-1);
if (b->instr && b->instr[0])
oprintf("%s (%i) [entry]\n", ind, (int)(b->instr[0]->eid-1));
return;
}
- strncat(ind, "\t", IND_BUFSZ-1);
+ platform_strncat(ind, "\t", IND_BUFSZ-1);
if (in->_ops[0] && (in->_ops[1] || in->_ops[2])) {
ir_value_dump(in->_ops[0], oprintf);
lex_endtoken(lex);
lex->tok.ttype = TOKEN_CHARCONST;
- /* It's a vector if we can successfully scan 3 floats */
-#ifdef _MSC_VER
- if (sscanf_s(lex->tok.value, " %f %f %f ",
- &lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3)
-#else
- if (sscanf(lex->tok.value, " %f %f %f ",
+
+ /* It's a vector if we can successfully scan 3 floats */
+ if (platform_sscanf(lex->tok.value, " %f %f %f ",
&lex->tok.constval.v.x, &lex->tok.constval.v.y, &lex->tok.constval.v.z) == 3)
-#endif
{
lex->tok.ttype = TOKEN_VECTORCONST;
--- /dev/null
+/*
+ * Copyright (C) 2012, 2013
+ * Dale Weiler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "gmqcc.h"
+
+#define CTIME_BUFFER 64
+#define GETENV_BUFFER 4096
+#define STRERROR_BUFFER 128
+
+static void **platform_mem_pool = NULL;
+static void platform_mem_atexit() {
+ size_t i;
+ for (i = 0; i < vec_size(platform_mem_pool); i++)
+ mem_d(platform_mem_pool[i]);
+ vec_free(platform_mem_pool);
+}
+
+static void *platform_mem_allocate(size_t bytes) {
+ void *mem = NULL;
+ if (!platform_mem_pool) {
+ atexit(&platform_mem_atexit);
+ vec_push(platform_mem_pool, NULL);
+ }
+
+ mem = mem_a(bytes);
+ vec_push(platform_mem_pool, mem);
+
+ return mem;
+}
+
+int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg) {
+ vsnprintf_s(buffer, bytes, bytes, format, arg);
+}
+
+int platform_sscanf(const char *str, const char *format, ...) {
+ va_list va;
+ va_start(va, format);
+ vsscanf_s(str, format, va);
+ va_end(va);
+}
+
+const struct tm *platform_localtime(const time_t *timer) {
+ struct tm *t;
+ t = (struct tm*)platform_mem_allocate(sizeof(struct tm));
+ localtime_s(&t, timer);
+ return &t;
+}
+
+const char *platform_ctime(const time_t *timer) {
+ char *buffer = (char *)platform_mem_allocate(CTIME_BUFFER);
+ ctime_s(buffer, CTIME_BUFFER, timer);
+ return buffer;
+}
+
+char *platform_strncat(char *dest, const char *src, size_t num) {
+ return strncat_s(dest, num, src, _TRUNCATE);
+}
+
+const char *platform_tmpnam(char *str) {
+ return tmpnam_s(str, L_tmpnam);
+}
+
+const char *platform_getenv(char *var) {
+ char *buffer = (char *)platform_mem_allocate(GETENV_BUFFER);
+ size_t size;
+ getenv_s(&size, buffer, GETENV_BUFFER, var);
+ return buffer;
+}
+
+int platform_snprintf(char *src, size_t bytes, const char *format, ...) {
+ int rt;
+ va_list va;
+ va_start(va, format);
+
+ rt = vsprintf_s(src, bytes, format, va);
+ va_end (va);
+
+ return rt;
+}
+
+char *platform_strcat(char *dest, const char *src) {
+ strcat_s(dest, strlen(src), src);
+ return dest;
+}
+
+char *platform_strncpy(char *dest, const char *src, size_t num) {
+ strncpy_s(dest, num, src, num);
+ return dest;
+}
+
+const char *platform_strerror(int err) {
+ char *buffer = (char*)platform_mem_allocate(STRERROR_BUFFER);
+ strerror_s(buffer, STRERROR_BUFFER, err);
+ return buffer;
+}
/* section found */
if (*(parse_end = opts_ini_next(parse_beg + 1, ']')) == ']') {
* parse_end = '\0'; /* terminate bro */
- util_strncpy(section_data, parse_beg + 1, sizeof(section_data));
+ platform_strncpy(section_data, parse_beg + 1, sizeof(section_data));
section_data[sizeof(section_data) - 1] = '\0';
*oldname_data = '\0';
} else if (!error) {
opts_ini_rstrip(read_value);
/* valid name value pair, lets call down to handler */
- util_strncpy(oldname_data, read_name, sizeof(oldname_data));
+ platform_strncpy(oldname_data, read_name, sizeof(oldname_data));
oldname_data[sizeof(oldname_data) - 1] ='\0';
if ((*errorhandle = loadhandle(section_data, read_name, read_value)) && !error)
memset(pathsplit, 0, 56);
- util_strncpy(directory, entry, 56);
+ platform_strncpy(directory, entry, 56);
for (itr = 0; (token = pak_tree_sep(&directory, "/")) != NULL; itr++) {
elements[itr] = token;
}
for (jtr = 0; jtr < itr - 1; jtr++) {
- util_strcat(pathsplit, elements[jtr]);
- util_strcat(pathsplit, "/");
+ platform_strcat(pathsplit, elements[jtr]);
+ platform_strcat(pathsplit, "/");
if (fs_dir_make(pathsplit)) {
mem_d(pathsplit);
if (strlen(file) >= 56)
goto err;
- util_strncpy(dir.name, file, strlen(file));
+ platform_strncpy(dir.name, file, strlen(file));
/*
* Allocate some memory for loading in the data that will be
varargs->expression.flags |= AST_FLAG_IS_VARARG;
varargs->expression.next = (ast_expression*)ast_value_new(ast_ctx(var), NULL, TYPE_VECTOR);
varargs->expression.count = 0;
- util_snprintf(name, sizeof(name), "%s##va##SET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##va##SET", var->name);
if (!parser_create_array_setter_proto(parser, varargs, name)) {
ast_delete(varargs);
ast_block_delete(block);
goto enderrfn;
}
- util_snprintf(name, sizeof(name), "%s##va##GET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##va##GET", var->name);
if (!parser_create_array_getter_proto(parser, varargs, varargs->expression.next, name)) {
ast_delete(varargs);
ast_block_delete(block);
static bool create_array_accessors(parser_t *parser, ast_value *var)
{
char name[1024];
- util_snprintf(name, sizeof(name), "%s##SET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##SET", var->name);
if (!parser_create_array_setter(parser, var, name))
return false;
- util_snprintf(name, sizeof(name), "%s##GET", var->name);
+ platform_snprintf(name, sizeof(name), "%s##GET", var->name);
if (!parser_create_array_getter(parser, var, var->expression.next, name))
return false;
return true;
goto cleanup;
}
- util_snprintf(name, sizeof(name), "%s##SETF", var->name);
+ platform_snprintf(name, sizeof(name), "%s##SETF", var->name);
if (!parser_create_array_field_setter(parser, array, name))
goto cleanup;
telem = ast_type_copy(ast_ctx(var), array->expression.next);
tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
tfield->expression.next = telem;
- util_snprintf(name, sizeof(name), "%s##GETFP", var->name);
+ platform_snprintf(name, sizeof(name), "%s##GETFP", var->name);
if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
ast_delete(tfield);
goto cleanup;
char *cmd = NULL;
popen_t *open = (popen_t*)mem_a(sizeof(popen_t));
-#ifndef _MSC_VER
- tmpnam(open->name_err);
- tmpnam(open->name_out);
-#else
- tmpnam_s(open->name_err, L_tmpnam);
- tmpnam_s(open->name_out, L_tmpnam);
-#endif
+ platform_tmpnam(open->name_err);
+ platform_tmpnam(open->name_out);
(void)mode; /* excluded */
FILE *tempfile = NULL;
task_template_t *tmpl = NULL;
- util_snprintf(fullfile, sizeof(fullfile), "%s/%s", dir, file);
+ platform_snprintf(fullfile, sizeof(fullfile), "%s/%s", dir, file);
tempfile = fs_file_open(fullfile, "r");
tmpl = (task_template_t*)mem_a(sizeof(task_template_t));
dir = fs_dir_open(directories[i]);
while ((files = fs_dir_read(dir))) {
- util_snprintf(buffer, sizeof(buffer), "%s/%s", directories[i], files->d_name);
+ platform_snprintf(buffer, sizeof(buffer), "%s/%s", directories[i], files->d_name);
if (stat(buffer, &directory) == -1) {
con_err("internal error: stat failed, aborting\n");
abort();
if (strcmp(files->d_name + strlen(files->d_name) - 5, ".tmpl") == 0) {
task_template_t *tmpl = task_template_compile(files->d_name, directories[i], pad);
char buf[4096]; /* one page should be enough */
- char *qcflags = NULL;
+ const char *qcflags = NULL;
task_t task;
found ++;
* to test compile flags for all tests. This needs to be
* BEFORE other flags (so that the .tmpl can override them)
*/
- #ifdef _MSC_VER
- {
- char buffer[4096];
- size_t size;
- getenv_s(&size, buffer, sizeof(buffer), "QCFLAGS");
- qcflags = buffer;
- }
- #else
- qcflags = getenv("QCFLAGS");
- #endif
+ qcflags = platform_getenv("QCFLAGS");
/*
* Generate the command required to open a pipe to a process
if (strcmp(tmpl->proceduretype, "-pp")) {
if (qcflags) {
if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
- util_snprintf(buf, sizeof(buf), "%s %s/%s %s %s -o %s",
+ platform_snprintf(buf, sizeof(buf), "%s %s/%s %s %s -o %s",
task_bins[TASK_COMPILE],
directories[i],
tmpl->sourcefile,
tmpl->tempfilename
);
} else {
- util_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s %s -o %s",
+ platform_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s %s -o %s",
task_bins[TASK_COMPILE],
curdir,
defs,
}
} else {
if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
- util_snprintf(buf, sizeof(buf), "%s %s/%s %s -o %s",
+ platform_snprintf(buf, sizeof(buf), "%s %s/%s %s -o %s",
task_bins[TASK_COMPILE],
directories[i],
tmpl->sourcefile,
tmpl->tempfilename
);
} else {
- util_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s -o %s",
+ platform_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s -o %s",
task_bins[TASK_COMPILE],
curdir,
defs,
} else {
/* Preprocessing (qcflags mean shit all here we don't allow them) */
if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
- util_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s",
+ platform_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s",
task_bins[TASK_COMPILE],
directories[i],
tmpl->sourcefile,
tmpl->tempfilename
);
} else {
- util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s",
+ platform_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s",
task_bins[TASK_COMPILE],
curdir,
defs,
* Open up some file desciptors for logging the stdout/stderr
* to our own.
*/
- util_snprintf(buf, sizeof(buf), "%s.stdout", tmpl->tempfilename);
+ platform_snprintf(buf, sizeof(buf), "%s.stdout", tmpl->tempfilename);
task.stdoutlogfile = util_strdup(buf);
if (!(task.stdoutlog = fs_file_open(buf, "w"))) {
con_err("error opening %s for stdout\n", buf);
continue;
}
- util_snprintf(buf, sizeof(buf), "%s.stderr", tmpl->tempfilename);
+ platform_snprintf(buf, sizeof(buf), "%s.stderr", tmpl->tempfilename);
task.stderrlogfile = util_strdup(buf);
if (!(task.stderrlog = fs_file_open(buf, "w"))) {
con_err("error opening %s for stderr\n", buf);
strstr(files->d_name, ".stdout") ||
strstr(files->d_name, ".stderr"))
{
- util_snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name);
+ platform_snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name);
if (remove(buffer))
con_err("error removing temporary file: %s\n", buffer);
}
* actually specified.
*/
if (!strcmp(tmpl->executeflags, "$null")) {
- util_snprintf(buffer, sizeof(buffer), "%s %s",
+ platform_snprintf(buffer, sizeof(buffer), "%s %s",
task_bins[TASK_EXECUTE],
tmpl->tempfilename
);
} else {
- util_snprintf(buffer, sizeof(buffer), "%s %s %s",
+ platform_snprintf(buffer, sizeof(buffer), "%s %s %s",
task_bins[TASK_EXECUTE],
tmpl->executeflags,
tmpl->tempfilename
size_t j = 0;
size_t failed = 0;
- util_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks));
+ platform_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks));
for (; i < vec_size(task_tasks); i++) {
memset(space[1], 0, sizeof(space[1]));
- util_snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1));
+ platform_snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1));
con_out("test #%u %*s", i + 1, strlen(space[0]) - strlen(space[1]), "");
return read;
}
-/*
- * These are various re-implementations (wrapping the real ones) of
- * string functions that MSVC considers unsafe. We wrap these up and
- * use the safe variations on MSVC.
- */
-#ifdef _MSC_VER
- static char **util_strerror_allocated() {
- static char **data = NULL;
- return data;
- }
-
- static void util_strerror_cleanup(void) {
- size_t i;
- char **data = util_strerror_allocated();
- for (i = 0; i < vec_size(data); i++)
- mem_d(data[i]);
- vec_free(data);
- }
-
- const char *util_strerror(int num) {
- char *allocated = NULL;
- static bool install = false;
- static size_t tries = 0;
- char **vector = util_strerror_allocated();
-
- /* try installing cleanup handler */
- while (!install) {
- if (tries == 32)
- return "(unknown)";
-
- install = !atexit(&util_strerror_cleanup);
- tries ++;
- }
-
- allocated = (char*)mem_a(4096); /* A page must be enough */
- strerror_s(allocated, 4096, num);
-
- vec_push(vector, allocated);
- return (const char *)allocated;
- }
-
- int util_snprintf(char *src, size_t bytes, const char *format, ...) {
- int rt;
- va_list va;
- va_start(va, format);
-
- rt = vsprintf_s(src, bytes, format, va);
- va_end (va);
-
- return rt;
- }
-
- char *util_strcat(char *dest, const char *src) {
- strcat_s(dest, strlen(src), src);
- return dest;
- }
-
- char *util_strncpy(char *dest, const char *src, size_t num) {
- strncpy_s(dest, num, src, num);
- return dest;
- }
-#else
- const char *util_strerror(int num) {
- return strerror(num);
- }
-
- int util_snprintf(char *src, size_t bytes, const char *format, ...) {
- int rt;
- va_list va;
- va_start(va, format);
- rt = vsnprintf(src, bytes, format, va);
- va_end (va);
-
- return rt;
- }
-
- char *util_strcat(char *dest, const char *src) {
- return strcat(dest, src);
- }
-
- char *util_strncpy(char *dest, const char *src, size_t num) {
- return strncpy(dest, src, num);
- }
-
-#endif /*! _MSC_VER */
-
-
void util_seed(uint32_t value) {
srand((int)value);
}