blob: fa5ff9ae9d28da9b79e2f4e7b2e0d455bc4536d1 [file] [log] [blame]
/*
* Set up arguments for main() and prepare environment variables
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License version 2.
*/
#include "libcflat.h"
#include "ctype.h"
#include "argv.h"
#include "auxinfo.h"
int __argc;
const char *__args;
char *__argv[100];
char *__environ[200];
char **environ = __environ;
static char args_copy[1000];
static char *copy_ptr = args_copy;
static const char *skip_blanks(const char *p)
{
while (isblank(*p))
++p;
return p;
}
void __setup_args(void)
{
const char *args = __args;
char **argv = __argv + __argc;
while (*(args = skip_blanks(args)) != '\0') {
*argv++ = copy_ptr;
while (*args != '\0' && !isblank(*args))
*copy_ptr++ = *args++;
*copy_ptr++ = '\0';
}
__argc = argv - __argv;
}
void setup_args(const char *args)
{
if (!args)
return;
__args = args;
__setup_args();
}
void add_setup_arg(const char *arg)
{
__argv[__argc] = copy_ptr;
strcpy(__argv[__argc], arg);
copy_ptr += strlen(arg) + 1;
++__argc;
}
void setup_args_progname(const char *args)
{
add_setup_arg(auxinfo.progname);
setup_args(args);
}
static char *env_eol(char *env)
{
while (*env && *env != '\n')
++env;
return env;
}
static char *env_invalid_eol(char *env)
{
char *eol = env_eol(env);
char eol_old = *eol;
*eol = '\0';
printf("Invalid environment variable: %s\n", env);
*eol = eol_old;
return eol;
}
static char *env_next(char *env)
{
char *p;
if (!*env)
return env;
if (isalpha(*env) || *env == '_') {
bool invalid = false;
p = env + 1;
while (*p && *p != '=' && *p != '\n') {
if (!(isalnum(*p) || *p == '_'))
invalid = true;
++p;
}
if (*p != '=')
invalid = true;
if (invalid) {
env = env_invalid_eol(env);
return *env ? env_next(env + 1) : env;
}
return env;
}
p = env;
while (isblank(*p))
++p;
if (*p == '\n')
return env_next(p + 1);
if (*p == '#')
env = env_eol(env);
else
env = env_invalid_eol(env);
return *env ? env_next(env + 1) : env;
}
void setup_env(char *env, int size)
{
char *eof = env + size, *p = env;
bool newline = false;
int i = 0;
while (*p)
++p;
if (p == eof)
newline = true;
while (env < eof) {
if (newline)
env = env_next(env);
if (!*env || env >= eof)
break;
__environ[i++] = env;
while (env < eof && *env && !(newline && *env == '\n'))
++env;
*env++ = '\0';
}
}