xref: /kvm-unit-tests/lib/argv.c (revision 4b6da8266e20882f41cdbbe254b08b900a5b9fbe)
1*4b6da826SThomas Huth /*
2*4b6da826SThomas Huth  * Set up arguments for main() and prepare environment variables
3*4b6da826SThomas Huth  *
4*4b6da826SThomas Huth  * This code is free software; you can redistribute it and/or modify it
5*4b6da826SThomas Huth  * under the terms of the GNU Library General Public License version 2.
6*4b6da826SThomas Huth  */
7*4b6da826SThomas Huth 
8ea7d43d0SAvi Kivity #include "libcflat.h"
96b97d595SAndrew Jones #include "auxinfo.h"
10ea7d43d0SAvi Kivity 
11ea7d43d0SAvi Kivity int __argc;
12ea7d43d0SAvi Kivity char *__args;
1369205bf1SAndrew Jones char *__argv[100];
1469205bf1SAndrew Jones char *__environ[200];
1569205bf1SAndrew Jones 
1669205bf1SAndrew Jones char **environ = __environ;
176b97d595SAndrew Jones 
186b97d595SAndrew Jones static char args_copy[1000];
196b97d595SAndrew Jones static char *copy_ptr = args_copy;
20ea7d43d0SAvi Kivity 
214bc666caSAndrew Jones #define isblank(c) ((c) == ' ' || (c) == '\t')
2269205bf1SAndrew Jones #define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z') || (c) == '_')
2369205bf1SAndrew Jones #define isalnum(c) (isalpha(c) || ((c) >= '0' && (c) <= '9'))
24ea7d43d0SAvi Kivity 
25ea7d43d0SAvi Kivity static char *skip_blanks(char *p)
26ea7d43d0SAvi Kivity {
27ea7d43d0SAvi Kivity 	while (isblank(*p))
28ea7d43d0SAvi Kivity 		++p;
29ea7d43d0SAvi Kivity 	return p;
30ea7d43d0SAvi Kivity }
31ea7d43d0SAvi Kivity 
32ea7d43d0SAvi Kivity void __setup_args(void)
33ea7d43d0SAvi Kivity {
34ea7d43d0SAvi Kivity 	char *args = __args;
356b97d595SAndrew Jones 	char **argv = __argv + __argc;
36ea7d43d0SAvi Kivity 
37ea7d43d0SAvi Kivity 	while (*(args = skip_blanks(args)) != '\0') {
386b97d595SAndrew Jones 		*argv++ = copy_ptr;
39ea7d43d0SAvi Kivity 		while (*args != '\0' && !isblank(*args))
406b97d595SAndrew Jones 			*copy_ptr++ = *args++;
416b97d595SAndrew Jones 		*copy_ptr++ = '\0';
42ea7d43d0SAvi Kivity 	}
43ea7d43d0SAvi Kivity 	__argc = argv - __argv;
44ea7d43d0SAvi Kivity }
455e61cba0SAndrew Jones 
465e61cba0SAndrew Jones void setup_args(char *args)
475e61cba0SAndrew Jones {
485e61cba0SAndrew Jones 	if (!args)
495e61cba0SAndrew Jones 		return;
505e61cba0SAndrew Jones 
515e61cba0SAndrew Jones 	__args = args;
525e61cba0SAndrew Jones 	__setup_args();
535e61cba0SAndrew Jones }
546ffea954SAndrew Jones 
55809ebcb3SAndrew Jones void setup_args_progname(char *args)
566ffea954SAndrew Jones {
576b97d595SAndrew Jones 	__argv[0] = copy_ptr;
58809ebcb3SAndrew Jones 	strcpy(__argv[0], auxinfo.progname);
59809ebcb3SAndrew Jones 	copy_ptr += strlen(auxinfo.progname) + 1;
606b97d595SAndrew Jones 	++__argc;
616ffea954SAndrew Jones 	if (args) {
626ffea954SAndrew Jones 		__args = args;
636ffea954SAndrew Jones 		__setup_args();
646ffea954SAndrew Jones 	}
656ffea954SAndrew Jones }
6669205bf1SAndrew Jones 
6769205bf1SAndrew Jones static char *env_eol(char *env)
6869205bf1SAndrew Jones {
6969205bf1SAndrew Jones 	while (*env && *env != '\n')
7069205bf1SAndrew Jones 		++env;
7169205bf1SAndrew Jones 	return env;
7269205bf1SAndrew Jones }
7369205bf1SAndrew Jones 
7469205bf1SAndrew Jones static char *env_invalid_eol(char *env)
7569205bf1SAndrew Jones {
7669205bf1SAndrew Jones 	char *eol = env_eol(env);
7769205bf1SAndrew Jones 	char eol_old = *eol;
7869205bf1SAndrew Jones 
7969205bf1SAndrew Jones 	*eol = '\0';
8069205bf1SAndrew Jones 	printf("Invalid environment variable: %s\n", env);
8169205bf1SAndrew Jones 	*eol = eol_old;
8269205bf1SAndrew Jones 	return eol;
8369205bf1SAndrew Jones }
8469205bf1SAndrew Jones 
8569205bf1SAndrew Jones static char *env_next(char *env)
8669205bf1SAndrew Jones {
8769205bf1SAndrew Jones 	char *p;
8869205bf1SAndrew Jones 
8969205bf1SAndrew Jones 	if (!*env)
9069205bf1SAndrew Jones 		return env;
9169205bf1SAndrew Jones 
9269205bf1SAndrew Jones 	if (isalpha(*env)) {
9369205bf1SAndrew Jones 		bool invalid = false;
9469205bf1SAndrew Jones 
9569205bf1SAndrew Jones 		p = env + 1;
9669205bf1SAndrew Jones 		while (*p && *p != '=' && *p != '\n') {
9769205bf1SAndrew Jones 			if (!isalnum(*p))
9869205bf1SAndrew Jones 				invalid = true;
9969205bf1SAndrew Jones 			++p;
10069205bf1SAndrew Jones 		}
10169205bf1SAndrew Jones 
10269205bf1SAndrew Jones 		if (*p != '=')
10369205bf1SAndrew Jones 			invalid = true;
10469205bf1SAndrew Jones 
10569205bf1SAndrew Jones 		if (invalid) {
10669205bf1SAndrew Jones 			env = env_invalid_eol(env);
10769205bf1SAndrew Jones 			return *env ? env_next(env + 1) : env;
10869205bf1SAndrew Jones 		}
10969205bf1SAndrew Jones 		return env;
11069205bf1SAndrew Jones 	}
11169205bf1SAndrew Jones 
11269205bf1SAndrew Jones 	p = env;
11369205bf1SAndrew Jones 	while (isblank(*p))
11469205bf1SAndrew Jones 		++p;
11569205bf1SAndrew Jones 
11669205bf1SAndrew Jones 	if (*p == '\n')
11769205bf1SAndrew Jones 		return env_next(p + 1);
11869205bf1SAndrew Jones 
11969205bf1SAndrew Jones 	if (*p == '#')
12069205bf1SAndrew Jones 		env = env_eol(env);
12169205bf1SAndrew Jones 	else
12269205bf1SAndrew Jones 		env = env_invalid_eol(env);
12369205bf1SAndrew Jones 
12469205bf1SAndrew Jones 	return *env ? env_next(env + 1) : env;
12569205bf1SAndrew Jones }
12669205bf1SAndrew Jones 
12769205bf1SAndrew Jones void setup_env(char *env, int size)
12869205bf1SAndrew Jones {
12969205bf1SAndrew Jones 	char *eof = env + size, *p = env;
13069205bf1SAndrew Jones 	bool newline = false;
13169205bf1SAndrew Jones 	int i = 0;
13269205bf1SAndrew Jones 
13369205bf1SAndrew Jones 	while (*p)
13469205bf1SAndrew Jones 		++p;
13569205bf1SAndrew Jones 	if (p == eof)
13669205bf1SAndrew Jones 		newline = true;
13769205bf1SAndrew Jones 
13869205bf1SAndrew Jones 	while (env < eof) {
13969205bf1SAndrew Jones 		if (newline)
14069205bf1SAndrew Jones 			env = env_next(env);
14169205bf1SAndrew Jones 		if (!*env || env >= eof)
14269205bf1SAndrew Jones 			break;
14369205bf1SAndrew Jones 		__environ[i++] = env;
14469205bf1SAndrew Jones 		while (env < eof && *env && !(newline && *env == '\n'))
14569205bf1SAndrew Jones 			++env;
14669205bf1SAndrew Jones 		*env++ = '\0';
14769205bf1SAndrew Jones 	}
14869205bf1SAndrew Jones }
149