147 lines
2.5 KiB
C
147 lines
2.5 KiB
C
/*
|
|
* 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 "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;
|
|
|
|
#define isblank(c) ((c) == ' ' || (c) == '\t')
|
|
#define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z') || (c) == '_')
|
|
#define isalnum(c) (isalpha(c) || ((c) >= '0' && (c) <= '9'))
|
|
|
|
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;
|
|
}
|
|
|
|
static void setup_args(const char *args)
|
|
{
|
|
if (!args)
|
|
return;
|
|
|
|
__args = args;
|
|
__setup_args();
|
|
}
|
|
|
|
void setup_args_progname(const char *args)
|
|
{
|
|
__argv[0] = copy_ptr;
|
|
strcpy(__argv[0], auxinfo.progname);
|
|
copy_ptr += strlen(auxinfo.progname) + 1;
|
|
++__argc;
|
|
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)) {
|
|
bool invalid = false;
|
|
|
|
p = env + 1;
|
|
while (*p && *p != '=' && *p != '\n') {
|
|
if (!isalnum(*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';
|
|
}
|
|
}
|