Skip to content

Commit

Permalink
Refactor: convert argc/argv to Strings
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed May 16, 2015
1 parent 017bf13 commit 271c1a1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 107 deletions.
3 changes: 1 addition & 2 deletions src/magicport.json
Original file line number Diff line number Diff line change
Expand Up @@ -3198,12 +3198,11 @@
"core.stdc.stdio",
"core.stdc.stdlib",
"core.stdc.string",
"root.filename",
"root.file"
],
"members" :
[
"struct Narg",
"function addargp",
"function response_expand"
]
}
Expand Down
97 changes: 44 additions & 53 deletions src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@
#include "hdrgen.h"
#include "doc.h"

bool response_expand(size_t *pargc, const char ***pargv);
bool response_expand(Strings *arguments);


void browse(const char *url);
void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv);
void getenv_setargv(const char *envvar, Strings *args);

void printCtfePerformanceStats();

static const char* parse_arch_arg(size_t argc, const char** argv, const char* arch);
static const char* parse_conf_arg(size_t argc, const char** argv);
static const char* parse_arch_arg(Strings *args, const char* arch);
static const char* parse_conf_arg(Strings *args);

void inlineScan(Module *m);

Expand Down Expand Up @@ -286,19 +286,26 @@ int tryMain(size_t argc, const char *argv[])
error(Loc(), "missing or null command line arguments");
fatal();
}

// Convert argc/argv into arguments[] for easier handling
Strings arguments;
arguments.setDim(argc);
for (size_t i = 0; i < argc; i++)
{
if (!argv[i])
goto Largs;
arguments[i] = argv[i];
}

if (response_expand(&argc,&argv)) // expand response files
if (response_expand(&arguments)) // expand response files
error(Loc(), "can't open response file");

files.reserve(argc - 1);
//for (size_t i = 0; i < arguments.dim; ++i) printf("arguments[%d] = '%s'\n", i, arguments[i]);

files.reserve(arguments.dim - 1);

// Set default values
global.params.argv0 = argv[0];
global.params.argv0 = arguments[0];
global.params.color = isConsoleColorSupported();
global.params.link = true;
global.params.useAssert = true;
Expand Down Expand Up @@ -374,7 +381,7 @@ int tryMain(size_t argc, const char *argv[])
VersionCondition::addPredefinedGlobalIdent("D_Version2");
VersionCondition::addPredefinedGlobalIdent("all");

global.inifilename = parse_conf_arg(argc, argv);
global.inifilename = parse_conf_arg(&arguments);
if (global.inifilename)
{
// can be empty as in -conf=
Expand All @@ -384,9 +391,9 @@ int tryMain(size_t argc, const char *argv[])
else
{
#if _WIN32
global.inifilename = findConfFile(argv[0], "sc.ini");
global.inifilename = findConfFile(global.params.argv0, "sc.ini");
#elif __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
global.inifilename = findConfFile(argv[0], "dmd.conf");
global.inifilename = findConfFile(global.params.argv0, "dmd.conf");
#else
#error "fix this"
#endif
Expand All @@ -400,13 +407,12 @@ int tryMain(size_t argc, const char *argv[])
sections.push("Environment");
parseConfFile(global.inifilename, &sections);

size_t dflags_argc = 0;
const char** dflags_argv = NULL;
getenv_setargv("DFLAGS", &dflags_argc, &dflags_argv);
Strings dflags;
getenv_setargv("DFLAGS", &dflags);

const char *arch = global.params.is64bit ? "64" : "32"; // use default
arch = parse_arch_arg(argc, argv, arch);
arch = parse_arch_arg(dflags_argc, dflags_argv, arch);
arch = parse_arch_arg(&arguments, arch);
arch = parse_arch_arg(&dflags, arch);
bool is64bit = arch[0] == '6';

sections.setDim(0);
Expand All @@ -415,18 +421,18 @@ int tryMain(size_t argc, const char *argv[])
sections.push(envsection);
parseConfFile(global.inifilename, &sections);

getenv_setargv("DFLAGS", &argc, &argv);
getenv_setargv("DFLAGS", &arguments);

#if 0
for (size_t i = 0; i < argc; i++)
for (size_t i = 0; i < arguments.dim; i++)
{
printf("argv[%d] = '%s'\n", i, argv[i]);
printf("arguments[%d] = '%s'\n", i, arguments[i]);
}
#endif

for (size_t i = 1; i < argc; i++)
for (size_t i = 1; i < arguments.dim; i++)
{
const char *p = argv[i];
const char *p = arguments[i];
if (*p == '-')
{
if (strcmp(p + 1, "allinst") == 0)
Expand Down Expand Up @@ -977,19 +983,19 @@ Language changes listed by -transition=id:\n\
size_t length = ((i >= argcstart) ? argc : argcstart) - i - 1;
if (length)
{
const char *ext = FileName::ext(argv[i + 1]);
const char *ext = FileName::ext(arguments[i + 1]);
if (ext && FileName::equals(ext, "d") == 0
&& FileName::equals(ext, "di") == 0)
{
error(Loc(), "-run must be followed by a source file, not '%s'", argv[i + 1]);
error(Loc(), "-run must be followed by a source file, not '%s'", arguments[i + 1]);
break;
}

files.push(argv[i + 1]);
files.push(arguments[i + 1]);
global.params.runargs.setDim(length - 1);
for (size_t j = 0; j < length - 1; ++j)
{
global.params.runargs[j] = argv[i + 2 + j];
global.params.runargs[j] = arguments[i + 2 + j];
}
i += length;
}
Expand All @@ -1002,11 +1008,11 @@ Language changes listed by -transition=id:\n\
else
{
Lerror:
error(Loc(), "unrecognized switch '%s'", argv[i]);
error(Loc(), "unrecognized switch '%s'", arguments[i]);
continue;

Lnoarg:
error(Loc(), "argument expected for switch '%s'", argv[i]);
error(Loc(), "argument expected for switch '%s'", arguments[i]);
continue;
}
}
Expand Down Expand Up @@ -1185,7 +1191,7 @@ Language changes listed by -transition=id:\n\
initTraitsStringTable();

if (global.params.verbose)
{ fprintf(global.stdmsg, "binary %s\n", argv[0]);
{ fprintf(global.stdmsg, "binary %s\n", global.params.argv0);
fprintf(global.stdmsg, "version %s\n", global.version);
fprintf(global.stdmsg, "config %s\n", global.inifilename ? global.inifilename
: "(none)");
Expand Down Expand Up @@ -1742,11 +1748,11 @@ int main(int argc, const char *argv[])

/***********************************
* Parse and append contents of environment variable envvar
* to argc and argv[].
* to args[].
* The string is separated into arguments, processing \ and ".
*/

void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv)
void getenv_setargv(const char *envvar, Strings *args)
{
char *p;

Expand All @@ -1760,14 +1766,6 @@ void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv)

env = mem.xstrdup(env); // create our own writable copy

size_t argc = *pargc;
Strings *argv = new Strings();
argv->setDim(argc);

for (size_t i = 0; i < argc; i++)
(*argv)[i] = (*pargv)[i];

size_t j = 1; // leave argv[0] alone
while (1)
{
switch (*env)
Expand All @@ -1778,13 +1776,10 @@ void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv)
break;

case 0:
goto Ldone;
return;

default:
argv->push(env); // append
//argv->insert(j, env); // insert at position j
j++;
argc++;
args->push(env); // append
p = env;
slash = 0;
instring = 0;
Expand Down Expand Up @@ -1823,7 +1818,7 @@ void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv)
*p = 0;
//if (wildcard)
//wildcardexpand(); // not implemented
goto Ldone;
return;

default:
Laddc:
Expand All @@ -1835,10 +1830,6 @@ void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv)
}
}
}

Ldone:
*pargc = argc;
*pargv = argv->tdata();
}

void escapePath(OutBuffer *buf, const char *fname)
Expand Down Expand Up @@ -1867,11 +1858,11 @@ void escapePath(OutBuffer *buf, const char *fname)
* to detect the desired architecture.
*/

static const char* parse_arch_arg(size_t argc, const char** argv, const char* arch)
static const char* parse_arch_arg(Strings *args, const char* arch)
{
for (size_t i = 0; i < argc; ++i)
for (size_t i = 0; i < args->dim; ++i)
{
const char* p = argv[i];
const char* p = (*args)[i];
if (p[0] == '-')
{
if (strcmp(p + 1, "m32") == 0 || strcmp(p + 1, "m32mscoff") == 0 || strcmp(p + 1, "m64") == 0)
Expand All @@ -1887,12 +1878,12 @@ static const char* parse_arch_arg(size_t argc, const char** argv, const char* ar
* Parse command line arguments for -conf=path.
*/

static const char* parse_conf_arg(size_t argc, const char** argv)
static const char* parse_conf_arg(Strings *args)
{
const char *conf=NULL;
for (size_t i = 0; i < argc; ++i)
for (size_t i = 0; i < args->dim; ++i)
{
const char* p = argv[i];
const char* p = (*args)[i];
if (p[0] == '-')
{
if (strncmp(p + 1, "conf=", 5) == 0)
Expand Down
62 changes: 10 additions & 52 deletions src/root/response.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#endif

#include "file.h"
#include "filename.h"

/*********************************
* #include <stdlib.h>
Expand Down Expand Up @@ -66,53 +67,22 @@
* !=0 failure (argc, argv unchanged)
*/

struct Narg
bool response_expand(Strings *args)
{
size_t argc; // arg count
size_t argvmax; // dimension of nargv[]
const char **argv;
};

static bool addargp(Narg *n, const char *p)
{
/* The 2 is to always allow room for a NULL argp at the end */
if (n->argc + 2 > n->argvmax)
{
n->argvmax = n->argc + 2;
const char **ap = n->argv;
ap = (const char **) realloc(ap,n->argvmax * sizeof(char *));
if (!ap)
{
if (n->argv)
free(n->argv);
memset(n, 0, sizeof(*n));
return true;
}
n->argv = ap;
}
n->argv[n->argc++] = p;
return false;
}

bool response_expand(size_t *pargc, const char ***pargv)
{
Narg n;
const char *cp;
int recurse = 0;

n.argc = 0;
n.argvmax = 0; /* dimension of n.argv[] */
n.argv = NULL;
for (size_t i = 0; i < *pargc; ++i)
for (size_t i = 0; i < args->dim; )
{
cp = (*pargv)[i];
cp = (*args)[i];
if (*cp != '@')
{
if (addargp(&n,(*pargv)[i]))
goto noexpand;
++i;
continue;
}

args->remove(i);

char *buffer;
char *bufend;

Expand Down Expand Up @@ -177,8 +147,8 @@ bool response_expand(size_t *pargc, const char ***pargv)
{
continue;
}
if (addargp(&n,p))
goto noexpand;
args->insert(i, p);
++i;
instring = 0;
c = 0;
num_slashes = 0;
Expand Down Expand Up @@ -258,27 +228,15 @@ bool response_expand(size_t *pargc, const char ***pargv)
L2:
;
}
if (n.argvmax == 0)
{
n.argvmax = 1;
n.argv = (const char **) calloc(n.argvmax, sizeof(char *));
if (!n.argv)
return true;
}
else
n.argv[n.argc] = NULL;
if (recurse)
{
/* Recursively expand @filename */
if (response_expand(&n.argc,&n.argv))
if (response_expand(args))
goto noexpand;
}
*pargc = n.argc;
*pargv = n.argv;
return false; /* success */

noexpand: /* error */
free(n.argv);
/* BUG: any file buffers are not free'd */
return true;
}

0 comments on commit 271c1a1

Please sign in to comment.