| 1 | // frontend_flag_spec.h
 | 
| 2 | 
 | 
| 3 | #ifndef FRONTEND_FLAG_SPEC_H
 | 
| 4 | #define FRONTEND_FLAG_SPEC_H
 | 
| 5 | 
 | 
| 6 | #include "_gen/core/runtime.asdl.h"
 | 
| 7 | #include "_gen/core/value.asdl.h"
 | 
| 8 | #include "_gen/frontend/id_kind.asdl.h"
 | 
| 9 | #include "mycpp/runtime.h"
 | 
| 10 | 
 | 
| 11 | // Forward declarations (can't include osh_eval.h)
 | 
| 12 | namespace args {
 | 
| 13 | class _Action;
 | 
| 14 | class _Attributes;
 | 
| 15 | class Reader;
 | 
| 16 | };  // namespace args
 | 
| 17 | 
 | 
| 18 | //
 | 
| 19 | // Types for compile-time FlagSpec
 | 
| 20 | //
 | 
| 21 | 
 | 
| 22 | union Val_c {
 | 
| 23 |   bool b;
 | 
| 24 |   int i;
 | 
| 25 |   float f;
 | 
| 26 |   const char* s;
 | 
| 27 | };
 | 
| 28 | 
 | 
| 29 | struct DefaultPair_c {
 | 
| 30 |   const char* name;
 | 
| 31 |   runtime_asdl::flag_type_t typ;
 | 
| 32 |   Val_c val;
 | 
| 33 | };
 | 
| 34 | 
 | 
| 35 | // all concrete subtypes of args::_Action
 | 
| 36 | enum class ActionType_c {
 | 
| 37 |   SetToString,    // name, valid
 | 
| 38 |   SetToString_q,  // hack for quit_parsing_flags
 | 
| 39 | 
 | 
| 40 |   SetToInt,         // name
 | 
| 41 |   SetToFloat,       // name
 | 
| 42 |   SetToTrue,        // name
 | 
| 43 |   SetAttachedBool,  // name, for OilFlags
 | 
| 44 | 
 | 
| 45 |   SetOption,             // name
 | 
| 46 |   SetNamedOption,        // no args, valid
 | 
| 47 |   SetNamedOption_shopt,  // no args, valid
 | 
| 48 |   SetAction,             // name
 | 
| 49 |   SetNamedAction,        // no args, valid
 | 
| 50 | };
 | 
| 51 | 
 | 
| 52 | // TODO: Figure out the difference between name and key
 | 
| 53 | // key = '--ast-format'
 | 
| 54 | // name = 'ast-format'
 | 
| 55 | // out.Set('ast-format', ...)
 | 
| 56 | // So I want to compress these two
 | 
| 57 | 
 | 
| 58 | struct Action_c {
 | 
| 59 |   const char* key;
 | 
| 60 |   ActionType_c type;
 | 
| 61 |   const char* name;
 | 
| 62 |   // for --ast-format, SetNamedAction(), SetNamedOption()
 | 
| 63 |   const char** strs;
 | 
| 64 | };
 | 
| 65 | 
 | 
| 66 | struct FlagSpec_c {
 | 
| 67 |   const char* name;         // e.g. 'wait'
 | 
| 68 |   const char** arity0;      // NULL terminated array
 | 
| 69 |   Action_c* arity1;         // NULL terminated array
 | 
| 70 |   Action_c* actions_long;   // NULL terminated array
 | 
| 71 |   const char** plus_flags;  // NULL terminated array
 | 
| 72 |   DefaultPair_c* defaults;
 | 
| 73 | };
 | 
| 74 | 
 | 
| 75 | struct FlagSpecAndMore_c {
 | 
| 76 |   const char* name;  // e.g. 'osh'
 | 
| 77 |   // These are Dict[str, _Action]
 | 
| 78 |   Action_c* actions_short;
 | 
| 79 |   Action_c* actions_long;
 | 
| 80 |   const char** plus_flags;  // NULL terminated array
 | 
| 81 |   DefaultPair_c* defaults;
 | 
| 82 | };
 | 
| 83 | 
 | 
| 84 | namespace flag_spec {
 | 
| 85 | 
 | 
| 86 | class _FlagSpec {
 | 
| 87 |  public:
 | 
| 88 |   _FlagSpec()
 | 
| 89 |       : arity0(nullptr),
 | 
| 90 |         arity1(nullptr),
 | 
| 91 |         plus_flags(nullptr),
 | 
| 92 |         actions_long(nullptr),
 | 
| 93 |         defaults(nullptr) {
 | 
| 94 |   }
 | 
| 95 | 
 | 
| 96 |   static constexpr ObjHeader obj_header() {
 | 
| 97 |     return ObjHeader::ClassFixed(field_mask(), sizeof(_FlagSpec));
 | 
| 98 |   }
 | 
| 99 | 
 | 
| 100 |   List<BigStr*>* arity0;
 | 
| 101 |   Dict<BigStr*, args::_Action*>* arity1;
 | 
| 102 |   List<BigStr*>* plus_flags;
 | 
| 103 |   Dict<BigStr*, args::_Action*>* actions_long;
 | 
| 104 |   Dict<BigStr*, value_asdl::value_t*>* defaults;
 | 
| 105 | 
 | 
| 106 |   static constexpr uint32_t field_mask() {
 | 
| 107 |     return maskbit(offsetof(_FlagSpec, arity0)) |
 | 
| 108 |            maskbit(offsetof(_FlagSpec, arity1)) |
 | 
| 109 |            maskbit(offsetof(_FlagSpec, plus_flags)) |
 | 
| 110 |            maskbit(offsetof(_FlagSpec, actions_long)) |
 | 
| 111 |            maskbit(offsetof(_FlagSpec, defaults));
 | 
| 112 |   }
 | 
| 113 | };
 | 
| 114 | 
 | 
| 115 | class _FlagSpecAndMore {
 | 
| 116 |  public:
 | 
| 117 |   _FlagSpecAndMore()
 | 
| 118 |       : actions_long(nullptr),
 | 
| 119 |         actions_short(nullptr),
 | 
| 120 |         plus_flags(nullptr),
 | 
| 121 |         defaults(nullptr) {
 | 
| 122 |   }
 | 
| 123 | 
 | 
| 124 |   static constexpr ObjHeader obj_header() {
 | 
| 125 |     return ObjHeader::ClassFixed(field_mask(), sizeof(_FlagSpecAndMore));
 | 
| 126 |   }
 | 
| 127 | 
 | 
| 128 |   Dict<BigStr*, args::_Action*>* actions_long;
 | 
| 129 |   Dict<BigStr*, args::_Action*>* actions_short;
 | 
| 130 |   List<BigStr*>* plus_flags;
 | 
| 131 |   Dict<BigStr*, value_asdl::value_t*>* defaults;
 | 
| 132 | 
 | 
| 133 |   static constexpr uint32_t field_mask() {
 | 
| 134 |     return maskbit(offsetof(_FlagSpecAndMore, actions_long)) |
 | 
| 135 |            maskbit(offsetof(_FlagSpecAndMore, actions_short)) |
 | 
| 136 |            maskbit(offsetof(_FlagSpecAndMore, plus_flags)) |
 | 
| 137 |            maskbit(offsetof(_FlagSpecAndMore, defaults));
 | 
| 138 |   }
 | 
| 139 | };
 | 
| 140 | 
 | 
| 141 | }  // namespace flag_spec
 | 
| 142 | 
 | 
| 143 | namespace flag_util {
 | 
| 144 | 
 | 
| 145 | // for testing only
 | 
| 146 | flag_spec::_FlagSpec* LookupFlagSpec(BigStr* spec_name);
 | 
| 147 | flag_spec::_FlagSpecAndMore* LookupFlagSpec2(BigStr* spec_name);
 | 
| 148 | 
 | 
| 149 | }  // namespace flag_util
 | 
| 150 | 
 | 
| 151 | #endif  // FRONTEND_FLAG_SPEC_H
 |