]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - test.c
More cleanup
[xonotic/gmqcc.git] / test.c
diff --git a/test.c b/test.c
index 2672cb6a93fa955cf6f772d49ec41348aa1789a6..2c985f0fad87d7ead73d61d3133adc9184e2c0ec 100644 (file)
--- a/test.c
+++ b/test.c
@@ -1,67 +1,30 @@
-/*
- * 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.
- */
-#define GMQCC_PLATFORM_HEADER /* TODO: eliminate! */
 #include <stdlib.h>
 #include <string.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <unistd.h>
 
 #include "gmqcc.h"
-#include "platform.h"
 
 static const char *task_bins[] = {
     "./gmqcc",
     "./qcvm"
 };
 
-/*
- * TODO: Windows version
- * this implements a unique bi-directional popen-like function that
- * allows reading data from both stdout and stderr. And writing to
- * stdin :)
- *
- * Example of use:
- * FILE *handles[3] = task_popen("ls", "-l", "r");
- * if (!handles) { perror("failed to open stdin/stdout/stderr to ls");
- * // handles[0] = stdin
- * // handles[1] = stdout
- * // handles[2] = stderr
- *
- * task_pclose(handles); // to close
- */
-#ifndef _WIN32
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <unistd.h>
 typedef struct {
-    fs_file_t *handles[3];
-    int        pipes  [3];
-
+    FILE *handles[3];
+    int pipes[3];
     int stderr_fd;
     int stdout_fd;
     int pid;
 } popen_t;
 
-static fs_file_t **task_popen(const char *command, const char *mode) {
+static FILE **task_popen(const char *command, const char *mode) {
     int     inhandle  [2];
     int     outhandle [2];
     int     errhandle [2];
@@ -85,7 +48,7 @@ static fs_file_t **task_popen(const char *command, const char *mode) {
             while (*line != '\0' && *line != ' ' &&
                    *line != '\t' && *line != '\n') line++;
         }
-        vec_push(argv, '\0');
+        vec_push(argv, (char *)0);
     }
 
 
@@ -95,17 +58,15 @@ static fs_file_t **task_popen(const char *command, const char *mode) {
 
     if ((data->pid = fork()) > 0) {
         /* parent */
-        close(inhandle  [0]);
+        close(inhandle [0]);
         close(outhandle [1]);
         close(errhandle [1]);
-
-        data->pipes  [0] = inhandle [1];
-        data->pipes  [1] = outhandle[0];
-        data->pipes  [2] = errhandle[0];
-
-        data->handles[0] = (fs_file_t*)fdopen(inhandle [1], "w");
-        data->handles[1] = (fs_file_t*)fdopen(outhandle[0], mode);
-        data->handles[2] = (fs_file_t*)fdopen(errhandle[0], mode);
+        data->pipes[0] = inhandle [1];
+        data->pipes[1] = outhandle[0];
+        data->pipes[2] = errhandle[0];
+        data->handles[0] = fdopen(inhandle [1], "w");
+        data->handles[1] = fdopen(outhandle[0], mode);
+        data->handles[2] = fdopen(errhandle[0], mode);
 
         /* sigh */
         vec_free(argv);
@@ -137,7 +98,7 @@ task_popen_error_0:
     return NULL;
 }
 
-static int task_pclose(fs_file_t **handles) {
+static int task_pclose(FILE **handles) {
     popen_t *data   = (popen_t*)handles;
     int      status = 0;
 
@@ -151,50 +112,6 @@ static int task_pclose(fs_file_t **handles) {
 
     return status;
 }
-#else
-    typedef struct {
-        fs_file_t *handles[3];
-        char       name_err[L_tmpnam];
-        char       name_out[L_tmpnam];
-    } popen_t;
-
-    static fs_file_t **task_popen(const char *command, const char *mode) {
-        char    *cmd  = NULL;
-        popen_t *open = (popen_t*)mem_a(sizeof(popen_t));
-
-        util_tmpnam(open->name_err);
-        util_tmpnam(open->name_out);
-
-        (void)mode; /* excluded */
-
-        util_asprintf(&cmd, "%s -redirout=%s -redirerr=%s", command, open->name_out, open->name_err);
-
-        system(cmd); /* HACK */
-        open->handles[0] = NULL;
-        open->handles[1] = fs_file_open(open->name_out, "r");
-        open->handles[2] = fs_file_open(open->name_err, "r");
-
-        mem_d(cmd);
-
-        return open->handles;
-    }
-
-    static int task_pclose(fs_file_t **files) {
-        popen_t *open = ((popen_t*)files);
-
-        fs_file_close(files[1]);
-        fs_file_close(files[2]);
-
-        remove(open->name_err);
-        remove(open->name_out);
-
-        mem_d(open);
-
-        return EXIT_SUCCESS;
-    }
-#   define popen _popen
-#   define pclose _pclose
-#endif /*! _WIN32 */
 
 #define TASK_COMPILE    0
 #define TASK_EXECUTE    1
@@ -360,7 +277,7 @@ static bool task_template_generate(task_template_t *tmpl, char tag, const char *
     return true;
 }
 
-static bool task_template_parse(const char *file, task_template_t *tmpl, fs_file_t *fp, size_t *pad) {
+static bool task_template_parse(const char *file, task_template_t *tmpl, FILE *fp, size_t *pad) {
     char  *data = NULL;
     char  *back = NULL;
     size_t size = 0;
@@ -370,7 +287,7 @@ static bool task_template_parse(const char *file, task_template_t *tmpl, fs_file
         return false;
 
     /* top down parsing */
-    while (fs_file_getline(&back, &size, fp) != FS_FILE_EOF) {
+    while (util_getline(&back, &size, fp) != EOF) {
         /* skip whitespace */
         data = back;
         if (*data && (*data == ' ' || *data == '\t'))
@@ -501,12 +418,12 @@ static task_template_t *task_template_compile(const char *file, const char *dir,
     /* a page should be enough */
     char             fullfile[4096];
     size_t           filepadd = 0;
-    fs_file_t       *tempfile = NULL;
+    FILE       *tempfile = NULL;
     task_template_t *tmpl     = NULL;
 
     util_snprintf(fullfile,    sizeof(fullfile), "%s/%s", dir, file);
 
-    tempfile = fs_file_open(fullfile, "r");
+    tempfile = fopen(fullfile, "r");
     tmpl     = (task_template_t*)mem_a(sizeof(task_template_t));
     task_template_nullify(tmpl);
 
@@ -603,7 +520,7 @@ static task_template_t *task_template_compile(const char *file, const char *dir,
     }
 
 success:
-    fs_file_close(tempfile);
+    fclose(tempfile);
     return tmpl;
 
 failure:
@@ -612,7 +529,7 @@ failure:
      * so the check to see if it's not null here is required.
      */
     if (tempfile)
-        fs_file_close(tempfile);
+        fclose(tempfile);
     mem_d (tmpl);
 
     return NULL;
@@ -656,12 +573,12 @@ static void task_template_destroy(task_template_t *tmpl) {
  */
 typedef struct {
     task_template_t *tmpl;
-    fs_file_t       **runhandles;
-    fs_file_t       *stderrlog;
-    fs_file_t       *stdoutlog;
-    char            *stdoutlogfile;
-    char            *stderrlogfile;
-    bool             compiled;
+    FILE **runhandles;
+    FILE *stderrlog;
+    FILE *stdoutlog;
+    char *stdoutlogfile;
+    char *stderrlogfile;
+    bool compiled;
 } task_t;
 
 static task_t *task_tasks = NULL;
@@ -672,8 +589,8 @@ static task_t *task_tasks = NULL;
  */
 static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
     bool             success = true;
-    fs_dir_t        *dir;
-    fs_dirent_t     *files;
+    DIR       *dir;
+    struct dirent     *files;
     struct stat      directory;
     char             buffer[4096];
     size_t           found = 0;
@@ -682,16 +599,16 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
     size_t           i;
 
     vec_push(directories, claim);
-    dir = fs_dir_open(claim);
+    dir = opendir(claim);
 
     /*
      * Generate a list of subdirectories since we'll be checking them too
      * for tmpl files.
      */
-    while ((files = fs_dir_read(dir))) {
+    while ((files = readdir(dir))) {
         util_asprintf(&claim, "%s/%s", curdir, files->d_name);
         if (stat(claim, &directory) == -1) {
-            fs_dir_close(dir);
+            closedir(dir);
             mem_d(claim);
             return false;
         }
@@ -703,7 +620,7 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
             claim = NULL;
         }
     }
-    fs_dir_close(dir);
+    closedir(dir);
 
     /*
      * Now do all the work, by touching all the directories inside
@@ -711,9 +628,9 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
      * use to run the tests.
      */
     for (i = 0; i < vec_size(directories); i++) {
-        dir = fs_dir_open(directories[i]);
+        dir = opendir(directories[i]);
 
-        while ((files = fs_dir_read(dir))) {
+        while ((files = readdir(dir))) {
             util_snprintf(buffer, sizeof(buffer), "%s/%s", directories[i], files->d_name);
             if (stat(buffer, &directory) == -1) {
                 con_err("internal error: stat failed, aborting\n");
@@ -744,14 +661,14 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
                  * so we don't trample over an existing one.
                  */
                 tmpl->tempfilename = NULL;
-                util_asprintf(&tmpl->tempfilename, "%s/TMPDAT.%s", directories[i], files->d_name);
+                util_asprintf(&tmpl->tempfilename, "%s/TMPDAT.%s.dat", directories[i], files->d_name);
 
                 /*
                  * Additional QCFLAGS enviroment variable may be used
                  * to test compile flags for all tests.  This needs to be
                  * BEFORE other flags (so that the .tmpl can override them)
                  */
-                qcflags = platform_getenv("QCFLAGS");
+                qcflags = getenv("QCFLAGS");
 
                 /*
                  * Generate the command required to open a pipe to a process
@@ -805,19 +722,21 @@ static 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")) {
-                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s",
+                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s -o %s",
                             task_bins[TASK_COMPILE],
                             directories[i],
                             tmpl->sourcefile,
+                            tmpl->compileflags,
                             tmpl->tempfilename
                         );
                     } else {
-                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s",
+                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s %s -o %s",
                             task_bins[TASK_COMPILE],
                             curdir,
                             defs,
                             directories[i],
                             tmpl->sourcefile,
+                            tmpl->compileflags,
                             tmpl->tempfilename
                         );
                     }
@@ -840,23 +759,21 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
                  */
                 util_snprintf(buf,  sizeof(buf), "%s.stdout", tmpl->tempfilename);
                 task.stdoutlogfile = util_strdup(buf);
-                if (!(task.stdoutlog     = fs_file_open(buf, "w"))) {
+                if (!(task.stdoutlog = fopen(buf, "w"))) {
                     con_err("error opening %s for stdout\n", buf);
                     continue;
                 }
 
                 util_snprintf(buf,  sizeof(buf), "%s.stderr", tmpl->tempfilename);
                 task.stderrlogfile = util_strdup(buf);
-                if (!(task.stderrlog = fs_file_open(buf, "w"))) {
+                if (!(task.stderrlog = fopen(buf, "w"))) {
                     con_err("error opening %s for stderr\n", buf);
                     continue;
                 }
-
                 vec_push(task_tasks, task);
             }
         }
-
-        fs_dir_close(dir);
+        closedir(dir);
         mem_d(directories[i]); /* free claimed memory */
     }
     vec_free(directories);
@@ -869,16 +786,17 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
  * left behind from a previous invoke of the test-suite.
  */
 static void task_precleanup(const char *curdir) {
-    fs_dir_t     *dir;
-    fs_dirent_t  *files;
+    DIR     *dir;
+    struct dirent  *files;
     char          buffer[4096];
 
-    dir = fs_dir_open(curdir);
+    dir = opendir(curdir);
 
-    while ((files = fs_dir_read(dir))) {
+    while ((files = readdir(dir))) {
         if (strstr(files->d_name, "TMP")     ||
             strstr(files->d_name, ".stdout") ||
-            strstr(files->d_name, ".stderr"))
+            strstr(files->d_name, ".stderr") ||
+            strstr(files->d_name, ".dat"))
         {
             util_snprintf(buffer, sizeof(buffer), "%s/%s", curdir, files->d_name);
             if (remove(buffer))
@@ -886,7 +804,7 @@ static void task_precleanup(const char *curdir) {
         }
     }
 
-    fs_dir_close(dir);
+    closedir(dir);
 }
 
 static void task_destroy(void) {
@@ -901,8 +819,8 @@ static void task_destroy(void) {
          * Close any open handles to files or processes here.  It's mighty
          * annoying to have to do all this cleanup work.
          */
-        if (task_tasks[i].stdoutlog)  fs_file_close (task_tasks[i].stdoutlog);
-        if (task_tasks[i].stderrlog)  fs_file_close (task_tasks[i].stderrlog);
+        if (task_tasks[i].stdoutlog) fclose(task_tasks[i].stdoutlog);
+        if (task_tasks[i].stderrlog) fclose(task_tasks[i].stderrlog);
 
         /*
          * Only remove the log files if the test actually compiled otherwise
@@ -937,7 +855,7 @@ static bool task_trymatch(size_t i, char ***line) {
     bool             success = true;
     bool             process = true;
     int              retval  = EXIT_SUCCESS;
-    fs_file_t       *execute;
+    FILE       *execute;
     char             buffer[4096];
     task_template_t *tmpl = task_tasks[i].tmpl;
 
@@ -961,7 +879,7 @@ static bool task_trymatch(size_t i, char ***line) {
             );
         }
 
-        execute = (fs_file_t*)popen(buffer, "r");
+        execute = popen(buffer, "r");
         if (!execute)
             return false;
     } else if (!strcmp(tmpl->proceduretype, "-pp")) {
@@ -969,9 +887,8 @@ static bool task_trymatch(size_t i, char ***line) {
          * we're preprocessing, which means we need to read int
          * the produced file and do some really weird shit.
          */
-        if (!(execute = fs_file_open(tmpl->tempfilename, "r")))
+        if (!(execute = fopen(tmpl->tempfilename, "r")))
             return false;
-
         process = false;
     } else {
         /*
@@ -979,9 +896,8 @@ static bool task_trymatch(size_t i, char ***line) {
          * in runhandles[2] (stderr) since that is where the compiler
          * puts it's errors.
          */
-        if (!(execute = fs_file_open(task_tasks[i].stderrlogfile, "r")))
+        if (!(execute = fopen(task_tasks[i].stderrlogfile, "r")))
             return false;
-
         process = false;
     }
 
@@ -994,14 +910,14 @@ static bool task_trymatch(size_t i, char ***line) {
         size_t size    = 0;
         size_t compare = 0;
 
-        while (fs_file_getline(&data, &size, execute) != FS_FILE_EOF) {
+        while (util_getline(&data, &size, execute) != EOF) {
             if (!strcmp(data, "No main function found\n")) {
                 con_err("test failure: `%s` (No main function found) [%s]\n",
                     tmpl->description,
                     tmpl->rulesfile
                 );
                 if (!process)
-                    fs_file_close(execute);
+                    fclose(execute);
                 else
                     pclose((FILE*)execute);
                 return false;
@@ -1065,7 +981,7 @@ static bool task_trymatch(size_t i, char ***line) {
     if (process)
         retval = pclose((FILE*)execute);
     else
-        fs_file_close(execute);
+        fclose(execute);
 
     return success && retval == EXIT_SUCCESS;
 }
@@ -1098,6 +1014,7 @@ static size_t task_schedualize(size_t *pad) {
     size_t i        = 0;
     size_t j        = 0;
     size_t failed   = 0;
+    int    status   = 0;
 
     util_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks));
 
@@ -1127,15 +1044,15 @@ static size_t task_schedualize(size_t *pad) {
          * Read data from stdout first and pipe that stuff into a log file
          * then we do the same for stderr.
          */
-        while (fs_file_getline(&data, &size, task_tasks[i].runhandles[1]) != FS_FILE_EOF) {
-            fs_file_puts(task_tasks[i].stdoutlog, data);
+        while (util_getline(&data, &size, task_tasks[i].runhandles[1]) != EOF) {
+            fputs(data, task_tasks[i].stdoutlog);
 
             if (strstr(data, "failed to open file")) {
                 task_tasks[i].compiled = false;
                 execute                = false;
             }
         }
-        while (fs_file_getline(&data, &size, task_tasks[i].runhandles[2]) != FS_FILE_EOF) {
+        while (util_getline(&data, &size, task_tasks[i].runhandles[2]) != EOF) {
             /*
              * If a string contains an error we just dissalow execution
              * of it in the vm.
@@ -1149,8 +1066,8 @@ static size_t task_schedualize(size_t *pad) {
                 task_tasks[i].compiled = false;
             }
 
-            fs_file_puts (task_tasks[i].stderrlog, data);
-            fs_file_flush(task_tasks[i].stderrlog); /* fast flush for read */
+            fputs(data, task_tasks[i].stderrlog);
+            fflush(task_tasks[i].stderrlog); /* fast flush for read */
         }
 
         if (!task_tasks[i].compiled && strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) {
@@ -1165,7 +1082,9 @@ static size_t task_schedualize(size_t *pad) {
             continue;
         }
 
-        if (task_pclose(task_tasks[i].runhandles) != EXIT_SUCCESS && strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) {
+        status = task_pclose(task_tasks[i].runhandles);
+        if ((!strcmp(task_tasks[i].tmpl->proceduretype, "-fail") && status == EXIT_SUCCESS)
+        ||  ( strcmp(task_tasks[i].tmpl->proceduretype, "-fail") && status == EXIT_FAILURE)) {
             con_out("failure:   `%s` %*s %*s\n",
                 task_tasks[i].tmpl->description,
                 (pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]),
@@ -1356,13 +1275,10 @@ static bool parsecmd(const char *optname, int *argc_, char ***argv_, char **out,
 }
 
 int main(int argc, char **argv) {
-    bool          succeed  = false;
-    char         *redirout = (char*)stdout;
-    char         *redirerr = (char*)stderr;
-    char         *defs     = NULL;
+    bool succeed  = false;
+    char *defs = NULL;
 
     con_init();
-    OPTS_OPTION_U16(OPTION_MEMDUMPCOLS) = 16;
 
     /*
      * Command line option parsing commences now We only need to support
@@ -1373,23 +1289,13 @@ int main(int argc, char **argv) {
         --argc;
 
         if (argv[0][0] == '-') {
-            if (parsecmd("redirout", &argc, &argv, &redirout, 1, false))
+            if (parsecmd("defs", &argc, &argv, &defs, 1, false))
                 continue;
-            if (parsecmd("redirerr", &argc, &argv, &redirerr, 1, false))
-                continue;
-            if (parsecmd("defs",     &argc, &argv, &defs,     1, false))
-                continue;
-
-            con_change(redirout, redirerr);
 
             if (!strcmp(argv[0]+1, "debug")) {
                 OPTS_OPTION_BOOL(OPTION_DEBUG) = true;
                 continue;
             }
-            if (!strcmp(argv[0]+1, "memchk")) {
-                OPTS_OPTION_BOOL(OPTION_MEMCHK) = true;
-                continue;
-            }
             if (!strcmp(argv[0]+1, "nocolor")) {
                 con_color(0);
                 continue;
@@ -1399,9 +1305,7 @@ int main(int argc, char **argv) {
             return -1;
         }
     }
-    con_change(redirout, redirerr);
     succeed = test_perform("tests", defs);
-    stat_info();
 
     return (succeed) ? EXIT_SUCCESS : EXIT_FAILURE;
 }