mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
more qfcc cleanup. split out some functions and kill some dead code
This commit is contained in:
parent
be28957dff
commit
77d244220b
5 changed files with 570 additions and 531 deletions
|
@ -246,6 +246,18 @@ typedef struct {
|
|||
} options_t;
|
||||
|
||||
extern options_t options;
|
||||
int DecodeArgs (int argc, char **argv);
|
||||
|
||||
extern const char *this_program;
|
||||
extern const char *sourcedir;
|
||||
|
||||
void parse_cpp_name ();
|
||||
void add_cpp_def (const char *arg);
|
||||
FILE * preprocess_file (const char *filename);
|
||||
extern const char *cpp_name;
|
||||
extern struct dstring_s *tempname;
|
||||
|
||||
extern const char *progs_src;
|
||||
|
||||
//XXX eww :/
|
||||
void PrecacheSound (def_t *e, int ch);
|
||||
|
|
|
@ -38,9 +38,9 @@ YFLAGS = -d
|
|||
bin_PROGRAMS= qfcc
|
||||
|
||||
qfcc_SOURCES= \
|
||||
class.c cmdlib.c debug.c emit.c expr.c function.c method.c opcodes.c \
|
||||
pr_def.c pr_imm.c precache.c qc-lex.l qc-parse.y qfcc.c struct.c switch.c \
|
||||
type.c
|
||||
class.c cmdlib.c cpp.c debug.c emit.c expr.c function.c method.c \
|
||||
opcodes.c options.c pr_def.c pr_imm.c precache.c qc-lex.l qc-parse.y \
|
||||
qfcc.c struct.c switch.c type.c
|
||||
|
||||
qfcc_LDADD= $(QFCC_LIBS)
|
||||
qfcc_DEPENDENCIES= $(QFCC_DEPS)
|
||||
|
|
264
tools/qfcc/source/cpp.c
Normal file
264
tools/qfcc/source/cpp.c
Normal file
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
cpp.c
|
||||
|
||||
cpp preprocessing support
|
||||
|
||||
Copyright (C) 2001 #AUTHOR#
|
||||
|
||||
Author: #AUTHOR#
|
||||
Date: #DATE#
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_PROCESS_H
|
||||
# include <process.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "QF/dstring.h"
|
||||
|
||||
#include "qfcc.h"
|
||||
|
||||
typedef struct cpp_arg_s {
|
||||
struct cpp_arg_s *next;
|
||||
const char *arg;
|
||||
} cpp_arg_t;
|
||||
|
||||
cpp_arg_t *cpp_arg_list;
|
||||
cpp_arg_t **cpp_arg_tail = &cpp_arg_list;
|
||||
cpp_arg_t *cpp_def_list;
|
||||
cpp_arg_t **cpp_def_tail = &cpp_def_list;
|
||||
const char **cpp_argv;
|
||||
const char *cpp_name = CPP_NAME;
|
||||
static int cpp_argc = 0;
|
||||
dstring_t *tempname;
|
||||
|
||||
static void
|
||||
add_cpp_arg (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
||||
cpp_arg->next = 0;
|
||||
cpp_arg->arg = arg;
|
||||
*cpp_arg_tail = cpp_arg;
|
||||
cpp_arg_tail = &(*cpp_arg_tail)->next;
|
||||
cpp_argc++;
|
||||
}
|
||||
|
||||
void
|
||||
add_cpp_def (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_def = malloc (sizeof (cpp_arg_t));
|
||||
cpp_def->next = 0;
|
||||
cpp_def->arg = arg;
|
||||
*cpp_def_tail = cpp_def;
|
||||
cpp_def_tail = &(*cpp_def_tail)->next;
|
||||
cpp_argc++;
|
||||
}
|
||||
|
||||
void
|
||||
parse_cpp_name ()
|
||||
{
|
||||
char *n;
|
||||
|
||||
n = strdup (cpp_name);
|
||||
while (*n) {
|
||||
while (*n && *n == ' ')
|
||||
n++;
|
||||
add_cpp_arg (n);
|
||||
while (*n && *n != ' ')
|
||||
n++;
|
||||
if (*n)
|
||||
*n++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
build_cpp_args (const char *in_name, const char *out_name)
|
||||
{
|
||||
cpp_arg_t *cpp_arg;
|
||||
cpp_arg_t *cpp_def;
|
||||
const char **arg;
|
||||
|
||||
if (cpp_argv)
|
||||
free (cpp_argv);
|
||||
cpp_argv = (const char **)malloc ((cpp_argc + 1) * sizeof (char**));
|
||||
for (arg = cpp_argv, cpp_arg = cpp_arg_list;
|
||||
cpp_arg;
|
||||
cpp_arg = cpp_arg->next) {
|
||||
if (!strcmp (cpp_arg->arg, "%d")) {
|
||||
for (cpp_def = cpp_def_list; cpp_def; cpp_def = cpp_def->next)
|
||||
*arg++ = cpp_def->arg;
|
||||
} else if (!strcmp (cpp_arg->arg, "%i")) {
|
||||
*arg++ = in_name;
|
||||
} else if (!strcmp (cpp_arg->arg, "%o")) {
|
||||
*arg++ = out_name;
|
||||
} else {
|
||||
*arg++ = cpp_arg->arg;
|
||||
}
|
||||
}
|
||||
*arg = 0;
|
||||
//for (arg = cpp_argv; *arg; arg++)
|
||||
// printf ("%s ", *arg);
|
||||
//puts ("");
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
FILE *
|
||||
preprocess_file (const char *filename)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
pid_t pid;
|
||||
int tempfd = 0;
|
||||
#endif
|
||||
char *temp1;
|
||||
char *temp2 = strrchr (this_program, PATH_SEPARATOR);
|
||||
|
||||
if (cpp_name) {
|
||||
if (options.save_temps) {
|
||||
char *basename = strdup (filename);
|
||||
char *temp;
|
||||
|
||||
temp = strrchr (basename, '.');
|
||||
if (temp)
|
||||
*temp = '\0'; // ignore the rest of the string
|
||||
|
||||
temp = strrchr (basename, '/');
|
||||
if (!temp)
|
||||
temp = basename;
|
||||
else
|
||||
temp++;
|
||||
|
||||
if (*sourcedir) {
|
||||
dsprintf (tempname, "%s%c%s", sourcedir,
|
||||
PATH_SEPARATOR, temp);
|
||||
} else {
|
||||
dsprintf (tempname, "%s.p", temp);
|
||||
}
|
||||
free (basename);
|
||||
} else {
|
||||
temp1 = getenv ("TMPDIR");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = getenv ("TEMP");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
dsprintf (tempname, "%s%c%sXXXXXX", temp1,
|
||||
PATH_SEPARATOR, temp2 ? temp2 + 1 : this_program);
|
||||
}
|
||||
build_cpp_args (filename, tempname->str);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!options.save_temps)
|
||||
mktemp (tempname->str);
|
||||
|
||||
{
|
||||
FILE *tmp = fopen (tempname->str, "wt");
|
||||
|
||||
fclose (tmp);
|
||||
}
|
||||
|
||||
{
|
||||
int status = spawnvp (_P_WAIT, cpp_argv[0], (char **)cpp_argv);
|
||||
|
||||
if (status) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
status);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
return fopen (tempname->str, "rt");
|
||||
#else
|
||||
if (!options.save_temps)
|
||||
tempfd = mkstemp (tempname->str);
|
||||
|
||||
if ((pid = fork ()) == -1) {
|
||||
perror ("fork");
|
||||
exit (1);
|
||||
}
|
||||
if (!pid) {
|
||||
// we're a child, check for abuse
|
||||
//const char **a;
|
||||
//for (a = cpp_argv; *a; a++)
|
||||
// printf ("%s ", *a);
|
||||
//puts("");
|
||||
execvp (cpp_argv[0], (char **)cpp_argv);
|
||||
fprintf (stderr, "Child shouldn't reach here\n");
|
||||
exit (1);
|
||||
} else {
|
||||
// give parental guidance (or bury it in the back yard)
|
||||
int status;
|
||||
pid_t rc;
|
||||
|
||||
// printf ("pid = %d\n", pid);
|
||||
if ((rc = waitpid (0, &status, 0 | WUNTRACED)) != pid) {
|
||||
if (rc == -1) {
|
||||
perror ("wait");
|
||||
exit (1);
|
||||
}
|
||||
fprintf (stderr, "%s: The wrong child (%ld) died. Don't ask me, I don't know either.\n",
|
||||
this_program,
|
||||
(long) rc);
|
||||
exit (1);
|
||||
}
|
||||
if (WIFEXITED (status)) {
|
||||
if (WEXITSTATUS (status)) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
WEXITSTATUS (status));
|
||||
exit (1);
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "%s: cpp returned prematurely.\n", filename);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
if (options.save_temps)
|
||||
return fopen (tempname->str, "rt");
|
||||
else
|
||||
return fdopen (tempfd, "r+t");
|
||||
#endif
|
||||
}
|
||||
return fopen (filename, "rt");
|
||||
}
|
289
tools/qfcc/source/options.c
Normal file
289
tools/qfcc/source/options.c
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
options.c
|
||||
|
||||
command line options handlnig
|
||||
|
||||
Copyright (C) 2001 #AUTHOR#
|
||||
|
||||
Author: #AUTHOR#
|
||||
Date: #DATE#
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "qfcc.h"
|
||||
|
||||
const char *this_program;
|
||||
|
||||
static struct option const long_options[] = {
|
||||
{"source", required_argument, 0, 's'},
|
||||
{"progs-src", required_argument, 0, 'P'},
|
||||
{"save-temps", no_argument, 0, 'S'},
|
||||
{"quiet", no_argument, 0, 'q'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"code", required_argument, 0, 'C'},
|
||||
{"warn", required_argument, 0, 'W'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"files", no_argument, 0, 'F'},
|
||||
{"traditional", no_argument, 0, 't'},
|
||||
{"strip-path", required_argument, 0, 'p'},
|
||||
{"define", required_argument, 0, 'D'},
|
||||
{"include", required_argument, 0, 'I'},
|
||||
{"undefine", required_argument, 0, 'U'},
|
||||
{"cpp", required_argument, 0, 256},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
static const char *short_options =
|
||||
"s:" // source dir
|
||||
"P:" // progs.src name
|
||||
"F" // generate files.dat
|
||||
"q" // quiet
|
||||
"v" // verbose
|
||||
"g" // debug
|
||||
"C:" // code options
|
||||
"W:" // warning options
|
||||
"h" // help
|
||||
"V" // version
|
||||
"p:" // strip path
|
||||
"S" // save temps
|
||||
"D:" // define
|
||||
"I:" // set includes
|
||||
"U:" // undefine
|
||||
;
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
printf ("%s - QuakeForge Code Compiler\n", this_program);
|
||||
printf ("Usage: %s [options]\n", this_program);
|
||||
printf (
|
||||
"Options:\n"
|
||||
" -s, --source DIR Look for progs.src in DIR instead of \".\"\n"
|
||||
" -q, --quiet Inhibit usual output\n"
|
||||
" -v, --verbose Display more output than usual\n"
|
||||
" -g, Generate debuggin info\n"
|
||||
" -C, --code OPTION,... Set code generation options\n"
|
||||
" -W, --warn OPTION,... Set warning options\n"
|
||||
" -h, --help Display this help and exit\n"
|
||||
" -V, --version Output version information and exit\n\n"
|
||||
" -S, --save-temps Do not delete temporary files\n"
|
||||
" -D, --define SYMBOL[=VAL],... Define symbols for the preprocessor\n"
|
||||
" -I, --include DIR,... Set directories for the preprocessor \n"
|
||||
" to search for #includes\n"
|
||||
" -U, --undefine SYMBOL,... Undefine preprocessor symbols\n\n"
|
||||
"For help on options for --code and --warn, see the qfcc(1) manual page\n"
|
||||
);
|
||||
exit (status);
|
||||
}
|
||||
|
||||
int
|
||||
DecodeArgs (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
|
||||
add_cpp_def ("-D__QFCC__=1");
|
||||
add_cpp_def ("-D__QUAKEC__=1");
|
||||
add_cpp_def ("-D__RUAMOKO__=1");
|
||||
add_cpp_def ("-D__RAUMOKO__=1");
|
||||
|
||||
options.code.progsversion = PROG_VERSION;
|
||||
options.warnings.uninited_variable = true;
|
||||
|
||||
options.save_temps = false;
|
||||
options.verbosity = 0;
|
||||
options.strip_path = 0;
|
||||
|
||||
sourcedir = "";
|
||||
progs_src = "progs.src";
|
||||
|
||||
while ((c = getopt_long (argc, argv, short_options, long_options, 0))
|
||||
!= EOF) {
|
||||
switch (c) {
|
||||
case 'h': // help
|
||||
usage (0);
|
||||
break;
|
||||
case 'V': // version
|
||||
printf ("%s version %s\n", PACKAGE, VERSION);
|
||||
exit (0);
|
||||
break;
|
||||
case 's': // src dir
|
||||
sourcedir = strdup (optarg);
|
||||
break;
|
||||
case 'P': // progs-src
|
||||
progs_src = strdup (optarg);
|
||||
break;
|
||||
case 'p':
|
||||
options.strip_path = atoi (optarg);
|
||||
break;
|
||||
case 'F':
|
||||
options.files_dat = true;
|
||||
break;
|
||||
case 'q': // quiet
|
||||
options.verbosity -= 1;
|
||||
break;
|
||||
case 'v': // verbose
|
||||
options.verbosity += 1;
|
||||
break;
|
||||
case 'g': // debug
|
||||
options.code.debug = true;
|
||||
break;
|
||||
case 't': // traditional
|
||||
options.traditional = true;
|
||||
options.code.progsversion = PROG_ID_VERSION;
|
||||
break;
|
||||
case 'C':{ // code options
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
if (!(strcasecmp (temp, "cow"))) {
|
||||
options.code.cow = true;
|
||||
} else if (!(strcasecmp (temp, "no-cow"))) {
|
||||
options.code.cow = false;
|
||||
} else if (!(strcasecmp (temp, "no-cpp"))) {
|
||||
cpp_name = 0;
|
||||
} else if (!(strcasecmp (temp, "debug"))) {
|
||||
options.code.debug = true;
|
||||
} else if (!(strcasecmp (temp, "no-debug"))) {
|
||||
options.code.debug = false;
|
||||
} else if (!(strcasecmp (temp, "v6only"))) {
|
||||
options.code.progsversion = PROG_ID_VERSION;
|
||||
add_cpp_def ("-D__VERSION6__=1");
|
||||
} else if (!(strcasecmp (temp, "no-v6only"))) {
|
||||
options.code.progsversion = PROG_VERSION;
|
||||
}
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 'W':{ // warning options
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
if (!(strcasecmp (temp, "all"))) {
|
||||
options.warnings.cow = true;
|
||||
options.warnings.undefined_function = true;
|
||||
options.warnings.uninited_variable = true;
|
||||
options.warnings.vararg_integer = true;
|
||||
options.warnings.integer_divide = true;
|
||||
} else if (!(strcasecmp (temp, "none"))) {
|
||||
options.warnings.cow = false;
|
||||
options.warnings.undefined_function = false;
|
||||
options.warnings.uninited_variable = false;
|
||||
options.warnings.vararg_integer = false;
|
||||
options.warnings.integer_divide = false;
|
||||
} else if (!(strcasecmp (temp, "cow"))) {
|
||||
options.warnings.cow = true;
|
||||
} else if (!(strcasecmp (temp, "no-cow"))) {
|
||||
options.warnings.cow = false;
|
||||
} else if (!(strcasecmp (temp, "error"))) {
|
||||
options.warnings.promote = true;
|
||||
} else if (!(strcasecmp (temp, "no-error"))) {
|
||||
options.warnings.promote = false;
|
||||
} else if (!(strcasecmp (temp, "undef-function"))) {
|
||||
options.warnings.undefined_function = true;
|
||||
} else if (!(strcasecmp (temp, "no-undef-function"))) {
|
||||
options.warnings.undefined_function = false;
|
||||
} else if (!(strcasecmp (temp, "uninited-var"))) {
|
||||
options.warnings.uninited_variable = true;
|
||||
} else if (!(strcasecmp (temp, "no-uninited-var"))) {
|
||||
options.warnings.uninited_variable = false;
|
||||
} else if (!(strcasecmp (temp, "vararg-integer"))) {
|
||||
options.warnings.vararg_integer = true;
|
||||
} else if (!(strcasecmp (temp, "no-vararg-integer"))) {
|
||||
options.warnings.vararg_integer = false;
|
||||
} else if (!(strcasecmp (temp, "integer-divide"))) {
|
||||
options.warnings.integer_divide = true;
|
||||
} else if (!(strcasecmp (temp, "no-integer-divide"))) {
|
||||
options.warnings.integer_divide = false;
|
||||
}
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 256: // --cpp=
|
||||
cpp_name = strdup (optarg);
|
||||
break;
|
||||
case 'S': // save temps
|
||||
options.save_temps = true;
|
||||
break;
|
||||
case 'D':{ // defines for cpp
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
add_cpp_def (strdup (va ("%s%s", "-D", temp)));
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 'I':{ // includes
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
add_cpp_def (strdup (va ("%s%s", "-I", temp)));
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 'U':{ // undefines
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
add_cpp_def (strdup (va ("%s%s", "-U", temp)));
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
}
|
|
@ -42,15 +42,9 @@ static const char rcsid[] =
|
|||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_PROCESS_H
|
||||
# include <process.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
@ -60,8 +54,6 @@ static const char rcsid[] =
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include <QF/crc.h>
|
||||
#include <QF/dstring.h>
|
||||
#include <QF/hash.h>
|
||||
|
@ -77,47 +69,12 @@ static const char rcsid[] =
|
|||
|
||||
options_t options;
|
||||
|
||||
char *sourcedir;
|
||||
char *progs_src;
|
||||
const char *this_program;
|
||||
|
||||
static struct option const long_options[] = {
|
||||
{"source", required_argument, 0, 's'},
|
||||
{"progs-src", required_argument, 0, 'P'},
|
||||
{"save-temps", no_argument, 0, 'S'},
|
||||
{"quiet", no_argument, 0, 'q'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"code", required_argument, 0, 'C'},
|
||||
{"warn", required_argument, 0, 'W'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"files", no_argument, 0, 'F'},
|
||||
{"traditional", no_argument, 0, 't'},
|
||||
{"strip-path", required_argument, 0, 'p'},
|
||||
{"define", required_argument, 0, 'D'},
|
||||
{"include", required_argument, 0, 'I'},
|
||||
{"undefine", required_argument, 0, 'U'},
|
||||
{"cpp", required_argument, 0, 256},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
const char *sourcedir;
|
||||
const char *progs_src;
|
||||
|
||||
char destfile[1024];
|
||||
char debugfile[1024];
|
||||
|
||||
typedef struct cpp_arg_s {
|
||||
struct cpp_arg_s *next;
|
||||
const char *arg;
|
||||
} cpp_arg_t;
|
||||
|
||||
cpp_arg_t *cpp_arg_list;
|
||||
cpp_arg_t **cpp_arg_tail = &cpp_arg_list;
|
||||
cpp_arg_t *cpp_def_list;
|
||||
cpp_arg_t **cpp_def_tail = &cpp_def_list;
|
||||
const char **cpp_argv;
|
||||
char *cpp_name = CPP_NAME;
|
||||
static int cpp_argc = 0;
|
||||
dstring_t *tempname;
|
||||
|
||||
pr_info_t pr;
|
||||
|
||||
int pr_source_line;
|
||||
|
@ -375,66 +332,6 @@ WriteData (int crc)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
PR_String
|
||||
|
||||
Returns a string suitable for printing (no newlines, max 60 chars length)
|
||||
*/
|
||||
char *
|
||||
PR_String (char *string)
|
||||
{
|
||||
static char buf[80];
|
||||
char *s;
|
||||
|
||||
s = buf;
|
||||
*s++ = '"';
|
||||
while (string && *string) {
|
||||
|
||||
if (s == buf + sizeof (buf) - 2)
|
||||
break;
|
||||
|
||||
if (*string == '\n') {
|
||||
*s++ = '\\';
|
||||
*s++ = 'n';
|
||||
} else if (*string == '"') {
|
||||
*s++ = '\\';
|
||||
*s++ = '"';
|
||||
} else {
|
||||
*s++ = *string;
|
||||
}
|
||||
string++;
|
||||
|
||||
if (s - buf > 60) {
|
||||
*s++ = '.';
|
||||
*s++ = '.';
|
||||
*s++ = '.';
|
||||
break;
|
||||
}
|
||||
}
|
||||
*s++ = '"';
|
||||
*s++ = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
def_t *
|
||||
PR_DefForFieldOfs (gofs_t ofs)
|
||||
{
|
||||
def_t *d;
|
||||
|
||||
for (d = pr.def_head.def_next; d; d = d->def_next) {
|
||||
if (d->type->type != ev_field)
|
||||
continue;
|
||||
if (*((int *) &pr_globals[d->ofs]) == ofs)
|
||||
return d;
|
||||
}
|
||||
|
||||
Error ("PR_DefForFieldOfs: couldn't find %i", ofs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
PR_BeginCompilation
|
||||
|
||||
|
@ -545,429 +442,6 @@ qboolean PR_FinishCompilation (void)
|
|||
return !errors;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
void
|
||||
PR_PrintFunction (def_t *def)
|
||||
{
|
||||
def_t *d;
|
||||
statref_t *r;
|
||||
|
||||
printf ("%s\n", def->name);
|
||||
for (d = def->scope_next; d; d = d->scope_next) {
|
||||
printf ("%s: %d %d %d\n",
|
||||
d->name ? d->name : "<temp>",
|
||||
d->ofs, d->type->type, pr_type_size[d->type->type]);
|
||||
for (r = d->refs; r; r = r->next)
|
||||
printf (" %ld", (long) (r->statement - statements));
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
printf ("%s - QuakeForge Code Compiler\n", this_program);
|
||||
printf ("Usage: %s [options]\n", this_program);
|
||||
printf ("Options:\n"
|
||||
" -s, --source DIR Look for progs.src in DIR instead of \".\"\n"
|
||||
" -q, --quiet Inhibit usual output\n"
|
||||
" -v, --verbose Display more output than usual\n"
|
||||
" -g, Generate debuggin info\n"
|
||||
" -C, --code OPTION,... Set code generation options\n"
|
||||
" -W, --warn OPTION,... Set warning options\n"
|
||||
" -h, --help Display this help and exit\n"
|
||||
" -V, --version Output version information and exit\n\n"
|
||||
" -S, --save-temps Do not delete temporary files\n"
|
||||
" -D, --define SYMBOL[=VAL],... Define symbols for the preprocessor\n"
|
||||
" -I, --include DIR,... Set directories for the preprocessor \n"
|
||||
" to search for #includes\n"
|
||||
" -U, --undefine SYMBOL,... Undefine preprocessor symbols\n\n"
|
||||
"For help on options for --code and --warn, see the qfcc(1) manual page\n");
|
||||
exit (status);
|
||||
}
|
||||
|
||||
static void
|
||||
add_cpp_arg (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
||||
cpp_arg->next = 0;
|
||||
cpp_arg->arg = arg;
|
||||
*cpp_arg_tail = cpp_arg;
|
||||
cpp_arg_tail = &(*cpp_arg_tail)->next;
|
||||
cpp_argc++;
|
||||
}
|
||||
|
||||
static void
|
||||
add_cpp_def (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_def = malloc (sizeof (cpp_arg_t));
|
||||
cpp_def->next = 0;
|
||||
cpp_def->arg = arg;
|
||||
*cpp_def_tail = cpp_def;
|
||||
cpp_def_tail = &(*cpp_def_tail)->next;
|
||||
cpp_argc++;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_cpp_name ()
|
||||
{
|
||||
char *n;
|
||||
|
||||
n = strdup (cpp_name);
|
||||
while (*n) {
|
||||
while (*n && *n == ' ')
|
||||
n++;
|
||||
add_cpp_arg (n);
|
||||
while (*n && *n != ' ')
|
||||
n++;
|
||||
if (*n)
|
||||
*n++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
build_cpp_args (const char *in_name, const char *out_name)
|
||||
{
|
||||
cpp_arg_t *cpp_arg;
|
||||
cpp_arg_t *cpp_def;
|
||||
const char **arg;
|
||||
|
||||
if (cpp_argv)
|
||||
free (cpp_argv);
|
||||
cpp_argv = (const char **)malloc ((cpp_argc + 1) * sizeof (char**));
|
||||
for (arg = cpp_argv, cpp_arg = cpp_arg_list;
|
||||
cpp_arg;
|
||||
cpp_arg = cpp_arg->next) {
|
||||
if (!strcmp (cpp_arg->arg, "%d")) {
|
||||
for (cpp_def = cpp_def_list; cpp_def; cpp_def = cpp_def->next)
|
||||
*arg++ = cpp_def->arg;
|
||||
} else if (!strcmp (cpp_arg->arg, "%i")) {
|
||||
*arg++ = in_name;
|
||||
} else if (!strcmp (cpp_arg->arg, "%o")) {
|
||||
*arg++ = out_name;
|
||||
} else {
|
||||
*arg++ = cpp_arg->arg;
|
||||
}
|
||||
}
|
||||
*arg = 0;
|
||||
//for (arg = cpp_argv; *arg; arg++)
|
||||
// printf ("%s ", *arg);
|
||||
//puts ("");
|
||||
}
|
||||
|
||||
static int
|
||||
DecodeArgs (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
|
||||
add_cpp_def ("-D__QFCC__=1");
|
||||
add_cpp_def ("-D__QUAKEC__=1");
|
||||
add_cpp_def ("-D__RUAMOKO__=1");
|
||||
add_cpp_def ("-D__RAUMOKO__=1");
|
||||
|
||||
options.code.progsversion = PROG_VERSION;
|
||||
options.warnings.uninited_variable = true;
|
||||
|
||||
options.save_temps = false;
|
||||
options.verbosity = 0;
|
||||
options.strip_path = 0;
|
||||
|
||||
sourcedir = "";
|
||||
progs_src = "progs.src";
|
||||
|
||||
while ((c = getopt_long (argc, argv, "s:" // source dir
|
||||
"P:" // progs.src name
|
||||
"F" // generate files.dat
|
||||
"q" // quiet
|
||||
"v" // verbose
|
||||
"g" // debug
|
||||
"C:" // code options
|
||||
"W:" // warning options
|
||||
"h" // help
|
||||
"V" // version
|
||||
"p:" // strip path
|
||||
"S" // save temps
|
||||
"D:" // define
|
||||
"I:" // set includes
|
||||
"U:" // undefine
|
||||
, long_options, (int *) 0)) != EOF) {
|
||||
switch (c) {
|
||||
case 'h': // help
|
||||
usage (0);
|
||||
break;
|
||||
case 'V': // version
|
||||
printf ("%s version %s\n", PACKAGE, VERSION);
|
||||
exit (0);
|
||||
break;
|
||||
case 's': // src dir
|
||||
sourcedir = strdup (optarg);
|
||||
break;
|
||||
case 'P': // progs-src
|
||||
progs_src = strdup (optarg);
|
||||
break;
|
||||
case 'p':
|
||||
options.strip_path = atoi (optarg);
|
||||
break;
|
||||
case 'F':
|
||||
options.files_dat = true;
|
||||
break;
|
||||
case 'q': // quiet
|
||||
options.verbosity -= 1;
|
||||
break;
|
||||
case 'v': // verbose
|
||||
options.verbosity += 1;
|
||||
break;
|
||||
case 'g': // debug
|
||||
options.code.debug = true;
|
||||
break;
|
||||
case 't': // traditional
|
||||
options.traditional = true;
|
||||
options.code.progsversion = PROG_ID_VERSION;
|
||||
break;
|
||||
case 'C':{ // code options
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
if (!(strcasecmp (temp, "cow"))) {
|
||||
options.code.cow = true;
|
||||
} else if (!(strcasecmp (temp, "no-cow"))) {
|
||||
options.code.cow = false;
|
||||
} else if (!(strcasecmp (temp, "no-cpp"))) {
|
||||
cpp_name = 0;
|
||||
} else if (!(strcasecmp (temp, "debug"))) {
|
||||
options.code.debug = true;
|
||||
} else if (!(strcasecmp (temp, "no-debug"))) {
|
||||
options.code.debug = false;
|
||||
} else if (!(strcasecmp (temp, "v6only"))) {
|
||||
options.code.progsversion = PROG_ID_VERSION;
|
||||
add_cpp_def ("-D__VERSION6__=1");
|
||||
} else if (!(strcasecmp (temp, "no-v6only"))) {
|
||||
options.code.progsversion = PROG_VERSION;
|
||||
}
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 'W':{ // warning options
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
if (!(strcasecmp (temp, "all"))) {
|
||||
options.warnings.cow = true;
|
||||
options.warnings.undefined_function = true;
|
||||
options.warnings.uninited_variable = true;
|
||||
options.warnings.vararg_integer = true;
|
||||
options.warnings.integer_divide = true;
|
||||
} else if (!(strcasecmp (temp, "none"))) {
|
||||
options.warnings.cow = false;
|
||||
options.warnings.undefined_function = false;
|
||||
options.warnings.uninited_variable = false;
|
||||
options.warnings.vararg_integer = false;
|
||||
options.warnings.integer_divide = false;
|
||||
} else if (!(strcasecmp (temp, "cow"))) {
|
||||
options.warnings.cow = true;
|
||||
} else if (!(strcasecmp (temp, "no-cow"))) {
|
||||
options.warnings.cow = false;
|
||||
} else if (!(strcasecmp (temp, "error"))) {
|
||||
options.warnings.promote = true;
|
||||
} else if (!(strcasecmp (temp, "no-error"))) {
|
||||
options.warnings.promote = false;
|
||||
} else if (!(strcasecmp (temp, "undef-function"))) {
|
||||
options.warnings.undefined_function = true;
|
||||
} else if (!(strcasecmp (temp, "no-undef-function"))) {
|
||||
options.warnings.undefined_function = false;
|
||||
} else if (!(strcasecmp (temp, "uninited-var"))) {
|
||||
options.warnings.uninited_variable = true;
|
||||
} else if (!(strcasecmp (temp, "no-uninited-var"))) {
|
||||
options.warnings.uninited_variable = false;
|
||||
} else if (!(strcasecmp (temp, "vararg-integer"))) {
|
||||
options.warnings.vararg_integer = true;
|
||||
} else if (!(strcasecmp (temp, "no-vararg-integer"))) {
|
||||
options.warnings.vararg_integer = false;
|
||||
} else if (!(strcasecmp (temp, "integer-divide"))) {
|
||||
options.warnings.integer_divide = true;
|
||||
} else if (!(strcasecmp (temp, "no-integer-divide"))) {
|
||||
options.warnings.integer_divide = false;
|
||||
}
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 256: // --cpp=
|
||||
cpp_name = strdup (optarg);
|
||||
break;
|
||||
case 'S': // save temps
|
||||
options.save_temps = true;
|
||||
break;
|
||||
case 'D':{ // defines for cpp
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
add_cpp_def (strdup (va ("%s%s", "-D", temp)));
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 'I':{ // includes
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
add_cpp_def (strdup (va ("%s%s", "-I", temp)));
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
case 'U':{ // undefines
|
||||
char *opts = strdup (optarg);
|
||||
char *temp = strtok (opts, ",");
|
||||
|
||||
while (temp) {
|
||||
add_cpp_def (strdup (va ("%s%s", "-U", temp)));
|
||||
temp = strtok (NULL, ",");
|
||||
}
|
||||
free (opts);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
}
|
||||
}
|
||||
return optind;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
FILE *
|
||||
preprocess_file (const char *filename)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
pid_t pid;
|
||||
int tempfd = 0;
|
||||
#endif
|
||||
char *temp1;
|
||||
char *temp2 = strrchr (this_program, PATH_SEPARATOR);
|
||||
|
||||
if (cpp_name) {
|
||||
if (options.save_temps) {
|
||||
char *basename = strdup (filename);
|
||||
char *temp;
|
||||
|
||||
temp = strrchr (basename, '.');
|
||||
if (temp)
|
||||
*temp = '\0'; // ignore the rest of the string
|
||||
|
||||
temp = strrchr (basename, '/');
|
||||
if (!temp)
|
||||
temp = basename;
|
||||
else
|
||||
temp++;
|
||||
|
||||
if (*sourcedir) {
|
||||
dsprintf (tempname, "%s%c%s", sourcedir,
|
||||
PATH_SEPARATOR, temp);
|
||||
} else {
|
||||
dsprintf (tempname, "%s.p", temp);
|
||||
}
|
||||
free (basename);
|
||||
} else {
|
||||
temp1 = getenv ("TMPDIR");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = getenv ("TEMP");
|
||||
if ((!temp1) || (!temp1[0])) {
|
||||
temp1 = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
dsprintf (tempname, "%s%c%sXXXXXX", temp1,
|
||||
PATH_SEPARATOR, temp2 ? temp2 + 1 : this_program);
|
||||
}
|
||||
build_cpp_args (filename, tempname->str);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!options.save_temps)
|
||||
mktemp (tempname->str);
|
||||
|
||||
{
|
||||
FILE *tmp = fopen (tempname->str, "wt");
|
||||
|
||||
fclose (tmp);
|
||||
}
|
||||
|
||||
{
|
||||
int status = spawnvp (_P_WAIT, cpp_argv[0], (char **)cpp_argv);
|
||||
|
||||
if (status) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
status);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
return fopen (tempname->str, "rt");
|
||||
#else
|
||||
if (!options.save_temps)
|
||||
tempfd = mkstemp (tempname->str);
|
||||
|
||||
if ((pid = fork ()) == -1) {
|
||||
perror ("fork");
|
||||
exit (1);
|
||||
}
|
||||
if (!pid) {
|
||||
// we're a child, check for abuse
|
||||
//const char **a;
|
||||
//for (a = cpp_argv; *a; a++)
|
||||
// printf ("%s ", *a);
|
||||
//puts("");
|
||||
execvp (cpp_argv[0], (char **)cpp_argv);
|
||||
fprintf (stderr, "Child shouldn't reach here\n");
|
||||
exit (1);
|
||||
} else {
|
||||
// give parental guidance (or bury it in the back yard)
|
||||
int status;
|
||||
pid_t rc;
|
||||
|
||||
// printf ("pid = %d\n", pid);
|
||||
if ((rc = waitpid (0, &status, 0 | WUNTRACED)) != pid) {
|
||||
if (rc == -1) {
|
||||
perror ("wait");
|
||||
exit (1);
|
||||
}
|
||||
fprintf (stderr, "%s: The wrong child (%ld) died. Don't ask me, I don't know either.\n",
|
||||
this_program,
|
||||
(long) rc);
|
||||
exit (1);
|
||||
}
|
||||
if (WIFEXITED (status)) {
|
||||
if (WEXITSTATUS (status)) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
WEXITSTATUS (status));
|
||||
exit (1);
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "%s: cpp returned prematurely.\n", filename);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
if (options.save_temps)
|
||||
return fopen (tempname->str, "rt");
|
||||
else
|
||||
return fdopen (tempfd, "r+t");
|
||||
#endif
|
||||
}
|
||||
return fopen (filename, "rt");
|
||||
}
|
||||
|
||||
const char *
|
||||
strip_path (const char *filename)
|
||||
|
|
Loading…
Reference in a new issue