cpp

Coverage Report

Created: 2024-03-13 14:13

/home/andy/git/oilshell/oil/cpp/frontend_flag_spec.cc
Line
Count
Source (jump to first uncovered line)
1
// frontend_flag_spec.cc
2
3
#include "cpp/frontend_flag_spec.h"
4
5
#include "_gen/frontend/arg_types.h"
6
#include "mycpp/gc_builtins.h"
7
// TODO: This prebuilt header should not be included in the tarball
8
// for definition of args::Reader, etc.
9
#include "prebuilt/frontend/args.mycpp.h"
10
11
namespace flag_util {
12
13
using runtime_asdl::flag_type_e;
14
using value_asdl::value;
15
using value_asdl::value_t;
16
17
7
void _CreateStrList(const char** in, List<BigStr*>* out) {
18
7
  int i = 0;
19
45
  while (true) {
20
45
    const char* s = in[i];
21
45
    if (!s) {
22
7
      break;
23
7
    }
24
    // log("a0 %s", s);
25
38
    out->append(StrFromC(s));
26
38
    ++i;
27
38
  }
28
7
}
29
30
void _CreateDefaults(DefaultPair_c* in,
31
3
                     Dict<BigStr*, value_asdl::value_t*>* out) {
32
3
  int i = 0;
33
36
  while (true) {
34
36
    DefaultPair_c* pair = &(in[i]);
35
36
    if (!pair->name) {
36
3
      break;
37
3
    }
38
33
    value_t* val;
39
33
    switch (pair->typ) {
40
21
    case flag_type_e::Bool:
41
21
      val = Alloc<value::Bool>(pair->val.b);
42
21
      break;
43
1
    case flag_type_e::Int:
44
1
      val = Alloc<value::Int>(pair->val.i);
45
1
      break;
46
0
    case flag_type_e::Float:
47
0
      val = Alloc<value::Float>(pair->val.f);
48
0
      break;
49
11
    case flag_type_e::Str: {
50
11
      const char* s = pair->val.s;
51
11
      if (s == nullptr) {
52
8
        val = value::Undef;
53
8
      } else {
54
3
        val = Alloc<value::Str>(StrFromC(s));
55
3
      }
56
11
    } break;
57
0
    default:
58
0
      FAIL(kShouldNotGetHere);
59
33
    }
60
33
    out->set(StrFromC(pair->name), val);
61
33
    ++i;
62
33
  }
63
3
}
64
65
2
void _CreateActions(Action_c* in, Dict<BigStr*, args::_Action*>* out) {
66
2
  int i = 0;
67
32
  while (true) {
68
32
    Action_c* p = &(in[i]);
69
32
    if (!p->key) {
70
2
      break;
71
2
    }
72
    // log("a1 %s", p->name);
73
30
    args::_Action* action = nullptr;
74
30
    switch (p->type) {
75
7
    case ActionType_c::SetToString: {
76
7
      List<BigStr*>* valid = nullptr;
77
7
      if (p->strs) {
78
3
        valid = NewList<BigStr*>();
79
3
        _CreateStrList(p->strs, valid);
80
3
      }
81
7
      auto a = Alloc<args::SetToString>(StrFromC(p->name), false, valid);
82
7
      action = a;
83
7
    } break;
84
1
    case ActionType_c::SetToString_q:
85
1
      action = Alloc<args::SetToString>(StrFromC(p->name), true, nullptr);
86
1
      break;
87
1
    case ActionType_c::SetToInt:
88
1
      action = Alloc<args::SetToInt>(StrFromC(p->name));
89
1
      break;
90
0
    case ActionType_c::SetToFloat:
91
0
      action = Alloc<args::SetToFloat>(StrFromC(p->name));
92
0
      break;
93
11
    case ActionType_c::SetToTrue:
94
11
      action = Alloc<args::SetToTrue>(StrFromC(p->name));
95
11
      break;
96
0
    case ActionType_c::SetAttachedBool:
97
0
      action = Alloc<args::SetAttachedBool>(StrFromC(p->name));
98
0
      break;
99
8
    case ActionType_c::SetOption:
100
8
      action = Alloc<args::SetOption>(StrFromC(p->name));
101
8
      break;
102
1
    case ActionType_c::SetNamedOption: {
103
1
      auto a = Alloc<args::SetNamedOption>(false);
104
1
      if (p->strs) {
105
0
        _CreateStrList(p->strs, a->names);
106
0
      }
107
1
      action = a;
108
1
    } break;
109
1
    case ActionType_c::SetNamedOption_shopt: {
110
1
      auto a = Alloc<args::SetNamedOption>(true);
111
1
      if (p->strs) {
112
0
        _CreateStrList(p->strs, a->names);
113
0
      }
114
1
      action = a;
115
1
    } break;
116
0
    case ActionType_c::SetAction:
117
0
      action = Alloc<args::SetAction>(StrFromC(p->name));
118
0
      break;
119
0
    case ActionType_c::SetNamedAction: {
120
0
      auto a = Alloc<args::SetNamedAction>();
121
0
      if (p->strs) {
122
0
        _CreateStrList(p->strs, a->names);
123
0
      }
124
0
      action = a;
125
0
    } break;
126
30
    }
127
128
30
    if (action) {
129
30
      out->set(StrFromC(p->key), action);
130
30
    }
131
30
    ++i;
132
30
  }
133
2
}
134
135
// Convenience function
136
template <typename K, typename V>
137
9
Dict<K, V>* NewDict() {
138
9
  return Alloc<Dict<K, V>>();
139
9
}
_ZN9flag_util7NewDictIP6BigStrPN4args7_ActionEEEP4DictIT_T0_Ev
Line
Count
Source
137
6
Dict<K, V>* NewDict() {
138
6
  return Alloc<Dict<K, V>>();
139
6
}
_ZN9flag_util7NewDictIP6BigStrPN10value_asdl7value_tEEEP4DictIT_T0_Ev
Line
Count
Source
137
3
Dict<K, V>* NewDict() {
138
3
  return Alloc<Dict<K, V>>();
139
3
}
140
141
// "Inflate" the static C data into a heap-allocated ASDL data structure.
142
//
143
// TODO: Make a GLOBAL CACHE?  It could be shared between subinterpreters even?
144
2
flag_spec::_FlagSpec* CreateSpec(FlagSpec_c* in) {
145
2
  auto out = Alloc<flag_spec::_FlagSpec>();
146
2
  out->arity0 = NewList<BigStr*>();
147
2
  out->arity1 = NewDict<BigStr*, args::_Action*>();
148
2
  out->actions_long = NewDict<BigStr*, args::_Action*>();
149
2
  out->plus_flags = NewList<BigStr*>();
150
2
  out->defaults = NewDict<BigStr*, value_asdl::value_t*>();
151
152
2
  if (in->arity0) {
153
2
    _CreateStrList(in->arity0, out->arity0);
154
2
  }
155
2
  if (in->arity1) {
156
0
    _CreateActions(in->arity1, out->arity1);
157
0
  }
158
2
  if (in->actions_long) {
159
0
    _CreateActions(in->actions_long, out->actions_long);
160
0
  }
161
2
  if (in->plus_flags) {
162
1
    _CreateStrList(in->plus_flags, out->plus_flags);
163
1
  }
164
2
  if (in->defaults) {
165
2
    _CreateDefaults(in->defaults, out->defaults);
166
2
  }
167
2
  return out;
168
2
}
169
170
1
flag_spec::_FlagSpecAndMore* CreateSpec2(FlagSpecAndMore_c* in) {
171
1
  auto out = Alloc<flag_spec::_FlagSpecAndMore>();
172
1
  out->actions_short = NewDict<BigStr*, args::_Action*>();
173
1
  out->actions_long = NewDict<BigStr*, args::_Action*>();
174
1
  out->plus_flags = NewList<BigStr*>();
175
1
  out->defaults = NewDict<BigStr*, value_asdl::value_t*>();
176
177
1
  if (in->actions_short) {
178
1
    _CreateActions(in->actions_short, out->actions_short);
179
1
  }
180
1
  if (in->actions_long) {
181
1
    _CreateActions(in->actions_long, out->actions_long);
182
1
  }
183
1
  if (in->plus_flags) {
184
1
    _CreateStrList(in->plus_flags, out->plus_flags);
185
1
  }
186
1
  if (in->defaults) {
187
1
    _CreateDefaults(in->defaults, out->defaults);
188
1
  }
189
1
  return out;
190
1
}
191
192
using arg_types::kFlagSpecs;
193
using arg_types::kFlagSpecsAndMore;
194
195
3
flag_spec::_FlagSpec* LookupFlagSpec(BigStr* spec_name) {
196
3
  int i = 0;
197
102
  while (true) {
198
102
    const char* name = kFlagSpecs[i].name;
199
102
    if (name == nullptr) {
200
1
      break;
201
1
    }
202
101
    if (str_equals0(name, spec_name)) {
203
      // log("%s found", spec_name->data_);
204
2
      return CreateSpec(&kFlagSpecs[i]);
205
2
    }
206
207
99
    i++;
208
99
  }
209
  // log("%s not found", spec_name->data_);
210
1
  return nullptr;
211
3
}
212
213
2
flag_spec::_FlagSpecAndMore* LookupFlagSpec2(BigStr* spec_name) {
214
2
  int i = 0;
215
14
  while (true) {
216
14
    const char* name = kFlagSpecsAndMore[i].name;
217
14
    if (name == nullptr) {
218
1
      break;
219
1
    }
220
13
    if (str_equals0(name, spec_name)) {
221
      // log("%s found", spec_name->data_);
222
1
      return CreateSpec2(&kFlagSpecsAndMore[i]);
223
1
    }
224
225
12
    i++;
226
12
  }
227
  // log("%s not found", spec_name->data_);
228
1
  return nullptr;
229
2
}
230
231
}  // namespace flag_util