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 | AppendEvalFlag, // no args, valid
|
52 | };
|
53 |
|
54 | // TODO: Figure out the difference between name and key
|
55 | // key = '--ast-format'
|
56 | // name = 'ast-format'
|
57 | // out.Set('ast-format', ...)
|
58 | // So I want to compress these two
|
59 |
|
60 | struct Action_c {
|
61 | const char* key;
|
62 | ActionType_c type;
|
63 | const char* name;
|
64 | // for --ast-format, SetNamedAction(), SetNamedOption()
|
65 | const char** strs;
|
66 | };
|
67 |
|
68 | struct FlagSpec_c {
|
69 | const char* name; // e.g. 'wait'
|
70 | const char** arity0; // NULL terminated array
|
71 | Action_c* arity1; // NULL terminated array
|
72 | Action_c* actions_long; // NULL terminated array
|
73 | const char** plus_flags; // NULL terminated array
|
74 | DefaultPair_c* defaults;
|
75 | };
|
76 |
|
77 | struct FlagSpecAndMore_c {
|
78 | const char* name; // e.g. 'osh'
|
79 | // These are Dict[str, _Action]
|
80 | Action_c* actions_short;
|
81 | Action_c* actions_long;
|
82 | const char** plus_flags; // NULL terminated array
|
83 | DefaultPair_c* defaults;
|
84 | };
|
85 |
|
86 | namespace flag_spec {
|
87 |
|
88 | class _FlagSpec {
|
89 | public:
|
90 | _FlagSpec()
|
91 | : arity0(nullptr),
|
92 | arity1(nullptr),
|
93 | plus_flags(nullptr),
|
94 | actions_long(nullptr),
|
95 | defaults(nullptr) {
|
96 | }
|
97 |
|
98 | static constexpr ObjHeader obj_header() {
|
99 | return ObjHeader::ClassFixed(field_mask(), sizeof(_FlagSpec));
|
100 | }
|
101 |
|
102 | List<BigStr*>* arity0;
|
103 | Dict<BigStr*, args::_Action*>* arity1;
|
104 | List<BigStr*>* plus_flags;
|
105 | Dict<BigStr*, args::_Action*>* actions_long;
|
106 | Dict<BigStr*, value_asdl::value_t*>* defaults;
|
107 |
|
108 | static constexpr uint32_t field_mask() {
|
109 | return maskbit(offsetof(_FlagSpec, arity0)) |
|
110 | maskbit(offsetof(_FlagSpec, arity1)) |
|
111 | maskbit(offsetof(_FlagSpec, plus_flags)) |
|
112 | maskbit(offsetof(_FlagSpec, actions_long)) |
|
113 | maskbit(offsetof(_FlagSpec, defaults));
|
114 | }
|
115 | };
|
116 |
|
117 | class _FlagSpecAndMore {
|
118 | public:
|
119 | _FlagSpecAndMore()
|
120 | : actions_long(nullptr),
|
121 | actions_short(nullptr),
|
122 | plus_flags(nullptr),
|
123 | defaults(nullptr) {
|
124 | }
|
125 |
|
126 | static constexpr ObjHeader obj_header() {
|
127 | return ObjHeader::ClassFixed(field_mask(), sizeof(_FlagSpecAndMore));
|
128 | }
|
129 |
|
130 | Dict<BigStr*, args::_Action*>* actions_long;
|
131 | Dict<BigStr*, args::_Action*>* actions_short;
|
132 | List<BigStr*>* plus_flags;
|
133 | Dict<BigStr*, value_asdl::value_t*>* defaults;
|
134 |
|
135 | static constexpr uint32_t field_mask() {
|
136 | return maskbit(offsetof(_FlagSpecAndMore, actions_long)) |
|
137 | maskbit(offsetof(_FlagSpecAndMore, actions_short)) |
|
138 | maskbit(offsetof(_FlagSpecAndMore, plus_flags)) |
|
139 | maskbit(offsetof(_FlagSpecAndMore, defaults));
|
140 | }
|
141 | };
|
142 |
|
143 | } // namespace flag_spec
|
144 |
|
145 | namespace flag_util {
|
146 |
|
147 | // for testing only
|
148 | flag_spec::_FlagSpec* LookupFlagSpec(BigStr* spec_name);
|
149 | flag_spec::_FlagSpecAndMore* LookupFlagSpec2(BigStr* spec_name);
|
150 |
|
151 | } // namespace flag_util
|
152 |
|
153 | #endif // FRONTEND_FLAG_SPEC_H
|