cpp

Coverage Report

Created: 2023-03-07 20:24

/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