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