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

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