Skip to content

Commit

Permalink
Merge pull request #4679 from WalterBright/envsections
Browse files Browse the repository at this point in the history
  • Loading branch information
andralex authored and WalterBright committed Jun 1, 2015
1 parent f6b6bae commit 7ed69f4
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 22 deletions.
67 changes: 60 additions & 7 deletions src/inifile.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "root.h"
#include "rmem.h"
#include "port.h"
#include "stringtable.h"

#include "utf.h"

Expand Down Expand Up @@ -119,19 +120,72 @@ const char *findConfFile(const char *argv0, const char *inifile)
return filename;
}

/**********************************
* Read from environment, looking for cached value first.
*/

const char *readFromEnv(StringTable *environment, const char *name)
{
size_t len = strlen(name);
StringValue *sv = environment->lookup(name, len);
if (sv)
return (const char *)sv->ptrvalue; // get cached value

return getenv(name);
}

/*********************************
* Write to our copy of the environment, not the real environment
*/

static void writeToEnv(StringTable *environment, char *nameEqValue)
{
char *p = strchr(nameEqValue, '=');
assert(p);
StringValue *sv = environment->insert(nameEqValue, p - nameEqValue);
sv->ptrvalue = (void *)(p + 1);
}

/************************************
* Update real enviroment with our copy.
*/

static int envput(StringValue *sv)
{
const char *name = sv->toDchars();
size_t namelen = strlen(name);
const char *value = (const char *)sv->ptrvalue;
size_t valuelen = strlen(value);
char *s = (char *)malloc(namelen + 1 + valuelen + 1);
assert(s);
memcpy(s, name, namelen);
s[namelen] = '=';
memcpy(s + namelen + 1, value, valuelen);
s[namelen + 1 + valuelen] = 0;
//printf("envput('%s')\n", s);
putenv(s);

return 0; // do all of them
}

void updateRealEnvironment(StringTable *environment)
{
environment->apply(&envput);
}

/*****************************
* Read and analyze .ini file.
* Write the entries into the process environment as
* Write the entries into environment as
* well as any entries in one of the specified section(s).
*
* Params:
* environment = our own cache of the program environment
* path = what @P will expand to
* buffer[len] = contents of configuration file
* sections[] = section namesdimension of array of section names
*/
void parseConfFile(const char *path, size_t length, unsigned char *buffer, Strings *sections)
void parseConfFile(StringTable *environment, const char *path, size_t length, unsigned char *buffer, Strings *sections)
{

// Parse into lines
bool envsection = true; // default is to read

Expand Down Expand Up @@ -201,7 +255,7 @@ void parseConfFile(const char *path, size_t length, unsigned char *buffer, Strin
memcpy(p, &line[k + 1], len2);
p[len2] = 0;
Port::strupr(p);
char *penv = getenv(p);
const char *penv = readFromEnv(environment, p);
if (penv)
buf.writestring(penv);
free(p);
Expand Down Expand Up @@ -283,7 +337,7 @@ void parseConfFile(const char *path, size_t length, unsigned char *buffer, Strin
else if (p[0] == '?' && p[1] == '=')
{
*p = '\0';
if (getenv(pn))
if (readFromEnv(environment, pn))
{
pn = NULL;
break;
Expand All @@ -305,7 +359,7 @@ void parseConfFile(const char *path, size_t length, unsigned char *buffer, Strin

if (pn)
{
putenv(strdup(pn));
writeToEnv(environment, strdup(pn));
#if LOG
printf("\tputenv('%s')\n", pn);
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
Expand All @@ -315,7 +369,6 @@ void parseConfFile(const char *path, size_t length, unsigned char *buffer, Strin
break;
}
}
return;
}

/********************
Expand Down
48 changes: 33 additions & 15 deletions src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "root.h"
#include "async.h"
#include "target.h"
#include "stringtable.h"

#include "mars.h"
#include "module.h"
Expand All @@ -41,7 +42,7 @@ long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);

bool response_expand(Strings *arguments);
void browse(const char *url);
void getenv_setargv(const char *envvar, Strings *args);
void getenv_setargv(const char *envvalue, Strings *args);

void obj_start(char *srcfile);
void obj_end(Library *library, File *objfile);
Expand All @@ -51,8 +52,20 @@ void printCtfePerformanceStats();
static const char* parse_arch_arg(Strings *args, const char* arch);
static const char* parse_conf_arg(Strings *args);

void inlineScan(Module *m);

// in traits.c
void initTraitsStringTable();

int runLINK();
void deleteExeFile();
int runProgram();

// inifile.c
const char *findConfFile(const char *argv0, const char *inifile);
void parseConfFile(const char *path, size_t len, unsigned char *buffer, Strings *sections);
const char *readFromEnv(StringTable *environment, const char *name);
void updateRealEnvironment(StringTable *environment);
void parseConfFile(StringTable *environment, const char *path, size_t len, unsigned char *buffer, Strings *sections);


FILE *stdmsg;
Expand Down Expand Up @@ -584,27 +597,33 @@ int main(int iargc, const char *argv[])

Strings sections;

StringTable environment;
environment._init(7);

/* Read the [Environment] section, so we can later
* pick up any DFLAGS settings.
*/
sections.push("Environment");
parseConfFile(inifilepath, inifile.len, inifile.buffer, &sections);
parseConfFile(&environment, inifilepath, inifile.len, inifile.buffer, &sections);

Strings dflags;
getenv_setargv("DFLAGS", &dflags);
getenv_setargv(readFromEnv(&environment, "DFLAGS"), &dflags);
environment.reset(7); // erase cached environment updates

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

sections.setDim(0);
char envsection[80];
sprintf(envsection, "Environment%s", arch);
sections.push(envsection);
parseConfFile(inifilepath, inifile.len, inifile.buffer, &sections);
parseConfFile(&environment, inifilepath, inifile.len, inifile.buffer, &sections);

getenv_setargv(readFromEnv(&environment, "DFLAGS"), &arguments);

getenv_setargv("DFLAGS", &arguments);
updateRealEnvironment(&environment);
environment.reset(1); // don't need environment cache any more

#if 0
for (size_t i = 0; i < arguments.dim; i++)
Expand Down Expand Up @@ -1623,24 +1642,23 @@ int main(int iargc, const char *argv[])


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

void getenv_setargv(const char *envvar, Strings *args)
void getenv_setargv(const char *envvalue, Strings *args)
{
if (!envvalue)
return;

char *p;

int instring;
int slash;
char c;

char *env = getenv(envvar);
if (!env)
return;

env = mem.strdup(env); // create our own writable copy
char *env = mem.strdup(envvalue); // create our own writable copy
//printf("env = '%s'\n", env);

while (1)
{
Expand Down
49 changes: 49 additions & 0 deletions src/root/stringtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ void StringTable::_init(size_t size)
count = 0;
}

void StringTable::reset(size_t size)
{
for (size_t i = 0; i < count; i++)
table[i] = NULL;

mem.free(table);
table = NULL;
_init(size);
}

StringTable::~StringTable()
{
// Zero out dangling pointers to help garbage collector.
Expand Down Expand Up @@ -174,3 +184,42 @@ StringValue *StringTable::insert(const char *s, size_t len)
}
return &se->value;
}

/********************************
* Walk the contents of the string table,
* calling fp for each entry.
* Params:
* fp = function to call. Returns !=0 to stop
* Returns:
* last return value of fp call
*/

static int walk(StringEntry *se, int (*fp)(StringValue *))
{
int result = 0;
if (se)
{
StringValue *sv = &se->value;
result = (*fp)(sv);
if (result)
return result;

result = walk(se->left, fp);
if (!result)
result = walk(se->right, fp);
}
return result;
}

int StringTable::apply(int (*fp)(StringValue *))
{
for (size_t i = 0; i < tabledim; ++i)
{
StringEntry *se = (StringEntry *)table[i];
int result = walk(se, fp);
if (result)
return result;
}
return 0;
}

2 changes: 2 additions & 0 deletions src/root/stringtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ struct StringTable

public:
void _init(size_t size = 37);
void reset(size_t size = 0);
~StringTable();

StringValue *lookup(const char *s, size_t len);
StringValue *insert(const char *s, size_t len);
StringValue *update(const char *s, size_t len);
int apply(int (*fp)(StringValue *));

private:
void **search(const char *s, size_t len);
Expand Down

0 comments on commit 7ed69f4

Please sign in to comment.