diff --git a/cc.c b/cc.c index 8c04eee..f3955bb 100644 --- a/cc.c +++ b/cc.c @@ -21,6 +21,9 @@ #include"cc.h" /* The core functions */ +void populate_env(char** envp); +void setup_env(char** envp); +char* env_lookup(char* variable); void initialize_types(); struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename); struct token_list* reverse_list(struct token_list* head); @@ -35,7 +38,7 @@ void preprocess(); void output_tokens(struct token_list *i, FILE* out); int strtoint(char *a); -int main(int argc, char** argv) +int main(int argc, char** argv, char** envp) { MAX_STRING = 4096; PREPROCESSOR_MODE = FALSE; @@ -141,6 +144,13 @@ int main(int argc, char** argv) global_token = reverse_list(global_token); global_token = remove_line_comments(global_token); + + /* Get the environmental bits */ + populate_env(envp); + setup_env(envp); + M2LIBC_PATH = env_lookup("M2LIBC_PATH"); + if(NULL == M2LIBC_PATH) M2LIBC_PATH = "./M2libc"; + preprocess(); if(PREPROCESSOR_MODE) @@ -155,7 +165,7 @@ int main(int argc, char** argv) } else { - /* Put tempfile and spawning info here */ + /* TODO Put tempfile and spawning info here */ output_tokens(global_token, destination_file); } return EXIT_SUCCESS; diff --git a/cc_env.c b/cc_env.c index 71a88f6..e9b5b62 100644 --- a/cc_env.c +++ b/cc_env.c @@ -20,9 +20,9 @@ #include void init_macro_env(char* sym, char* value, char* source, int num); +char* env_lookup(char* variable); - -void setup_env(char** envp) +void setup_env() { char* ARCH = NULL; struct utsname* unameData = calloc(1, sizeof(struct utsname)); @@ -36,8 +36,9 @@ void setup_env(char** envp) else ARCH = unameData->machine; - /* TODO Check for override using envp */ - + /* Check for override */ + char* hold = env_lookup("ARCHITECTURE_OVERRIDE"); + if(NULL != hold) ARCH = hold; /* Set desired architecture */ if(match("knight-native", ARCH)) Architecture = KNIGHT_NATIVE; @@ -76,3 +77,157 @@ void setup_env(char** envp) exit(EXIT_FAILURE); } } + +struct Token +{ + /* + * For the token linked-list, this stores the token; for the env linked-list + * this stores the value of the variable. + */ + char* value; + /* + * Used only for the env linked-list. It holds a string containing the + * name of the var. + */ + char* var; + /* + * This struct stores a node of a singly linked list, store the pointer to + * the next node. + */ + struct Token* next; +}; + +struct Token* env; + +int array_length(char** array) +{ + int length = 0; + + while(array[length] != NULL) + { + length = length + 1; + } + + return length; +} + +/* Search for a variable in the token linked-list */ +char* token_lookup(char* variable, struct Token* token) +{ + /* Start at the head */ + struct Token* n = token; + + /* Loop over the linked-list */ + while(n != NULL) + { + if(match(variable, n->var)) + { + /* We have found the correct node */ + return n->value; /* Done */ + } + + /* Nope, try the next */ + n = n->next; + } + + /* We didn't find anything! */ + return NULL; +} + +/* Search for a variable in the env linked-list */ +char* env_lookup(char* variable) +{ + return token_lookup(variable, env); +} + +void populate_env(char** envp) +{ + /* You can't populate a NULL environment */ + if(NULL == envp) + { + return; + } + + /* avoid empty arrays */ + int max = array_length(envp); + + if(0 == max) + { + return; + } + + /* Initialize env and n */ + env = calloc(1, sizeof(struct Token)); + require(env != NULL, "Memory initialization of env failed\n"); + struct Token* n; + n = env; + int i; + int j; + int k; + char* envp_line; + + for(i = 0; i < max; i = i + 1) + { + n->var = calloc(MAX_STRING, sizeof(char)); + require(n->var != NULL, "Memory initialization of n->var in population of env failed\n"); + n->value = calloc(MAX_STRING, sizeof(char)); + require(n->value != NULL, "Memory initialization of n->var in population of env failed\n"); + j = 0; + /* + * envp is weird. + * When referencing envp[i]'s characters directly, they were all jumbled. + * So just copy envp[i] to envp_line, and work with that - that seems + * to fix it. + */ + envp_line = calloc(MAX_STRING, sizeof(char)); + require(envp_line != NULL, "Memory initialization of envp_line in population of env failed\n"); + strcpy(envp_line, envp[i]); + + while(envp_line[j] != '=') + { + /* Copy over everything up to = to var */ + n->var[j] = envp_line[j]; + j = j + 1; + } + + /* If we get strange input, we need to ignore it */ + if(n->var == NULL) + { + continue; + } + + j = j + 1; /* Skip over = */ + k = 0; /* As envp[i] will continue as j but n->value begins at 0 */ + + while(envp_line[j] != 0) + { + /* Copy everything else to value */ + n->value[k] = envp_line[j]; + j = j + 1; + k = k + 1; + } + + /* Sometimes, we get lines like VAR=, indicating nothing is in the variable */ + if(n->value == NULL) + { + n->value = ""; + } + + /* Advance to next part of linked list */ + n->next = calloc(1, sizeof(struct Token)); + require(n->next != NULL, "Memory initialization of n->next in population of env failed\n"); + n = n->next; + } + + /* Get rid of node on the end */ + n = NULL; + /* Also destroy the n->next reference */ + n = env; + + while(n->next->var != NULL) + { + n = n->next; + } + + n->next = NULL; +} diff --git a/cc_globals.c b/cc_globals.c index 13f0036..d9f70c2 100644 --- a/cc_globals.c +++ b/cc_globals.c @@ -44,3 +44,6 @@ int BOOTSTRAP_MODE; /* enable preprocessor-only mode */ int PREPROCESSOR_MODE; + +/* enable spawn behavior to be effective */ +char* M2LIBC_PATH; diff --git a/cc_globals.h b/cc_globals.h index cdac985..404c8f7 100644 --- a/cc_globals.h +++ b/cc_globals.h @@ -47,3 +47,6 @@ extern int BOOTSTRAP_MODE; /* enable preprocessor-only mode */ extern int PREPROCESSOR_MODE; + +/* enable spawn behavior to be effective */ +extern char* M2LIBC_PATH;