OILS / cpp / frontend_flag_spec.h View on Github | oils.pub

153 lines, 103 significant
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)
12namespace args {
13class _Action;
14class _Attributes;
15class Reader;
16}; // namespace args
17
18//
19// Types for compile-time FlagSpec
20//
21
22union Val_c {
23 bool b;
24 int i;
25 float f;
26 const char* s;
27};
28
29struct 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
36enum 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
60struct 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
68struct 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
77struct 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
86namespace flag_spec {
87
88class _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
117class _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
145namespace flag_util {
146
147// for testing only
148flag_spec::_FlagSpec* LookupFlagSpec(BigStr* spec_name);
149flag_spec::_FlagSpecAndMore* LookupFlagSpec2(BigStr* spec_name);
150
151} // namespace flag_util
152
153#endif // FRONTEND_FLAG_SPEC_H