OILS / cpp / frontend_flag_spec.h View on Github | oilshell.org

151 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 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
58struct 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
66struct 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
75struct 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
84namespace flag_spec {
85
86class _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
115class _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
143namespace flag_util {
144
145// for testing only
146flag_spec::_FlagSpec* LookupFlagSpec(BigStr* spec_name);
147flag_spec::_FlagSpecAndMore* LookupFlagSpec2(BigStr* spec_name);
148
149} // namespace flag_util
150
151#endif // FRONTEND_FLAG_SPEC_H