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
|