1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "option.h"
6 #include "util.h"
7 
8 #pragma GCC visibility push(hidden)
9 
10 #include <string.h>
11 
12 #pragma GCC visibility pop
13 
14 #define OPTION_DEFAULT(option) \
15     case OPTION_##option: value = OPTION_##option##_DEFAULT; break
16 
initialize_options(struct options * o)17 static void initialize_options(struct options* o) {
18     for (enum option i = 0; i < OPTION_MAX; ++i) {
19         const char* value = NULL;
20         switch (i) {
21             OPTION_DEFAULT(FILENAME);
22             OPTION_DEFAULT(SHUTDOWN);
23             OPTION_DEFAULT(REBOOT);
24         case OPTION_MAX:
25             __builtin_unreachable();
26         }
27         o->value[i] = value;
28     }
29 }
30 
31 #define OPTION_STRING(option)                               \
32     case OPTION_##option:                                   \
33         string = OPTION_##option##_STRING;                  \
34         string_len = sizeof(OPTION_##option##_STRING) - 1;  \
35         break
36 
apply_option(struct options * o,const char * arg)37 static void apply_option(struct options* o, const char* arg) {
38     size_t len = strlen(arg);
39     for (enum option i = 0; i < OPTION_MAX; ++i) {
40         const char* string = NULL;
41         size_t string_len = 0;
42         switch (i) {
43             OPTION_STRING(FILENAME);
44             OPTION_STRING(SHUTDOWN);
45             OPTION_STRING(REBOOT);
46         case OPTION_MAX:
47             __builtin_unreachable();
48         }
49         if (len > string_len &&
50             arg[string_len] == '=' &&
51             !strncmp(arg, string, string_len)) {
52             o->value[i] = &arg[string_len + 1];
53         }
54     }
55 }
56 
parse_options(zx_handle_t log,struct options * o,char ** strings)57 void parse_options(zx_handle_t log, struct options *o, char** strings) {
58     initialize_options(o);
59     for (char** sp = strings; *sp != NULL; ++sp) {
60         const char* arg = *sp;
61         printl(log, "option \"%s\"", arg);
62         apply_option(o, arg);
63     }
64 }
65