cpp

Coverage Report

Created: 2023-09-13 01:07

/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
      : arity0(nullptr),
89
        arity1(nullptr),
90
        plus_flags(nullptr),
91
        actions_long(nullptr),
92
3
        defaults(nullptr) {
93
3
  }
94
95
3
  static constexpr ObjHeader obj_header() {
96
3
    return ObjHeader::ClassFixed(field_mask(), sizeof(_FlagSpec));
97
3
  }
98
99
  List<Str*>* arity0;
100
  Dict<Str*, args::_Action*>* arity1;
101
  List<Str*>* plus_flags;
102
  Dict<Str*, args::_Action*>* actions_long;
103
  Dict<Str*, runtime_asdl::value_t*>* defaults;
104
105
3
  static constexpr uint32_t field_mask() {
106
3
    return maskbit(offsetof(_FlagSpec, arity0)) |
107
3
           maskbit(offsetof(_FlagSpec, arity1)) |
108
3
           maskbit(offsetof(_FlagSpec, plus_flags)) |
109
3
           maskbit(offsetof(_FlagSpec, actions_long)) |
110
3
           maskbit(offsetof(_FlagSpec, defaults));
111
3
  }
112
};
113
114
class _FlagSpecAndMore {
115
 public:
116
  _FlagSpecAndMore()
117
      : actions_long(nullptr),
118
        actions_short(nullptr),
119
        plus_flags(nullptr),
120
2
        defaults(nullptr) {
121
2
  }
122
123
2
  static constexpr ObjHeader obj_header() {
124
2
    return ObjHeader::ClassFixed(field_mask(), sizeof(_FlagSpecAndMore));
125
2
  }
126
127
  Dict<Str*, args::_Action*>* actions_long;
128
  Dict<Str*, args::_Action*>* actions_short;
129
  List<Str*>* plus_flags;
130
  Dict<Str*, runtime_asdl::value_t*>* defaults;
131
132
2
  static constexpr uint32_t field_mask() {
133
2
    return maskbit(offsetof(_FlagSpecAndMore, actions_long)) |
134
2
           maskbit(offsetof(_FlagSpecAndMore, actions_short)) |
135
2
           maskbit(offsetof(_FlagSpecAndMore, plus_flags)) |
136
2
           maskbit(offsetof(_FlagSpecAndMore, defaults));
137
2
  }
138
};
139
140
// for testing only
141
flag_spec::_FlagSpec* LookupFlagSpec(Str* spec_name);
142
flag_spec::_FlagSpecAndMore* LookupFlagSpec2(Str* spec_name);
143
144
args::_Attributes* Parse(Str* spec_name, args::Reader* arg_r);
145
146
Tuple2<args::_Attributes*, args::Reader*> ParseCmdVal(
147
    Str* spec_name, runtime_asdl::cmd_value::Argv* cmd_val);
148
149
// With optional arg
150
Tuple2<args::_Attributes*, args::Reader*> ParseCmdVal(
151
    Str* spec_name, runtime_asdl::cmd_value::Argv* cmd_val,
152
    bool accept_typed_args);
153
154
Tuple2<args::_Attributes*, args::Reader*> ParseLikeEcho(
155
    Str* spec_name, runtime_asdl::cmd_value::Argv* cmd_val);
156
157
args::_Attributes* ParseMore(Str* spec_name, args::Reader* arg_r);
158
159
}  // namespace flag_spec
160
161
#endif  // FRONTEND_FLAG_SPEC_H