2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
34 const char * const * args_left
;
36 const char *program_name
;
39 static void debug_all(const char attr_unused
*str
)
41 mem_enable_debugging_option(NULL
, 0);
42 obj_registry_enable_debugging_option(NULL
, 0);
43 thread_enable_debugging_option(NULL
, 0);
46 static void debug_select(const char *str
)
50 l
= strcspn(str
, ",");
51 if ((unsigned)!mem_enable_debugging_option(str
, l
) &
52 (unsigned)!obj_registry_enable_debugging_option(str
, l
) &
53 (unsigned)!thread_enable_debugging_option(str
, l
))
54 warning("invalid debugging option %.*s", (int)l
, str
);
61 static void profile_all(const char attr_unused
*str
)
63 function_enable_profile(NULL
, 0);
64 mem_al_enable_profile(NULL
, 0);
67 static void profile_select(const char *str
)
71 l
= strcspn(str
, ",");
72 if ((unsigned)!function_enable_profile(str
, l
) &
73 (unsigned)!mem_al_enable_profile(str
, l
))
74 warning("invalid profiling option %.*s", (int)l
, str
);
81 static void ipret_set_strict_calls(const char attr_unused
*str
)
83 ipret_strict_calls
= true;
86 static void ipret_set_privileged(const char attr_unused
*str
)
88 ipret_is_privileged
= true;
91 static void ipret_set_compile(const char attr_unused
*str
)
96 static void set_nosave(const char attr_unused
*str
)
107 uchar_efficient_t mode
;
108 void (*handler
)(const char *str
);
114 static const struct arg args
[] = {
115 { "--compile", ARG_SWITCH
, ipret_set_compile
, NULL
, 0, 0 },
116 { "--debug", ARG_SWITCH
, debug_all
, NULL
, 0, 0 },
117 { "--debug=", ARG_STRING
, debug_select
, NULL
, 0, 0 },
118 { "--nosave", ARG_SWITCH
, set_nosave
, NULL
, 0, 0 },
119 { "--privileged", ARG_SWITCH
, ipret_set_privileged
, NULL
, 0, 0 },
120 { "--profile", ARG_SWITCH
, profile_all
, NULL
, 0, 0 },
121 { "--profile=", ARG_STRING
, profile_select
, NULL
, 0, 0 },
122 { "--ptrcomp", ARG_SWITCH
, mem_al_set_ptrcomp
, NULL
, 0, 0 },
123 { "--strict-calls", ARG_SWITCH
, ipret_set_strict_calls
, NULL
, 0, 0 },
124 { "--system-malloc", ARG_SWITCH
, mem_al_set_system_malloc
, NULL
, 0, 0 },
125 { "--thread-tick", ARG_SWITCH
, NULL
, &thread_tick
, 0, 0 },
126 { "--threads=", ARG_NUMBER
, NULL
, &nr_cpus_override
, 1, (unsigned)-1 },
127 { "--tick=", ARG_NUMBER
, NULL
, &tick_us
, 1, (uint32_t)-1 },
130 static void process_arg(const char *arg
)
133 for (a
= args
; a
< args
+ n_array_elements(args
); a
++) {
134 size_t sl
= strlen(a
->str
);
137 if (!strcmp(arg
, a
->str
)) {
146 if (!strncmp(arg
, a
->str
, sl
)) {
147 const char *val
= arg
+ sl
;
153 if (!strncmp(arg
, a
->str
, sl
)) {
156 const char *val
= arg
+ sl
;
159 num
= strtoul(val
, &endptr
, 10);
162 if ((uint32_t)num
!= num
|| num
< a
->min
|| num
> a
->max
)
169 internal(file_line
, "process_arg: unknown mode %u", a
->mode
);
173 fatal("invalid argument '%s'", arg
);
176 void args_init(int argc
, const char * const argv
[])
181 fatal("the argument 0 is not present");
183 if ((env
= getenv("AJLA_OPTIONS"))) {
185 size_t len
= strcspn(env
, " ");
187 char *a
= malloc(len
+ 1);
189 fatal("malloc failed");
190 *(char *)mempcpy(a
, env
, len
) = 0;
200 for (i
= 1; i
< argc
; i
++) {
201 if (likely(argv
[i
][0] != '-'))
203 if (argv
[i
][0] == '-' && argv
[i
][1] == '-' && !argv
[i
][2]) {
207 process_arg(argv
[i
]);
209 args_left
= argv
+ i
;
210 n_args_left
= argc
- i
;
215 program_name
= args_left
[0];
216 for (p
= program_name
; *p
; p
++) {
217 if (unlikely(os_is_path_separator(*p
)))
218 program_name
= p
+ 1;