cpp

Coverage Report

Created: 2025-05-18 18:20

/home/uke/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
49
  while (true) {
20
49
    const char* s = in[i];
21
49
    if (!s) {
22
7
      break;
23
7
    }
24
    // log("a0 %s", s);
25
42
    out->append(StrFromC(s));
26
42
    ++i;
27
42
  }
28
7
}
29
30
void _CreateDefaults(DefaultPair_c* in,
31
3
                     Dict<BigStr*, value_asdl::value_t*>* out) {
32
3
  int i = 0;
33
38
  while (true) {
34
38
    DefaultPair_c* pair = &(in[i]);
35
38
    if (!pair->name) {
36
3
      break;
37
3
    }
38
35
    value_t* val;
39
35
    switch (pair->typ) {
40
23
    case flag_type_e::Bool:
41
23
      val = Alloc<value::Bool>(pair->val.b);
42
23
      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
35
    }
60
35
    out->set(StrFromC(pair->name), val);
61
35
    ++i;
62
35
  }
63
3
}
64
65
2
void _CreateActions(Action_c* in, Dict<BigStr*, args::_Action*>* out) {
66
2
  int i = 0;
67
35
  while (true) {
68
35
    Action_c* p = &(in[i]);
69
35
    if (!p->key) {
70
2
      break;
71
2
    }
72
    // log("a1 %s", p->name);
73
33
    args::_Action* action = nullptr;
74
33
    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
9
    case ActionType_c::SetOption:
100
9
      action = Alloc<args::SetOption>(StrFromC(p->name));
101
9
      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
2
    case ActionType_c::AppendEvalFlag:
127
2
      action = Alloc<args::AppendEvalFlag>(StrFromC(p->name));
128
2
      break;
129
33
    }  // switch
130
131
33
    if (action) {
132
33
      out->set(StrFromC(p->key), action);
133
33
    }
134
33
    ++i;
135
33
  }
136
2
}
137
138
// Convenience function
139
template <typename K, typename V>
140
9
Dict<K, V>* NewDict() {
141
9
  return Alloc<Dict<K, V>>();
142
9
}
_ZN9flag_util7NewDictIP6BigStrPN4args7_ActionEEEP4DictIT_T0_Ev
Line
Count
Source
140
6
Dict<K, V>* NewDict() {
141
6
  return Alloc<Dict<K, V>>();
142
6
}
_ZN9flag_util7NewDictIP6BigStrPN10value_asdl7value_tEEEP4DictIT_T0_Ev
Line
Count
Source
140
3
Dict<K, V>* NewDict() {
141
3
  return Alloc<Dict<K, V>>();
142
3
}
143
144
// "Inflate" the static C data into a heap-allocated ASDL data structure.
145
//
146
// TODO: Make a GLOBAL CACHE?  It could be shared between subinterpreters even?
147
2
flag_spec::_FlagSpec* CreateSpec(FlagSpec_c* in) {
148
2
  auto out = Alloc<flag_spec::_FlagSpec>();
149
2
  out->arity0 = NewList<BigStr*>();
150
2
  out->arity1 = NewDict<BigStr*, args::_Action*>();
151
2
  out->actions_long = NewDict<BigStr*, args::_Action*>();
152
2
  out->plus_flags = NewList<BigStr*>();
153
2
  out->defaults = NewDict<BigStr*, value_asdl::value_t*>();
154
155
2
  if (in->arity0) {
156
2
    _CreateStrList(in->arity0, out->arity0);
157
2
  }
158
2
  if (in->arity1) {
159
0
    _CreateActions(in->arity1, out->arity1);
160
0
  }
161
2
  if (in->actions_long) {
162
0
    _CreateActions(in->actions_long, out->actions_long);
163
0
  }
164
2
  if (in->plus_flags) {
165
1
    _CreateStrList(in->plus_flags, out->plus_flags);
166
1
  }
167
2
  if (in->defaults) {
168
2
    _CreateDefaults(in->defaults, out->defaults);
169
2
  }
170
2
  return out;
171
2
}
172
173
1
flag_spec::_FlagSpecAndMore* CreateSpec2(FlagSpecAndMore_c* in) {
174
1
  auto out = Alloc<flag_spec::_FlagSpecAndMore>();
175
1
  out->actions_short = NewDict<BigStr*, args::_Action*>();
176
1
  out->actions_long = NewDict<BigStr*, args::_Action*>();
177
1
  out->plus_flags = NewList<BigStr*>();
178
1
  out->defaults = NewDict<BigStr*, value_asdl::value_t*>();
179
180
1
  if (in->actions_short) {
181
1
    _CreateActions(in->actions_short, out->actions_short);
182
1
  }
183
1
  if (in->actions_long) {
184
1
    _CreateActions(in->actions_long, out->actions_long);
185
1
  }
186
1
  if (in->plus_flags) {
187
1
    _CreateStrList(in->plus_flags, out->plus_flags);
188
1
  }
189
1
  if (in->defaults) {
190
1
    _CreateDefaults(in->defaults, out->defaults);
191
1
  }
192
1
  return out;
193
1
}
194
195
using arg_types::kFlagSpecs;
196
using arg_types::kFlagSpecsAndMore;
197
198
3
flag_spec::_FlagSpec* LookupFlagSpec(BigStr* spec_name) {
199
3
  int i = 0;
200
113
  while (true) {
201
113
    const char* name = kFlagSpecs[i].name;
202
113
    if (name == nullptr) {
203
1
      break;
204
1
    }
205
112
    if (str_equals0(name, spec_name)) {
206
      // log("%s found", spec_name->data_);
207
2
      return CreateSpec(&kFlagSpecs[i]);
208
2
    }
209
210
110
    i++;
211
110
  }
212
  // log("%s not found", spec_name->data_);
213
1
  return nullptr;
214
3
}
215
216
2
flag_spec::_FlagSpecAndMore* LookupFlagSpec2(BigStr* spec_name) {
217
2
  int i = 0;
218
14
  while (true) {
219
14
    const char* name = kFlagSpecsAndMore[i].name;
220
14
    if (name == nullptr) {
221
1
      break;
222
1
    }
223
13
    if (str_equals0(name, spec_name)) {
224
      // log("%s found", spec_name->data_);
225
1
      return CreateSpec2(&kFlagSpecsAndMore[i]);
226
1
    }
227
228
12
    i++;
229
12
  }
230
  // log("%s not found", spec_name->data_);
231
1
  return nullptr;
232
2
}
233
234
}  // namespace flag_util