| 1 | #include "cpp/frontend_flag_spec.h"
 | 
| 2 | 
 | 
| 3 | #include "vendor/greatest.h"
 | 
| 4 | 
 | 
| 5 | using 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 | 
 | 
| 18 | const char* arity0_1[] = {"foo", "bar", nullptr};
 | 
| 19 | 
 | 
| 20 | Action_c arity1_1[] = {
 | 
| 21 |     {"z", ActionType_c::SetToInt, "z"},
 | 
| 22 |     {"zz", ActionType_c::SetToString, "zz"},
 | 
| 23 |     {},  // sentinel
 | 
| 24 | };
 | 
| 25 | 
 | 
| 26 | Action_c actions_long_1[] = {
 | 
| 27 |     {"all", ActionType_c::SetToTrue, "all"},
 | 
| 28 |     {"line", ActionType_c::SetToTrue, "line"},
 | 
| 29 |     {},  // sentinel
 | 
| 30 | };
 | 
| 31 | 
 | 
| 32 | const char* plus_1[] = {"o", "p", nullptr};
 | 
| 33 | 
 | 
| 34 | DefaultPair_c defaults_1[] = {
 | 
| 35 |     {"x", flag_type_e::Bool},
 | 
| 36 |     {"y", flag_type_e::Int},
 | 
| 37 |     {},
 | 
| 38 | };
 | 
| 39 | 
 | 
| 40 | DefaultPair_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 | 
 | 
| 48 | FlagSpec_c spec1 = {"export",       arity0_1, arity1_1,
 | 
| 49 |                     actions_long_1, plus_1,   defaults_1};
 | 
| 50 | // a copy for demonstrations
 | 
| 51 | FlagSpec_c spec2 = {"unset",        arity0_1, arity1_1,
 | 
| 52 |                     actions_long_1, plus_1,   defaults_1};
 | 
| 53 | 
 | 
| 54 | TEST 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 | 
 | 
| 116 | TEST 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 | 
 | 
| 140 | GREATEST_MAIN_DEFS();
 | 
| 141 | 
 | 
| 142 | int 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 | }
 |