X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=test.c;h=0559e618c3f64b4b0f1f371a85b06a74f5ba4e03;hb=c9e3c29a259eeb8e1684993a30d2a06a153f5265;hp=a3956e99c9c8d18183b8add937ec5c85f52259f7;hpb=a5e0542f95d8ab316a6faf47b7d3fc07653ac75b;p=xonotic%2Fgmqcc.git diff --git a/test.c b/test.c index a3956e9..0559e61 100644 --- a/test.c +++ b/test.c @@ -23,7 +23,6 @@ #include "gmqcc.h" #include #include -#include opts_cmd_t opts; @@ -50,7 +49,7 @@ char *task_bins[] = { #ifndef _WIN32 #include #include - +#include #include typedef struct { FILE *handles[3]; @@ -157,7 +156,120 @@ int task_pclose(FILE **handles) { return status; } #else +# define _WIN32_LEAN_AND_MEAN +# define popen _popen +# define pclose _pclose +# include +# include +# include + /* + * Bidirectional piping implementation for windows using CreatePipe and DuplicateHandle + + * other hacks. + */ + + typedef struct { + int __dummy; + /* TODO: implement */ + } popen_t; + + FILE **task_popen(const char *command, const char *mode) { + (void)command; + (void)mode; + + /* TODO: implement */ + return NULL; + } + + void task_pclose(FILE **files) { + /* TODO: implement */ + (void)files; + return; + } + +# ifdef __MINGW32__ + /* mingw32 has dirent.h */ +# include +# elif defined (_MSC_VER) + /* + * visual studio lacks dirent.h it's a posix thing + * so we emulate it with the WinAPI. + */ + + struct dirent { + long d_ino; + unsigned short d_reclen; + unsigned short d_namlen; + char d_name[FILENAME_MAX]; + }; + + typedef struct { + struct _finddata_t dd_dta; + struct dirent dd_dir; + long dd_handle; + int dd_stat; + char dd_name[1]; + } DIR; + + DIR *opendir(const char *name) { + DIR *dir = (DIR*)mem_a(sizeof(DIR) + strlen(name)); + if (!dir) + return NULL; + + strcpy(dir->dd_name, name); + return dir; + } + + int closedir(DIR *dir) { + FindClose((HANDLE)dir->dd_handle); + mem_d ((void*)dir); + return 0; + } + + struct dirent *readdir(DIR *dir) { + WIN32_FIND_DATA info; + struct dirent *data; + int rets; + + if (!dir->dd_handle) { + char *dirname; + if (*dir->dd_name) { + size_t n = strlen(dir->dd_name); + if ((dirname = (char*)mem_a(n + 5) /* 4 + 1 */)) { + strcpy(dirname, dir->dd_name); + strcpy(dirname + n, "\\*.*"); /* 4 + 1 */ + } + } else { + if (!(dirname = util_strdup("\\*.*"))) + return NULL; + } + dir->dd_handle = (long)FindFirstFile(dirname, &info); + mem_d(dirname); + rets = !(!dir->dd_handle); + } else if (dir->dd_handle != -11) { + rets = FindNextFile ((HANDLE)dir->dd_handle, &info); + } else { + rets = 0; + } + + if (!rets) + return NULL; + + if ((data = (struct dirent*)mem_a(sizeof(struct dirent)))) { + strncpy(data->d_name, info.cFileName, FILENAME_MAX - 1); + data->d_name[FILENAME_MAX - 1] = '\0'; /* terminate */ + data->d_namlen = strlen(data->d_name); + } + return data; + } + + /* + * 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 /* undef just incase */ +# define S_ISDIR(X) ((X)&_S_IFDIR) +# endif #endif #define TASK_COMPILE 0 @@ -201,6 +313,9 @@ int task_pclose(FILE **handles) { * This simply performs compilation only * -execute * This will perform compilation and execution + * -fail + * This will perform compilation, but requires + * the compilation to fail in order to succeed. * * This must be provided, this tag is NOT optional. * @@ -521,6 +636,12 @@ task_template_t *task_template_compile(const char *file, const char *dir) { con_err("template compile error: %s missing `M:` tag (use `$null` for exclude)\n", file); goto failure; } + } else if (!strcmp(template->proceduretype, "-fail")) { + if (template->executeflags) + con_err("template compile warning: %s erroneous tag `E:` when only failing\n", file); + if (template->comparematch) + con_err("template compile warning: %s erroneous tag `M:` when only failing\n", file); + goto success; } else { con_err("template compile error: %s invalid procedure type: %s\n", file, template->proceduretype); goto failure; @@ -769,9 +890,10 @@ void task_destroy(const char *curdir) { /* * Only remove the log files if the test actually compiled otherwise - * forget about it. + * forget about it (or if it didn't compile, and the procedure type + * was set to -fail (meaning it shouldn't compile) .. stil remove) */ - if (task_tasks[i].compiled) { + if (task_tasks[i].compiled || !strcmp(task_tasks[i].template->proceduretype, "-fail")) { if (remove(task_tasks[i].stdoutlogfile)) con_err("error removing stdout log file: %s\n", task_tasks[i].stdoutlogfile); else @@ -946,7 +1068,7 @@ void task_schedualize() { fflush(task_tasks[i].stdoutlog); } - if (!task_tasks[i].compiled) { + if (!task_tasks[i].compiled && strcmp(task_tasks[i].template->proceduretype, "-fail")) { con_err("test failure: `%s` [%s] (failed to compile) see %s.stdout and %s.stderr\n", task_tasks[i].template->description, (task_tasks[i].template->failuremessage) ?