xref: /kvm-unit-tests/lib/argv.c (revision e526bc786e9878c3880ae4b09b01a4572756e492)
1 /*
2  * Set up arguments for main() and prepare environment variables
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Library General Public License version 2.
6  */
7 
8 #include "libcflat.h"
9 #include "ctype.h"
10 #include "argv.h"
11 #include "auxinfo.h"
12 
13 int __argc;
14 const char *__args;
15 char *__argv[100];
16 char *__environ[200];
17 
18 char **environ = __environ;
19 
20 static char args_copy[1000];
21 static char *copy_ptr = args_copy;
22 
skip_blanks(const char * p)23 static const char *skip_blanks(const char *p)
24 {
25 	while (isblank(*p))
26 		++p;
27 	return p;
28 }
29 
__setup_args(void)30 void __setup_args(void)
31 {
32 	const char *args = __args;
33 	char **argv = __argv + __argc;
34 
35 	while (*(args = skip_blanks(args)) != '\0') {
36 		*argv++ = copy_ptr;
37 		while (*args != '\0' && !isblank(*args))
38 			*copy_ptr++ = *args++;
39 		*copy_ptr++ = '\0';
40 	}
41 	__argc = argv - __argv;
42 }
43 
setup_args(const char * args)44 void setup_args(const char *args)
45 {
46 	if (!args)
47 		return;
48 
49 	__args = args;
50 	__setup_args();
51 }
52 
add_setup_arg(const char * arg)53 void add_setup_arg(const char *arg)
54 {
55 	__argv[__argc] = copy_ptr;
56 	strcpy(__argv[__argc], arg);
57 	copy_ptr += strlen(arg) + 1;
58 	++__argc;
59 }
60 
setup_args_progname(const char * args)61 void setup_args_progname(const char *args)
62 {
63 	add_setup_arg(auxinfo.progname);
64 	setup_args(args);
65 }
66 
env_eol(char * env)67 static char *env_eol(char *env)
68 {
69 	while (*env && *env != '\n')
70 		++env;
71 	return env;
72 }
73 
env_invalid_eol(char * env)74 static char *env_invalid_eol(char *env)
75 {
76 	char *eol = env_eol(env);
77 	char eol_old = *eol;
78 
79 	*eol = '\0';
80 	printf("Invalid environment variable: %s\n", env);
81 	*eol = eol_old;
82 	return eol;
83 }
84 
env_next(char * env)85 static char *env_next(char *env)
86 {
87 	char *p;
88 
89 	if (!*env)
90 		return env;
91 
92 	if (isalpha(*env) || *env == '_') {
93 		bool invalid = false;
94 
95 		p = env + 1;
96 		while (*p && *p != '=' && *p != '\n') {
97 			if (!(isalnum(*p) || *p == '_'))
98 				invalid = true;
99 			++p;
100 		}
101 
102 		if (*p != '=')
103 			invalid = true;
104 
105 		if (invalid) {
106 			env = env_invalid_eol(env);
107 			return *env ? env_next(env + 1) : env;
108 		}
109 		return env;
110 	}
111 
112 	p = env;
113 	while (isblank(*p))
114 		++p;
115 
116 	if (*p == '\n')
117 		return env_next(p + 1);
118 
119 	if (*p == '#')
120 		env = env_eol(env);
121 	else
122 		env = env_invalid_eol(env);
123 
124 	return *env ? env_next(env + 1) : env;
125 }
126 
setup_env(char * env,int size)127 void setup_env(char *env, int size)
128 {
129 	char *eof = env + size, *p = env;
130 	bool newline = false;
131 	int i = 0;
132 
133 	while (*p)
134 		++p;
135 	if (p == eof)
136 		newline = true;
137 
138 	while (env < eof) {
139 		if (newline)
140 			env = env_next(env);
141 		if (!*env || env >= eof)
142 			break;
143 		__environ[i++] = env;
144 		while (env < eof && *env && !(newline && *env == '\n'))
145 			++env;
146 		*env++ = '\0';
147 	}
148 }
149