diff --git a/.gitignore b/.gitignore index 342039c..416e445 100644 --- a/.gitignore +++ b/.gitignore @@ -3,11 +3,7 @@ *.rej *.patch *.diff - -testsuite -qcvm -gmqcc -pak +*.exe distro/archlinux/* distro/archbsd/* diff --git a/ast.c b/ast.c old mode 100644 new mode 100755 index ae710d6..aa70509 --- a/ast.c +++ b/ast.c @@ -220,7 +220,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi if (!e) { if (pos + 6 >= bufsize) goto full; - strncpy(buf + pos, "(null)", 6); + util_strncpy(buf + pos, "(null)", 6); return pos + 6; } @@ -229,7 +229,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi switch (e->expression.vtype) { case TYPE_VARIANT: - strncpy(buf + pos, "(variant)", 9); + util_strncpy(buf + pos, "(variant)", 9); return pos + 9; case TYPE_FIELD: @@ -275,7 +275,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi if (pos + 1 >= bufsize) goto full; buf[pos++] = '['; - pos += snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->expression.count); + pos += util_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->expression.count); if (pos + 1 >= bufsize) goto full; buf[pos++] = ']'; @@ -286,7 +286,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi typelen = strlen(typestr); if (pos + typelen >= bufsize) goto full; - strncpy(buf + pos, typestr, typelen); + util_strncpy(buf + pos, typestr, typelen); return pos + typelen; } @@ -1219,12 +1219,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); - strncpy(name, self->name, namelen); + util_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) { - snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); + util_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); @@ -1277,12 +1277,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); - strncpy(name, self->name, namelen); + util_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) { - snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); + util_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); @@ -1419,11 +1419,11 @@ bool ast_local_codegen(ast_value *self, ir_function *func, bool param) namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); - strncpy(name, self->name, namelen); + util_strncpy(name, self->name, namelen); self->ir_values[0] = v; for (ai = 1; ai < self->expression.count; ++ai) { - snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); + util_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); diff --git a/ast.h b/ast.h old mode 100644 new mode 100755 diff --git a/code.c b/code.c old mode 100644 new mode 100755 diff --git a/conout.c b/conout.c old mode 100644 new mode 100755 index 7e8cd9a..dd4dca3 --- a/conout.c +++ b/conout.c @@ -110,7 +110,7 @@ static int win_fputs(FILE *h, const char *str) { int wcolor; int icolor; - int state; + int state = 0; /* attributes */ int intense = -1; @@ -218,7 +218,11 @@ static int con_write(FILE *handle, const char *fmt, va_list va) { { 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 ln = (GMQCC_IS_DEFINE(handle)) ? win_fputs(handle, data) : fs_file_puts(handle, data); } #endif diff --git a/correct.c b/correct.c old mode 100644 new mode 100755 diff --git a/distro/Makefile b/distro/Makefile index 36fc942..96ddce2 100644 --- a/distro/Makefile +++ b/distro/Makefile @@ -1,5 +1,7 @@ DROPBOX := dropbox_uploader.sh UNAME := $(shell uname -m) +DOWNLOAD:= ../doc/html/download.c +BRANCH := $(shell git branch | sed -n -e 's/^\* \(.*\)/\1/p') ifneq ($(shell uname -m), x86_64) $(error Cannot build packages without an x86_64 capable CPU) endif @@ -29,9 +31,23 @@ upload: @find . -type f -regex ".*/.*\.\(xz\|deb\|zip\)" -exec ./$$(basename $(DROPBOX)) upload {} \; @rm dropbox_config dropbox_uploader.sh +website: + $(CC) $(DOWNLOAD) -o html.gen + @./html.gen ../ + @rm html.gen + @git stash + @git checkout gh-pages + @rm -f ../download.html + @mv -f download.html ../download.html + @cd ..; git add download.html; git commit -m 'update download page'; git push origin gh-pages; + @git checkout $(BRANCH) + @git stash apply + clean: @rm -f *.deb @rm -f *.pkg.tar.xz @rm -f *.zip + @rm -f *.gen + @rm -f *.html all: base upload diff --git a/doc/html/download.c b/doc/html/download.c new file mode 100644 index 0000000..33845a7 --- /dev/null +++ b/doc/html/download.c @@ -0,0 +1,284 @@ +#include +#include +#include +#include + +/* + * protect some information, not that I care, but this is just to stay + * safer. + */ +#define SECURITY_BASE "\ +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" +#define SECURITY_TOKEN "\ +P29hdXRoX2NvbnN1bWVyX2tleT03NnZoM3E0Mmhudm16bTMmb2F1dGhfdG9rZW49\ +dzBieHpmMGRmdDhlZGZxJm9hdXRoX3NpZ25hdHVyZV9tZXRob2Q9UExBSU5URVhU\ +Jm9hdXRoX3NpZ25hdHVyZT10bWVlY2h0MmNtaDcyeGElMjY5dm9zeDd4OGd5NGtn\ +amsmb2F1dGhfdGltZXN0YW1wPSZvYXV0aF9ub25jZT0xMjE2NQo=" + +int isbase64(char c) { + return !!(c && strchr(SECURITY_BASE, c) != NULL); +} +char value(char c) { + const char *load = SECURITY_BASE; + const char *find = strchr(load, c); + + return (find) ? find - load : 0; +} + +int security_decode(unsigned char *dest, const unsigned char *src, int srclen) { + unsigned char *p; + + if(!*src) + return 0; + + *dest = 0; + p = dest; + + do { + *p++ = (value(src[0]) << 2) | (value(src[1]) >> 4); + *p++ = (value(src[1]) << 4) | (value(src[2]) >> 2); + *p++ = (value(src[2]) << 6) | (value(src[3]) >> 0); + + if(!isbase64(src[1])) { + p -= 2; + break; + } + else if(!isbase64(src[2])) { + p -= 2; + break; + } + else if(!isbase64(src[3])) { + p--; + break; + } + src += 4; + + while(*src && (*src == 13 || *src == 10)) + src++; + } while(srclen-= 4); + + *p = 0; + return p-dest; +} + +#define BASEURL " https://api-content.dropbox.com/1/files/sandbox/" + +/* + * If more platforms are supported add the entries between the start + * tag here, and the end tag below. Nothing else needs to be done + * (the table needs to match the HTML too) + */ +#define ARCHLINUX_32_REF "%sgmqcc-%c.%c.%c-1-i686.pkg.tar.xz%s" +#define ARCHLINUX_64_REF "%sgmqcc-%c.%c.%c-1-x86_64.pkg.tar.xz%s" +#define DEBIAN_32_REF "%sgmqcc-%c.%c.%c-i686.deb%s" +#define DEBIAN_64_REF "%sgmqcc-%c.%c.%c-x86_64.deb%s" +#define WINDOWS_32_REF "%sgmqcc-%c.%c.%c-win32.zip%s" +#define WINDOWS_64_REF "%sgmqcc-%c.%c.%c-win64.zip%s" + +#define HTML "\ +\ +\ +\ + \ + \ + GMQCC\ + \ + \ + \ + \ + \ +\ +\ +
\ +
\ +
\ +

GMQCC

\ +

An Improved Quake C Compiler

\ + \ +
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
Operating System / Distributionx86 Architecturex86_64 Architecture
ArchlinuxDownloadDownload
DebianDownloadDownload
WindowsDownloadDownload
\ +
\ +
\ + \ +
\ +
\ + \ +\ +\ +" + +static char build_table[][4096] = { + ARCHLINUX_32_REF, ARCHLINUX_64_REF, + DEBIAN_32_REF, DEBIAN_64_REF, + WINDOWS_32_REF, WINDOWS_64_REF +}; +/*
*/ + +#define ISXDIGIT(c) ((c >= 48 && c <= 57) || ((c & ~0x20) >= 65 && (c & ~0x20) <= 70)) +typedef struct { + char *data; + unsigned int len; + unsigned int size; +} url_t; +void escape(url_t *str) { + char *p, *ptr; + char hexstr[3]; + unsigned int i=0; + unsigned long l=0; + + p = str->data; + for(i=0; i < str->len; i++) { + if((p - str->data) >= str->len) + break; + if(*p == '%' && + ((p - str->data)+2) < str->len && + ISXDIGIT(*(p+1)) && + ISXDIGIT(*(p+2)) + ) { + p++; + hexstr[0] = *p++; + hexstr[1] = *p++; + hexstr[2] = 0; + l = strtoul(hexstr, &ptr, 16); + str->data[i] = (char)(l & 0x7f); + continue; + } + if(*p == '+') { + *p = ' '; + } + str->data[i] = *p++; + } + str->data[i] = 0; + str->len = i; +} + +void version(const char *directory, char *major, char *minor, char *patch) { + FILE *handle; + char file[4096]; + size_t size = 0; + char *data = NULL; + snprintf(file, sizeof(file), "%s/gmqcc.h", directory); + + handle = fopen(file, "r"); + if (!handle) { + fprintf(stderr, "failed to open %s for reading version (%s)\n", + file, strerror(errno) + ); + abort(); + } + + while (getline(&data, &size, handle) != EOF) { + + #define TEST(TYPE, STORE) \ + if (strstr(data, "#define GMQCC_VERSION_" TYPE )) { \ + char *get = data; \ + while (!isdigit(*get)) \ + get++; \ + *STORE = *get; \ + } + + TEST("MAJOR", major) + TEST("MINOR", minor) + TEST("PATCH", patch) + + #undef TEST + } + + free(data); +} + +void genhtml() { + FILE *fp = fopen("download.html", "w"); + if (!fp) { + fprintf(stderr, "failed to generate HTML: %s\n", strerror(errno)); + abort(); + } + + fprintf(fp, HTML, + build_table[0], build_table[1], + build_table[2], build_table[3], + build_table[4], build_table[5] + ); + fclose (fp); +} + +/* + * Builds a list of download links with the right version and handles the + * rest of the magic. + */ +void build(const char *directory) { + /* Figure out version number */ + char find[3]; + char decode[4096]; + size_t size; + version(directory, &find[0], &find[1], &find[2]); + + /* + * decode the secuity stuff for preparing the URLs which will be used + * as links. + */ + memset(decode, 0, sizeof(decode)); + security_decode(decode, SECURITY_TOKEN, strlen(SECURITY_TOKEN)); + + for (size = 0; size < sizeof(build_table) / sizeof(*build_table); size++) { + char *load = strdup(build_table[size]); + url_t esc = { NULL, 0 }; + + snprintf(build_table[size], 4096, load, BASEURL, find[0], find[1], find[2], decode); + esc.data = strdup(build_table[size]); + esc.size = strlen(build_table[size]); + esc.len = esc.size; + + /* Yes we also need to escape URLs just incase */ + escape(&esc); + free(load); + } + + /* + * Now generate the HTML file for those download links by asking tinyurl to + */ + genhtml(); +} + +int main(int argc, char **argv) { + size_t itr; + + argc--; + argv++; + if (!argc) { + printf("usage: %s [gmqcc.h location]\n", argv[-1]); + return 0; + } + + build(*argv); +} diff --git a/exec.c b/exec.c old mode 100644 new mode 100755 index 8b0ee5e..dff388b --- a/exec.c +++ b/exec.c @@ -36,7 +36,7 @@ static void loaderror(const char *fmt, ...) va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); - printf(": %s\n", strerror(err)); + printf(": %s\n", util_strerror(err)); } static void qcvmerror(qc_program *prog, const char *fmt, ...) @@ -672,7 +672,7 @@ static int qc_ftos(qc_program *prog) qcany str; CheckArgs(1); num = GetArg(0); - snprintf(buffer, sizeof(buffer), "%g", num->_float); + util_snprintf(buffer, sizeof(buffer), "%g", num->_float); str.string = prog_tempstring(prog, buffer); Return(str); return 0; @@ -684,7 +684,7 @@ static int qc_stof(qc_program *prog) qcany num; CheckArgs(1); str = GetArg(0); - num._float = strtof(prog_getstring(prog, str->string), NULL); + num._float = (float)strtod(prog_getstring(prog, str->string), NULL); Return(num); return 0; } @@ -696,7 +696,7 @@ static int qc_vtos(qc_program *prog) qcany str; CheckArgs(1); num = GetArg(0); - snprintf(buffer, sizeof(buffer), "'%g %g %g'", num->vector[0], num->vector[1], num->vector[2]); + util_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; @@ -709,7 +709,7 @@ static int qc_etos(qc_program *prog) qcany str; CheckArgs(1); num = GetArg(0); - snprintf(buffer, sizeof(buffer), "%i", num->_int); + util_snprintf(buffer, sizeof(buffer), "%i", num->_int); str.string = prog_tempstring(prog, buffer); Return(str); return 0; diff --git a/fs.c b/fs.c old mode 100644 new mode 100755 index 3a482a1..501041f --- a/fs.c +++ b/fs.c @@ -36,6 +36,7 @@ * at least I think so). */ #ifdef _MSC_VER +#include /* _CrtSetReportMode, _CRT_ASSERT */ /* {{{ */ /* * Visual Studio has security CRT features which I actually want to support @@ -228,7 +229,7 @@ int fs_file_getline(char **lineptr, size_t *n, FILE *stream) { if (!dir) return NULL; - strncpy(dir->dd_name, name, strlen(name)); + util_strncpy(dir->dd_name, name, strlen(name)); return dir; } @@ -248,8 +249,8 @@ int fs_file_getline(char **lineptr, size_t *n, FILE *stream) { if (*dir->dd_name) { size_t n = strlen(dir->dd_name); if ((dirname = (char*)mem_a(n + 5) /* 4 + 1 */)) { - strncpy(dirname, dir->dd_name, n); - strncpy(dirname + n, "\\*.*", 4); /* 4 + 1 */ + util_strncpy(dirname, dir->dd_name, n); + util_strncpy(dirname + n, "\\*.*", 4); /* 4 + 1 */ } } else { if (!(dirname = util_strdup("\\*.*"))) @@ -269,7 +270,7 @@ int fs_file_getline(char **lineptr, size_t *n, FILE *stream) { return NULL; if ((data = (struct dirent*)mem_a(sizeof(struct dirent)))) { - strncpy(data->d_name, info.cFileName, FILENAME_MAX - 1); + util_strncpy(data->d_name, info.cFileName, FILENAME_MAX - 1); data->d_name[FILENAME_MAX - 1] = '\0'; /* terminate */ data->d_namlen = strlen(data->d_name); } @@ -283,13 +284,6 @@ int fs_file_getline(char **lineptr, size_t *n, FILE *stream) { int fs_dir_make(const char *path) { return !CreateDirectory(path, NULL); } - - /* - * Visual studio also lacks S_ISDIR for sys/stat.h, so we emulate this as well - * which is not hard at all. - */ -# undef S_ISDIR -# define S_ISDIR(X) ((X)&_S_IFDIR) #else # if !defined(__MINGW32__) # include /* mkdir */ diff --git a/ftepp.c b/ftepp.c old mode 100644 new mode 100755 index 9d0fed9..b07899a --- a/ftepp.c +++ b/ftepp.c @@ -82,7 +82,7 @@ static uint32_t ftepp_predef_randval = 0; /* __DATE__ */ char *ftepp_predef_date(lex_file *context) { - struct tm *itime; + 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 */ @@ -91,7 +91,12 @@ char *ftepp_predef_date(lex_file *context) { /* get time */ time (&rtime); + +#ifdef _MSC_VER + localtime_s(itime, &rtime); +#else itime = localtime(&rtime); +#endif strftime(value, 82, "\"%b %d %Y\"", itime); @@ -100,7 +105,7 @@ char *ftepp_predef_date(lex_file *context) { /* __TIME__ */ char *ftepp_predef_time(lex_file *context) { - struct tm *itime; + 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 */ @@ -109,7 +114,12 @@ char *ftepp_predef_time(lex_file *context) { /* get time */ time (&rtime); + +#ifdef _MSC_VER + localtime_s(itime, &rtime); +#else itime = localtime(&rtime); +#endif strftime(value, 82, "\"%X\"", itime); @@ -126,7 +136,7 @@ char *ftepp_predef_line(lex_file *context) { 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); - snprintf(value, length, "\"%s\"", context->name); + util_snprintf(value, length, "\"%s\"", context->name); return value; } @@ -312,7 +322,7 @@ static GMQCC_INLINE void ftepp_update_output_condition(ftepp_t *ftepp) static GMQCC_INLINE ppmacro* ftepp_macro_find(ftepp_t *ftepp, const char *name) { - return util_htget(ftepp->macros, name); + return (ppmacro*)util_htget(ftepp->macros, name); } static GMQCC_INLINE void ftepp_macro_delete(ftepp_t *ftepp, const char *name) @@ -832,7 +842,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param if (resetline && !ftepp->in_macro) { char lineno[128]; - snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline)); + util_snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline)); ftepp_out(ftepp, lineno, false); } @@ -1432,7 +1442,7 @@ static bool ftepp_include(ftepp_t *ftepp) ftepp_out(ftepp, "\n#pragma file(", false); ftepp_out(ftepp, ctx.file, false); - snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1)); + util_snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1)); ftepp_out(ftepp, lineno, false); /* skip the line */ @@ -1797,12 +1807,12 @@ ftepp_t *ftepp_create() minor[2] = '"'; } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) { ftepp_add_define(ftepp, NULL, "__STD_GMQCC__"); - snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR); - snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR); + util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR); + util_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR); } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCCX) { ftepp_add_define(ftepp, NULL, "__STD_QCCX__"); - snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR); - snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR); + util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR); + util_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 */ diff --git a/gmqcc.h b/gmqcc.h old mode 100644 new mode 100755 index ad185a0..6ae52e9 --- a/gmqcc.h +++ b/gmqcc.h @@ -36,7 +36,6 @@ */ #ifdef _MSC_VER # pragma warning(disable : 4244 ) /* conversion from 'int' to 'float', possible loss of data */ -# pragma warning(disable : 4018 ) /* signed/unsigned mismatch */ #endif /*! _MSC_VER */ #define GMQCC_VERSION_MAJOR 0 @@ -168,17 +167,6 @@ GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \ typedef __int64 int64_t; #endif /*! _MSC_VER */ -/* - *windows makes these prefixed because they're C99 - * TODO: utility versions that are type-safe and not - * just plain textual subsitution. - */ -#ifdef _MSC_VER -# define snprintf(X, Y, Z, ...) _snprintf(X, Y, Z, __VA_ARGS__) - /* strtof doesn't exist -> strtod does though :) */ -# define strtof(X, Y) (float)(strtod(X, Y)) -#endif /*! _MSC_VER */ - /* * Very roboust way at determining endianess at compile time: this handles * almost every possible situation. Otherwise a runtime check has to be @@ -275,7 +263,7 @@ GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \ unsigned short d_reclen; unsigned short d_namlen; char d_name[FILENAME_MAX]; - } + }; typedef struct { struct _finddata_t dd_dta; @@ -284,6 +272,14 @@ GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \ int dd_stat; char dd_name[1]; } DIR; + /* + * Visual studio also lacks S_ISDIR for sys/stat.h, so we emulate this as well + * which is not hard at all. + */ +# ifdef S_ISDIR +# undef S_ISDIR +# endif /*! S_ISDIR */ +# define S_ISDIR(X) ((X)&_S_IFDIR) #else # include #endif /*! _WIN32 && !defined(__MINGW32__) */ @@ -313,8 +309,18 @@ uint16_t util_crc16(uint16_t crc, const char *data, size_t len); void util_seed(uint32_t); uint32_t util_rand(); -int util_vasprintf(char **ret, const char *fmt, va_list); -int util_asprintf (char **ret, const char *fmt, ...); +/* + * 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); #ifdef NOTRACK diff --git a/intrin.h b/intrin.h old mode 100644 new mode 100755 index 4b4c947..4f672dd --- a/intrin.h +++ b/intrin.h @@ -404,7 +404,7 @@ ast_expression *intrin_func(parser_t *parser, const char *name) { if ((find = (void*)parser_find_global(parser, name)) && ((ast_value*)find)->expression.vtype == TYPE_FUNCTION) for (i = 0; i < vec_size(parser->functions); ++i) if (((ast_value*)find)->name && !strcmp(parser->functions[i]->name, ((ast_value*)find)->name) && parser->functions[i]->builtin < 0) - return find; + return (ast_expression*)find; if ((find = util_htget(intrin_intrinsics(), name))) { /* intrinsic is in table. This will "generate the function" so diff --git a/ir.c b/ir.c old mode 100644 new mode 100755 index cabddf4..2552510 --- a/ir.c +++ b/ir.c @@ -3059,7 +3059,7 @@ static ir_value* ir_gen_extparam_proto(ir_builder *ir) ir_value *global; char name[128]; - snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparam_protos))); + util_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); diff --git a/ir.h b/ir.h old mode 100644 new mode 100755 diff --git a/lexer.c b/lexer.c old mode 100644 new mode 100755 diff --git a/lexer.h b/lexer.h old mode 100644 new mode 100755 diff --git a/main.c b/main.c old mode 100644 new mode 100755 diff --git a/msvc/gmqcc.sln b/msvc/gmqcc.sln old mode 100644 new mode 100755 index b87c6f4..39daed8 --- a/msvc/gmqcc.sln +++ b/msvc/gmqcc.sln @@ -1,25 +1,38 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qcvm", "qcvm.vcxproj", "{8DC505A6-6047-4683-BA81-BC4B7A839352}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmqcc", "gmqcc.vcxproj", "{0F0B0779-1A2F-43E9-B833-18C443F7229E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsuite", "testsuite.vcxproj", "{3F8F0021-66B8-43ED-906C-1CFE204E5673}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8DC505A6-6047-4683-BA81-BC4B7A839352}.Release|Win32.ActiveCfg = Release|Win32 - {8DC505A6-6047-4683-BA81-BC4B7A839352}.Release|Win32.Build.0 = Release|Win32 - {0F0B0779-1A2F-43E9-B833-18C443F7229E}.Release|Win32.ActiveCfg = Release|Win32 - {0F0B0779-1A2F-43E9-B833-18C443F7229E}.Release|Win32.Build.0 = Release|Win32 - {3F8F0021-66B8-43ED-906C-1CFE204E5673}.Release|Win32.ActiveCfg = Release|Win32 - {3F8F0021-66B8-43ED-906C-1CFE204E5673}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmqcc", "gmqcc\gmqcc.vcxproj", "{A6BD74E1-31BB-4D00-A9E0-09FF1BC76ED6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qcvm", "qcvm\qcvm.vcxproj", "{DC980E20-C7A8-4112-A517-631DBDA788E7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pak", "pak\pak.vcxproj", "{A6F66BE9-57EF-4E93-AA9D-6E0C8B0990AD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsuite", "testsuite\testsuite.vcxproj", "{7E2839D9-9C1A-4489-9FF9-FDC854EBED3D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A6BD74E1-31BB-4D00-A9E0-09FF1BC76ED6}.Debug|Win32.ActiveCfg = Debug|Win32 + {A6BD74E1-31BB-4D00-A9E0-09FF1BC76ED6}.Debug|Win32.Build.0 = Debug|Win32 + {A6BD74E1-31BB-4D00-A9E0-09FF1BC76ED6}.Release|Win32.ActiveCfg = Release|Win32 + {A6BD74E1-31BB-4D00-A9E0-09FF1BC76ED6}.Release|Win32.Build.0 = Release|Win32 + {DC980E20-C7A8-4112-A517-631DBDA788E7}.Debug|Win32.ActiveCfg = Debug|Win32 + {DC980E20-C7A8-4112-A517-631DBDA788E7}.Debug|Win32.Build.0 = Debug|Win32 + {DC980E20-C7A8-4112-A517-631DBDA788E7}.Release|Win32.ActiveCfg = Release|Win32 + {DC980E20-C7A8-4112-A517-631DBDA788E7}.Release|Win32.Build.0 = Release|Win32 + {A6F66BE9-57EF-4E93-AA9D-6E0C8B0990AD}.Debug|Win32.ActiveCfg = Debug|Win32 + {A6F66BE9-57EF-4E93-AA9D-6E0C8B0990AD}.Debug|Win32.Build.0 = Debug|Win32 + {A6F66BE9-57EF-4E93-AA9D-6E0C8B0990AD}.Release|Win32.ActiveCfg = Release|Win32 + {A6F66BE9-57EF-4E93-AA9D-6E0C8B0990AD}.Release|Win32.Build.0 = Release|Win32 + {7E2839D9-9C1A-4489-9FF9-FDC854EBED3D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E2839D9-9C1A-4489-9FF9-FDC854EBED3D}.Debug|Win32.Build.0 = Debug|Win32 + {7E2839D9-9C1A-4489-9FF9-FDC854EBED3D}.Release|Win32.ActiveCfg = Release|Win32 + {7E2839D9-9C1A-4489-9FF9-FDC854EBED3D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc/gmqcc/gmqcc.vcxproj b/msvc/gmqcc/gmqcc.vcxproj new file mode 100755 index 0000000..f184b3b --- /dev/null +++ b/msvc/gmqcc/gmqcc.vcxproj @@ -0,0 +1,90 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {A6BD74E1-31BB-4D00-A9E0-09FF1BC76ED6} + gmqcc + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + + + true + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvc/gmqcc/gmqcc.vcxproj.filters b/msvc/gmqcc/gmqcc.vcxproj.filters new file mode 100755 index 0000000..9272e9f --- /dev/null +++ b/msvc/gmqcc/gmqcc.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvc/gmqcc.vcxproj b/msvc/pak/pak.vcxproj old mode 100644 new mode 100755 similarity index 55% rename from msvc/gmqcc.vcxproj rename to msvc/pak/pak.vcxproj index d8f46a8..ab075a9 --- a/msvc/gmqcc.vcxproj +++ b/msvc/pak/pak.vcxproj @@ -1,78 +1,78 @@ - - - - - Release - Win32 - - - - {0F0B0779-1A2F-43E9-B833-18C443F7229E} - gmqcc - false - - - - Application - false - true - MultiByte - - - - - - - - - - false - - - - Level3 - MaxSpeed - true - true - - - false - true - true - - - - - Del /Q "$(IntDir)\*.tlog" - - - - - $(IntDir) - - - $(IntDir) - - - $(IntDir)conout_gmqcc.o - - - - - - - - - $(IntDir)util_gmqcc.o - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {A6F66BE9-57EF-4E93-AA9D-6E0C8B0990AD} + pak + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + + + true + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvc/pak/pak.vcxproj.filters b/msvc/pak/pak.vcxproj.filters new file mode 100755 index 0000000..745f4ce --- /dev/null +++ b/msvc/pak/pak.vcxproj.filters @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvc/qcvm.vcxproj b/msvc/qcvm/qcvm.vcxproj old mode 100644 new mode 100755 similarity index 54% rename from msvc/qcvm.vcxproj rename to msvc/qcvm/qcvm.vcxproj index 5382279..8892daa --- a/msvc/qcvm.vcxproj +++ b/msvc/qcvm/qcvm.vcxproj @@ -1,67 +1,76 @@ - - - - - Release - Win32 - - - - {8DC505A6-6047-4683-BA81-BC4B7A839352} - qcvm - false - - - - Application - false - true - Unicode - - - - - - - - - - - Level3 - Full - true - true - .;%(AdditionalIncludeDirectories) - AnySuitable - Speed - true - true - QCVM_EXECUTOR=1;%(PreprocessorDefinitions) - - - true - true - true - - - Del /Q "$(IntDir)\*.tlog" - - - - - $(IntDir)conout_qcvm.o - - - $(IntDir) - - - $(IntDir)util_qcvm.o - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {DC980E20-C7A8-4112-A517-631DBDA788E7} + qcvm + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + QCVM_EXECUTOR;%(PreprocessorDefinitions) + + + true + + + + + Level3 + MaxSpeed + true + true + QCVM_EXECUTOR;%(PreprocessorDefinitions) + + + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvc/qcvm/qcvm.vcxproj.filters b/msvc/qcvm/qcvm.vcxproj.filters new file mode 100755 index 0000000..526cd89 --- /dev/null +++ b/msvc/qcvm/qcvm.vcxproj.filters @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/msvc/testsuite.vcxproj b/msvc/testsuite/testsuite.vcxproj old mode 100644 new mode 100755 similarity index 58% rename from msvc/testsuite.vcxproj rename to msvc/testsuite/testsuite.vcxproj index 3e77231..f0207f9 --- a/msvc/testsuite.vcxproj +++ b/msvc/testsuite/testsuite.vcxproj @@ -1,58 +1,74 @@ - - - - - Release - Win32 - - - - {3F8F0021-66B8-43ED-906C-1CFE204E5673} - testsuite - false - - - - Application - false - true - MultiByte - - - - - - - - - - Level3 - MaxSpeed - true - true - - - true - true - true - - - Del /Q "$(IntDir)\*.tlog" - - - - - $(IntDir)conout_testsuite.o - - - - $(IntDir)util_testsuite.o - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {7E2839D9-9C1A-4489-9FF9-FDC854EBED3D} + testsuite + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + + + true + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvc/testsuite/testsuite.vcxproj.filters b/msvc/testsuite/testsuite.vcxproj.filters new file mode 100755 index 0000000..5cd16e3 --- /dev/null +++ b/msvc/testsuite/testsuite.vcxproj.filters @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/opts.c b/opts.c old mode 100644 new mode 100755 index c2e019e..77aa9c0 --- a/opts.c +++ b/opts.c @@ -216,7 +216,7 @@ static size_t opts_ini_parse ( /* section found */ if (*(parse_end = opts_ini_next(parse_beg + 1, ']')) == ']') { * parse_end = '\0'; /* terminate bro */ - strncpy(section_data, parse_beg + 1, sizeof(section_data)); + util_strncpy(section_data, parse_beg + 1, sizeof(section_data)); section_data[sizeof(section_data) - 1] = '\0'; *oldname_data = '\0'; } else if (!error) { @@ -237,7 +237,7 @@ static size_t opts_ini_parse ( opts_ini_rstrip(read_value); /* valid name value pair, lets call down to handler */ - strncpy(oldname_data, read_name, sizeof(oldname_data)); + util_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) diff --git a/pak.c b/pak.c old mode 100644 new mode 100755 index 2ab417d..653a463 --- a/pak.c +++ b/pak.c @@ -95,14 +95,14 @@ static void pak_tree_build(const char *entry) { memset(pathsplit, 0, 56); - strncpy(directory, entry, 56); + util_strncpy(directory, entry, 56); for (itr = 0; (token = pak_tree_sep(&directory, "/")) != NULL; itr++) { elements[itr] = token; } for (jtr = 0; jtr < itr - 1; jtr++) { - strcat(pathsplit, elements[jtr]); - strcat(pathsplit, "/"); + util_strcat(pathsplit, elements[jtr]); + util_strcat(pathsplit, "/"); if (fs_dir_make(pathsplit)) { mem_d(pathsplit); @@ -364,7 +364,7 @@ bool pak_insert_one(pak_file_t *pak, const char *file) { return false; } - strncpy(dir.name, file, strlen(file)); + util_strncpy(dir.name, file, strlen(file)); /* * Allocate some memory for loading in the data that will be diff --git a/parser.c b/parser.c old mode 100644 new mode 100755 index 66c3726..836f6ca --- a/parser.c +++ b/parser.c @@ -257,10 +257,10 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do { size_t hash = util_hthash(parser->ht_imm_string, str); ast_value *out; - if ( (out = util_htgeth(parser->ht_imm_string, str, hash)) ) { + if ( (out = (ast_value*)util_htgeth(parser->ht_imm_string, str, hash)) ) { if (dotranslate && out->name[0] == '#') { char name[32]; - snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++)); + util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++)); ast_value_set_name(out, name); } return out; @@ -273,7 +273,7 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do */ if (dotranslate) { char name[32]; - snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++)); + util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++)); out = ast_value_new(parser_ctx(parser), name, TYPE_STRING); } else out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING); @@ -4227,13 +4227,13 @@ static bool parse_function_body(parser_t *parser, ast_value *var) 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; - snprintf(name, sizeof(name), "%s##va##SET", var->name); + util_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; } - snprintf(name, sizeof(name), "%s##va##GET", var->name); + util_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); @@ -5533,10 +5533,10 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield */ if (var->expression.vtype == TYPE_ARRAY) { char name[1024]; - snprintf(name, sizeof(name), "%s##SET", var->name); + util_snprintf(name, sizeof(name), "%s##SET", var->name); if (!parser_create_array_setter(parser, var, name)) goto cleanup; - snprintf(name, sizeof(name), "%s##GET", var->name); + util_snprintf(name, sizeof(name), "%s##GET", var->name); if (!parser_create_array_getter(parser, var, var->expression.next, name)) goto cleanup; } @@ -5554,14 +5554,14 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield goto cleanup; } - snprintf(name, sizeof(name), "%s##SETF", var->name); + util_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; - snprintf(name, sizeof(name), "%s##GETFP", var->name); + util_snprintf(name, sizeof(name), "%s##GETFP", var->name); if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) { ast_delete(tfield); goto cleanup; diff --git a/test.c b/test.c old mode 100644 new mode 100755 index 2ede2ae..6987bb3 --- a/test.c +++ b/test.c @@ -488,7 +488,7 @@ task_template_t *task_template_compile(const char *file, const char *dir, size_t FILE *tempfile = NULL; task_template_t *tmpl = NULL; - snprintf(fullfile, sizeof(fullfile), "%s/%s", dir, file); + util_snprintf(fullfile, sizeof(fullfile), "%s/%s", dir, file); tempfile = fs_file_open(fullfile, "r"); tmpl = (task_template_t*)mem_a(sizeof(task_template_t)); @@ -657,7 +657,7 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { dir = fs_dir_open(curdir); while ((files = fs_dir_read(dir))) { - snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name); + util_snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name); if (stat(buffer, &directory) == -1) { con_err("internal error: stat failed, aborting\n"); @@ -697,7 +697,16 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { * 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 /* * Generate the command required to open a pipe to a process @@ -707,7 +716,7 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { if (strcmp(tmpl->proceduretype, "-pp")) { if (qcflags) { if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) { - snprintf(buf, sizeof(buf), "%s %s/%s %s %s -o %s", + util_snprintf(buf, sizeof(buf), "%s %s/%s %s %s -o %s", task_bins[TASK_COMPILE], curdir, tmpl->sourcefile, @@ -716,7 +725,7 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { tmpl->tempfilename ); } else { - snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s %s -o %s", + util_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s %s -o %s", task_bins[TASK_COMPILE], curdir, defs, @@ -729,7 +738,7 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { } } else { if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) { - snprintf(buf, sizeof(buf), "%s %s/%s %s -o %s", + util_snprintf(buf, sizeof(buf), "%s %s/%s %s -o %s", task_bins[TASK_COMPILE], curdir, tmpl->sourcefile, @@ -737,7 +746,7 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { tmpl->tempfilename ); } else { - snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s -o %s", + util_snprintf(buf, sizeof(buf), "%s %s/%s %s/%s %s -o %s", task_bins[TASK_COMPILE], curdir, defs, @@ -751,14 +760,14 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { } else { /* Preprocessing (qcflags mean shit all here we don't allow them) */ if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) { - snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s", + util_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s", task_bins[TASK_COMPILE], curdir, tmpl->sourcefile, tmpl->tempfilename ); } else { - snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s", + util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s", task_bins[TASK_COMPILE], curdir, defs, @@ -786,14 +795,14 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { * Open up some file desciptors for logging the stdout/stderr * to our own. */ - snprintf(buf, sizeof(buf), "%s.stdout", tmpl->tempfilename); + util_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; } - snprintf(buf, sizeof(buf), "%s.stderr", tmpl->tempfilename); + util_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); @@ -829,7 +838,7 @@ void task_precleanup(const char *curdir) { strstr(files->d_name, ".stdout") || strstr(files->d_name, ".stderr")) { - snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name); + util_snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name); if (remove(buffer)) con_err("error removing temporary file: %s\n", buffer); else @@ -891,6 +900,7 @@ void task_destroy(void) { */ bool task_trymatch(task_template_t *tmpl, char ***line) { bool success = true; + bool preprocessing = false; FILE *execute; char buffer[4096]; memset (buffer,0,sizeof(buffer)); @@ -901,12 +911,12 @@ bool task_trymatch(task_template_t *tmpl, char ***line) { * actually specified. */ if (!strcmp(tmpl->executeflags, "$null")) { - snprintf(buffer, sizeof(buffer), "%s %s", + util_snprintf(buffer, sizeof(buffer), "%s %s", task_bins[TASK_EXECUTE], tmpl->tempfilename ); } else { - snprintf(buffer, sizeof(buffer), "%s %s %s", + util_snprintf(buffer, sizeof(buffer), "%s %s %s", task_bins[TASK_EXECUTE], tmpl->executeflags, tmpl->tempfilename @@ -928,6 +938,8 @@ bool task_trymatch(task_template_t *tmpl, char ***line) { */ if (!(execute = fs_file_open(tmpl->tempfilename, "r"))) return false; + + preprocessing = true; } /* @@ -944,7 +956,10 @@ bool task_trymatch(task_template_t *tmpl, char ***line) { tmpl->description, tmpl->rulesfile ); - pclose(execute); + if (preprocessing) + fs_file_close(execute); + else + pclose(execute); return false; } @@ -983,7 +998,7 @@ bool task_trymatch(task_template_t *tmpl, char ***line) { data = NULL; } - if (strcmp(tmpl->proceduretype, "-pp")) + if (!preprocessing) pclose(execute); else fs_file_close(execute); @@ -1017,11 +1032,11 @@ void task_schedualize(size_t *pad) { size_t i = 0; size_t j = 0; - snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks)); + util_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])); - snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1)); + util_snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1)); con_out("test #%u %*s", i + 1, strlen(space[0]) - strlen(space[1]), ""); diff --git a/utf8.c b/utf8.c old mode 100644 new mode 100755 diff --git a/util.c b/util.c old mode 100644 new mode 100755 index b7e3c7c..abc102f --- a/util.c +++ b/util.c @@ -688,14 +688,13 @@ int util_vasprintf(char **dat, const char *fmt, va_list args) { * will return the required amount to allocate. */ #ifdef _MSC_VER - char *str; if ((len = _vscprintf(fmt, args)) < 0) { *dat = NULL; return -1; } - tmp = mem_a(len + 1); - if ((ret = _vsnprintf(tmp, len+1, fmt, args)) != len) { + tmp = (char*)mem_a(len + 1); + if ((ret = _vsnprintf_s(tmp, len+1, len+1, fmt, args)) != len) { mem_d(tmp); *dat = NULL; return -1; @@ -742,6 +741,92 @@ int util_asprintf(char **ret, const char *fmt, ...) { return read; } +/* + * These are various re-implementations (wrapping the real ones) of + * string functions that MSVC consideres unsafe. We wrap these up and + * use the safe varations 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 */ + /* * Implementation of the Mersenne twister PRNG (pseudo random numer * generator). Implementation of MT19937. Has a period of 2^19937-1