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