cpp

Coverage Report

Created: 2024-03-13 14:13

/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/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)
12
namespace args {
13
class _Action;
14
class _Attributes;
15
class Reader;
16
};  // namespace args
17
18
//
19
// Types for compile-time FlagSpec
20
//
21
22
union Val_c {
23
  bool b;
24
  int i;
25
  float f;
26
  const char* s;
27
};
28
29
struct 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
36
enum 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
58
struct 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
66
struct 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
75
struct 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
84
namespace flag_spec {
85
86
class _FlagSpec {
87
 public:
88
  _FlagSpec()
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
  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
3
  static constexpr uint32_t field_mask() {
107
3
    return maskbit(offsetof(_FlagSpec, arity0)) |
108
3
           maskbit(offsetof(_FlagSpec, arity1)) |
109
3
           maskbit(offsetof(_FlagSpec, plus_flags)) |
110
3
           maskbit(offsetof(_FlagSpec, actions_long)) |
111
3
           maskbit(offsetof(_FlagSpec, defaults));
112
3
  }
113
};
114
115
class _FlagSpecAndMore {
116
 public:
117
  _FlagSpecAndMore()
118
      : actions_long(nullptr),
119
        actions_short(nullptr),
120
        plus_flags(nullptr),
121
2
        defaults(nullptr) {
122
2
  }
123
124
2
  static constexpr ObjHeader obj_header() {
125
2
    return ObjHeader::ClassFixed(field_mask(), sizeof(_FlagSpecAndMore));
126
2
  }
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
2
  static constexpr uint32_t field_mask() {
134
2
    return maskbit(offsetof(_FlagSpecAndMore, actions_long)) |
135
2
           maskbit(offsetof(_FlagSpecAndMore, actions_short)) |
136
2
           maskbit(offsetof(_FlagSpecAndMore, plus_flags)) |
137
2
           maskbit(offsetof(_FlagSpecAndMore, defaults));
138
2
  }
139
};
140
141
}  // namespace flag_spec
142
143
namespace flag_util {
144
145
// for testing only
146
flag_spec::_FlagSpec* LookupFlagSpec(BigStr* spec_name);
147
flag_spec::_FlagSpecAndMore* LookupFlagSpec2(BigStr* spec_name);
148
149
}  // namespace flag_util
150
151
#endif  // FRONTEND_FLAG_SPEC_H