X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=test.c;h=8751fd5798196225ecd0002786946da082184403;hp=7722af26a4a5caae39c636fcfc6ee78be72e40e4;hb=d411d6068524252056039f543fcebcad480a5b24;hpb=3d115760a0f2f4fd313aefbd94b512d441208336 diff --git a/test.c b/test.c index 7722af2..8751fd5 100644 --- a/test.c +++ b/test.c @@ -20,10 +20,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "gmqcc.h" +#include +#include #include #include +#include "gmqcc.h" + opts_cmd_t opts; static const char *task_bins[] = { @@ -60,7 +63,7 @@ typedef struct { int pid; } popen_t; -FILE ** 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]; @@ -101,13 +104,13 @@ FILE ** task_popen(const char *command, const char *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 */ - if (argv) - vec_free(argv); + vec_free(argv); return data->handles; } else if (data->pid == 0) { /* child */ @@ -116,9 +119,9 @@ FILE ** task_popen(const char *command, const char *mode) { close(errhandle[0]); /* see piping documentation for this sillyness :P */ - close(0); (void)!dup(inhandle [0]); - close(1); (void)!dup(outhandle[1]); - close(2); (void)!dup(errhandle[1]); + dup2(inhandle [0], 0); + dup2(outhandle[1], 1); + dup2(errhandle[1], 2); execvp(*argv, argv); exit(EXIT_FAILURE); @@ -132,12 +135,11 @@ task_popen_error_2: close(outhandle[0]), close(outhandle[1]); task_popen_error_1: close(inhandle [0]), close(inhandle [1]); task_popen_error_0: - if (argv) - vec_free(argv); + vec_free(argv); return NULL; } -int task_pclose(FILE **handles) { +static int task_pclose(FILE **handles) { popen_t *data = (popen_t*)handles; int status = 0; @@ -158,7 +160,7 @@ int task_pclose(FILE **handles) { char name_out[L_tmpnam]; } popen_t; - FILE **task_popen(const char *command, const char *mode) { + static FILE **task_popen(const char *command, const char *mode) { char *cmd = NULL; popen_t *open = (popen_t*)mem_a(sizeof(popen_t)); @@ -179,7 +181,7 @@ int task_pclose(FILE **handles) { return open->handles; } - void task_pclose(FILE **files) { + static void task_pclose(FILE **files) { popen_t *open = ((popen_t*)files); fs_file_close(files[1]); fs_file_close(files[2]); @@ -281,7 +283,7 @@ typedef struct { * This is very much like a compiler code generator :-). This generates * a value from some data observed from the compiler. */ -bool task_template_generate(task_template_t *tmpl, char tag, const char *file, size_t line, char *value, size_t *pad) { +static bool task_template_generate(task_template_t *tmpl, char tag, const char *file, size_t line, char *value, size_t *pad) { size_t desclen = 0; size_t filelen = 0; char **destval = NULL; @@ -297,7 +299,7 @@ bool task_template_generate(task_template_t *tmpl, char tag, const char *file, s case 'I': destval = &tmpl->sourcefile; break; case 'F': destval = &tmpl->testflags; break; default: - con_printmsg(LVL_ERROR, __FILE__, __LINE__, "internal error", + con_printmsg(LVL_ERROR, __FILE__, __LINE__, 0, "internal error", "invalid tag `%c:` during code generation\n", tag ); @@ -309,7 +311,7 @@ bool task_template_generate(task_template_t *tmpl, char tag, const char *file, s * assigned value. */ if (*destval) { - con_printmsg(LVL_ERROR, file, line, "compile error", + con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "compile error", "tag `%c:` already assigned value: %s\n", tag, *destval ); @@ -322,6 +324,8 @@ bool task_template_generate(task_template_t *tmpl, char tag, const char *file, s */ if (value && *value && (*value == ' ' || *value == '\t')) value++; + else if (!value) + exit(EXIT_FAILURE); /* * Value will contain a newline character at the end, we need to strip @@ -329,8 +333,6 @@ bool task_template_generate(task_template_t *tmpl, char tag, const char *file, s */ if (strchr(value, '\n')) *strrchr(value, '\n')='\0'; - else /* cppcheck: possible nullpointer dereference */ - exit(EXIT_FAILURE); /* * Now allocate and set the actual value for the specific tag. Which @@ -354,7 +356,7 @@ bool task_template_generate(task_template_t *tmpl, char tag, const char *file, s return true; } -bool task_template_parse(const char *file, task_template_t *tmpl, FILE *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; @@ -377,7 +379,7 @@ bool task_template_parse(const char *file, task_template_t *tmpl, FILE *fp, size */ case '/': if (data[1] != '/') { - con_printmsg(LVL_ERROR, file, line, "tmpl parse error", + con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error", "invalid character `/`, perhaps you meant `//` ?"); mem_d(back); @@ -407,14 +409,14 @@ bool task_template_parse(const char *file, task_template_t *tmpl, FILE *fp, size case 'I': case 'F': if (data[1] != ':') { - con_printmsg(LVL_ERROR, file, line, "tmpl parse error", + con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error", "expected `:` after `%c`", *data ); goto failure; } if (!task_template_generate(tmpl, *data, file, line, &data[3], pad)) { - con_printmsg(LVL_ERROR, file, line, "tmpl compile error", + con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl compile error", "failed to generate for given task\n" ); goto failure; @@ -429,7 +431,7 @@ bool task_template_parse(const char *file, task_template_t *tmpl, FILE *fp, size { char *value = &data[3]; if (data[1] != ':') { - con_printmsg(LVL_ERROR, file, line, "tmpl parse error", + con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error", "expected `:` after `%c`", *data ); @@ -454,7 +456,7 @@ bool task_template_parse(const char *file, task_template_t *tmpl, FILE *fp, size } default: - con_printmsg(LVL_ERROR, file, line, "tmpl parse error", + con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error", "invalid tag `%c`", *data ); goto failure; @@ -471,8 +473,7 @@ bool task_template_parse(const char *file, task_template_t *tmpl, FILE *fp, size return true; failure: - if (back) - mem_d (back); + mem_d (back); return false; } @@ -480,7 +481,7 @@ failure: * Nullifies the template data: used during initialization of a new * template and free. */ -void task_template_nullify(task_template_t *tmpl) { +static void task_template_nullify(task_template_t *tmpl) { if (!tmpl) return; @@ -495,7 +496,7 @@ void task_template_nullify(task_template_t *tmpl) { tmpl->testflags = NULL; } -task_template_t *task_template_compile(const char *file, const char *dir, size_t *pad) { +static task_template_t *task_template_compile(const char *file, const char *dir, size_t *pad) { /* a page should be enough */ char fullfile[4096]; size_t filepadd = 0; @@ -609,7 +610,7 @@ failure: return NULL; } -void task_template_destroy(task_template_t **tmpl) { +static void task_template_destroy(task_template_t **tmpl) { if (!tmpl) return; @@ -637,6 +638,7 @@ void task_template_destroy(task_template_t **tmpl) { * Nullify all the template members otherwise NULL comparision * checks will fail if tmpl pointer is reused. */ + mem_d((*tmpl)->tempfilename); mem_d(*tmpl); } @@ -660,7 +662,7 @@ static task_t *task_tasks = NULL; * Read a directory and searches for all template files in it * which is later used to run all tests. */ -bool task_propagate(const char *curdir, size_t *pad, const char *defs) { +static bool task_propagate(const char *curdir, size_t *pad, const char *defs) { bool success = true; DIR *dir; struct dirent *files; @@ -692,6 +694,7 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { char *qcflags = NULL; task_t task; + task.compiled = false; util_debug("TEST", "compiling task template: %s/%s\n", curdir, files->d_name); found ++; if (!tmpl) { @@ -704,7 +707,7 @@ 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", curdir, files->d_name); + util_asprintf(&tmpl->tempfilename, "%s/TMPDAT.%s.dat", curdir, files->d_name); /* * Additional QCFLAGS enviroment variable may be used @@ -840,7 +843,7 @@ bool task_propagate(const char *curdir, size_t *pad, const char *defs) { * Task precleanup removes any existing temporary files or log files * left behind from a previous invoke of the test-suite. */ -void task_precleanup(const char *curdir) { +static void task_precleanup(const char *curdir) { DIR *dir; struct dirent *files; char buffer[4096]; @@ -863,7 +866,7 @@ void task_precleanup(const char *curdir) { fs_dir_close(dir); } -void task_destroy(void) { +static void task_destroy(void) { /* * Free all the data in the task list and finally the list itself * then proceed to cleanup anything else outside the program like @@ -894,7 +897,7 @@ void task_destroy(void) { else util_debug("TEST", "removed stderr log file: %s\n", task_tasks[i].stderrlogfile); - remove(task_tasks[i].tmpl->tempfilename); + (void)!remove(task_tasks[i].tmpl->tempfilename); } /* free util_strdup data for log files */ @@ -912,7 +915,7 @@ void task_destroy(void) { * messages IF the procedure type is -execute, otherwise it matches * the preprocessor output. */ -bool task_trymatch(task_template_t *tmpl, char ***line) { +static bool task_trymatch(task_template_t *tmpl, char ***line) { bool success = true; bool preprocessing = false; FILE *execute; @@ -1020,7 +1023,7 @@ bool task_trymatch(task_template_t *tmpl, char ***line) { return success; } -const char *task_type(task_template_t *tmpl) { +static const char *task_type(task_template_t *tmpl) { if (!strcmp(tmpl->proceduretype, "-pp")) return "type: preprocessor"; if (!strcmp(tmpl->proceduretype, "-execute")) @@ -1037,7 +1040,7 @@ const char *task_type(task_template_t *tmpl) { * from thin air and executed INLINE. */ #include -void task_schedualize(size_t *pad) { +static void task_schedualize(size_t *pad) { char space[2][64]; bool execute = false; char *data = NULL; @@ -1210,7 +1213,7 @@ void task_schedualize(size_t *pad) { * * It expects con_init() was called before hand. */ -GMQCC_WARN bool test_perform(const char *curdir, const char *defs) { +static GMQCC_WARN bool test_perform(const char *curdir, const char *defs) { static const char *default_defs = "defs.qh"; size_t pad[] = { @@ -1283,6 +1286,7 @@ int main(int argc, char **argv) { char *defs = NULL; con_init(); + OPTS_OPTION_U16(OPTION_MEMDUMPCOLS) = 16; /* * Command line option parsing commences now We only need to support @@ -1321,7 +1325,7 @@ int main(int argc, char **argv) { } con_change(redirout, redirerr); succeed = test_perform("tests", defs); - util_meminfo(); + stat_info(); return (succeed) ? EXIT_SUCCESS : EXIT_FAILURE;