OILS / cpp / frontend_flag_spec_test.cc View on Github | oilshell.org

154 lines, 98 significant
1#include "cpp/frontend_flag_spec.h"
2
3#include "vendor/greatest.h"
4
5using runtime_asdl::flag_type_e;
6
7//
8// FlagSpec Literals
9//
10
11// must be NUL terminated
12//
13// I tried to make this constexpr, but ran into errors. Here is some
14// std::array crap, but let's keep it simple.
15//
16// https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/EcWhnxFdFwE
17
18const char* arity0_1[] = {"foo", "bar", nullptr};
19
20Action_c arity1_1[] = {
21 {"z", ActionType_c::SetToInt, "z"},
22 {"zz", ActionType_c::SetToString, "zz"},
23 {}, // sentinel
24};
25
26Action_c actions_long_1[] = {
27 {"all", ActionType_c::SetToTrue, "all"},
28 {"line", ActionType_c::SetToTrue, "line"},
29 {}, // sentinel
30};
31
32const char* plus_1[] = {"o", "p", nullptr};
33
34DefaultPair_c defaults_1[] = {
35 {"x", flag_type_e::Bool},
36 {"y", flag_type_e::Int},
37 {},
38};
39
40DefaultPair_c defaults_2[] = {
41 {"b", flag_type_e::Bool, {.b = true}},
42 {"i", flag_type_e::Int, {.i = 42}},
43 {"f", flag_type_e::Float, {.f = 3.14}},
44 {"s", flag_type_e::Str, {.s = "foo"}},
45 {},
46};
47
48FlagSpec_c spec1 = {"export", arity0_1, arity1_1,
49 actions_long_1, plus_1, defaults_1};
50// a copy for demonstrations
51FlagSpec_c spec2 = {"unset", arity0_1, arity1_1,
52 actions_long_1, plus_1, defaults_1};
53
54TEST flag_spec_test() {
55 // Test the declared constants
56 log("spec1.arity0 %s", spec1.arity0[0]);
57 log("spec1.arity0 %s", spec1.arity0[1]);
58
59 log("spec1.arity1 %s", spec1.arity1[0].name);
60 log("spec1.arity1 %s", spec1.arity1[1].name);
61
62 log("spec1.plus_flags %s", spec1.plus_flags[0]);
63 log("spec1.plus_flags %s", spec1.plus_flags[1]);
64
65 log("spec1.defaults %s", spec1.defaults[0].name);
66 log("spec1.defaults %s", spec1.defaults[1].name);
67
68 log("sizeof %d", sizeof(spec1.arity0)); // 8
69 log("sizeof %d", sizeof(arity0_1) / sizeof(arity0_1[0]));
70
71 flag_spec::_FlagSpec* spec;
72
73 spec = flag_util::LookupFlagSpec(StrFromC("new_var"));
74 ASSERT(spec != nullptr);
75
76 spec = flag_util::LookupFlagSpec(StrFromC("readonly"));
77 ASSERT(spec != nullptr);
78
79 spec = flag_util::LookupFlagSpec(StrFromC("zzz"));
80 ASSERT(spec == nullptr);
81
82 flag_spec::_FlagSpecAndMore* spec2;
83
84 spec2 = flag_util::LookupFlagSpec2(StrFromC("main"));
85 ASSERT(spec2 != nullptr);
86
87 spec2 = flag_util::LookupFlagSpec2(StrFromC("zzz"));
88 ASSERT(spec2 == nullptr);
89
90 int i = 0;
91 while (true) {
92 DefaultPair_c* d = &(defaults_2[i]);
93 if (!d->name) {
94 break;
95 }
96 switch (d->typ) {
97 case flag_type_e::Bool:
98 log("b = %d", d->val.b);
99 break;
100 case flag_type_e::Int:
101 log("i = %d", d->val.i);
102 break;
103 case flag_type_e::Float:
104 log("b = %f", d->val.f);
105 break;
106 case flag_type_e::Str:
107 log("b = %s", d->val.s);
108 break;
109 }
110 ++i;
111 }
112
113 PASS();
114}
115
116TEST show_sizeof() {
117 log("sizeof(flag_spec::_FlagSpecAndMore) = %d",
118 sizeof(flag_spec::_FlagSpecAndMore));
119 // alignment is 8, so why doesn't it work?
120 log("alignof(flag_spec::_FlagSpecAndMore) = %d",
121 alignof(flag_spec::_FlagSpecAndMore));
122
123#if 0
124 // throw off the alignment
125 __attribute__((unused)) auto i = new bool[1];
126#endif
127
128 auto out = Alloc<flag_spec::_FlagSpecAndMore>();
129 log("sizeof(out) = %d", sizeof(out));
130
131 log("sizeof(flag_spec::_FlagSpec) = %d", sizeof(flag_spec::_FlagSpec));
132 // alignment is 8, so why doesn't it work?
133 log("alignof(flag_spec::_FlagSpec) = %d", alignof(flag_spec::_FlagSpec));
134 auto out2 = Alloc<flag_spec::_FlagSpec>();
135 log("sizeof(out2) = %d", sizeof(out2));
136
137 PASS();
138}
139
140GREATEST_MAIN_DEFS();
141
142int main(int argc, char** argv) {
143 gHeap.Init();
144
145 GREATEST_MAIN_BEGIN();
146
147 RUN_TEST(flag_spec_test);
148 RUN_TEST(show_sizeof);
149
150 gHeap.CleanProcessExit();
151
152 GREATEST_MAIN_END(); /* display results */
153 return 0;
154}