• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nickg / nvc / 15665032143

15 Jun 2025 04:09PM UTC coverage: 92.197% (+0.007%) from 92.19%
15665032143

push

github

nickg
Generate 'instance_name and 'path_name dynamically at runtime

76 of 79 new or added lines in 5 files covered. (96.2%)

204 existing lines in 9 files now uncovered.

69656 of 75551 relevant lines covered (92.2%)

572648.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.21
/src/vlog/vlog-node.c
1
//
2
//  Copyright (C) 2022-2025  Nick Gasson
3
//
4
//  This program is free software: you can redistribute it and/or modify
5
//  it under the terms of the GNU General Public License as published by
6
//  the Free Software Foundation, either version 3 of the License, or
7
//  (at your option) any later version.
8
//
9
//  This program is distributed in the hope that it will be useful,
10
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
//  GNU General Public License for more details.
13
//
14
//  You should have received a copy of the GNU General Public License
15
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

18
#include "util.h"
19
#include "vlog/vlog-node.h"
20
#include "vlog/vlog-number.h"
21
#include "object.h"
22

23
#include <string.h>
24
#include <inttypes.h>
25
#include <stdlib.h>
26

27
static const imask_t has_map[V_LAST_NODE_KIND] = {
28
   // V_MODULE
29
   (I_IDENT | I_PORTS | I_STMTS | I_DECLS | I_IDENT2),
30

31
   // V_PORT_DECL
32
   (I_IDENT | I_SUBKIND | I_IDENT2 | I_REF | I_RANGES | I_TYPE),
33

34
   // V_REF
35
   (I_IDENT | I_REF),
36

37
   // V_ALWAYS
38
   (I_IDENT | I_SUBKIND | I_STMTS),
39

40
   // V_TIMING
41
   (I_VALUE | I_STMTS),
42

43
   // V_NBASSIGN
44
   (I_TARGET | I_VALUE | I_DELAY),
45

46
   // V_EVENT
47
   (I_SUBKIND | I_VALUE),
48

49
   // V_INITIAL
50
   (I_IDENT | I_STMTS),
51

52
   // V_SEQ_BLOCK
53
   (I_IDENT | I_STMTS),
54

55
   // V_SYS_TCALL
56
   (I_IDENT | I_PARAMS),
57

58
   // V_STRING
59
   (I_TEXT),
60

61
   // V_NUMBER
62
   (I_NUMBER),
63

64
   // V_NET_DECL
65
   (I_IDENT | I_SUBKIND | I_TYPE | I_RANGES | I_VALUE),
66

67
   // V_ASSIGN
68
   (I_TARGET | I_VALUE | I_IDENT | I_DELAY),
69

70
   // V_DIMENSION
71
   (I_SUBKIND | I_LEFT | I_RIGHT),
72

73
   // V_IF
74
   (I_CONDS),
75

76
   // V_COND
77
   (I_VALUE | I_STMTS),
78

79
   // V_VAR_DECL
80
   (I_IDENT | I_TYPE | I_RANGES | I_VALUE),
81

82
   // V_DELAY_CONTROL
83
   (I_VALUE),
84

85
   // V_BINARY
86
   (I_LEFT | I_RIGHT | I_SUBKIND),
87

88
   // V_BASSIGN
89
   (I_TARGET | I_VALUE | I_SUBKIND | I_DELAY),
90

91
   // V_UNARY
92
   (I_VALUE | I_SUBKIND),
93

94
   // V_GATE_INST
95
   (I_SUBKIND | I_PARAMS | I_IDENT | I_REF | I_TARGET),
96

97
   // V_STRENGTH
98
   (I_SUBKIND),
99

100
   // V_MOD_INST
101
   (I_IDENT | I_PARAMS),
102

103
   // V_BIT_SELECT
104
   (I_IDENT | I_REF | I_PARAMS),
105

106
   // V_SYS_FCALL
107
   (I_IDENT | I_PARAMS),
108

109
   // V_FOREVER
110
   (I_STMTS),
111

112
   // V_SPECIFY
113
   (0),
114

115
   // V_PRIMITIVE
116
   (I_IDENT | I_IDENT2 | I_PORTS | I_DECLS | I_STMTS),
117

118
   // V_UDP_TABLE
119
   (I_IDENT | I_PARAMS | I_SUBKIND | I_STMTS),
120

121
   // V_UDP_ENTRY
122
   (I_TEXT),
123

124
   // V_DATA_TYPE
125
   (I_SUBKIND | I_RANGES),
126

127
   // V_TYPE_DECL
128
   (I_IDENT | I_TYPE),
129

130
   // V_ENUM_DECL
131
   (I_IDENT | I_TYPE | I_RANGES | I_DECLS),
132

133
   // V_ENUM_NAME
134
   (I_IDENT | I_TYPE),
135

136
   // V_UNION_DECL
137
   (I_IDENT | I_DECLS),
138

139
   // V_STRUCT_DECL
140
   (I_IDENT | I_DECLS),
141

142
   // V_EVENT_CONTROL
143
   (I_PARAMS),
144

145
   // V_EMPTY
146
   (0),
147

148
   // V_REPEAT
149
   (I_VALUE | I_STMTS),
150

151
   // V_WHILE
152
   (I_VALUE | I_STMTS),
153

154
   // V_DO_WHILE
155
   (I_VALUE | I_STMTS),
156

157
   // V_TASK_DECL
158
   (I_IDENT | I_STMTS | I_DECLS),
159

160
   // V_FUNC_DECL
161
   (I_IDENT | I_STMTS | I_DECLS | I_TYPE),
162

163
   // V_WAIT
164
   (I_VALUE | I_STMTS),
165

166
   // V_PARAM_DECL
167
   (I_IDENT | I_VALUE | I_TYPE),
168

169
   // V_COND_EXPR
170
   (I_VALUE | I_LEFT | I_RIGHT),
171

172
   // V_REAL
173
   (I_DVAL),
174

175
   // V_CONCAT
176
   (I_PARAMS | I_VALUE),
177

178
   // V_FOR_LOOP
179
   (I_LEFT | I_VALUE | I_RIGHT | I_STMTS),
180

181
   // V_FOR_INIT
182
   (I_DECLS | I_STMTS),
183

184
   // V_FOR_STEP
185
   (I_STMTS),
186

187
   // V_PREFIX
188
   (I_TARGET | I_SUBKIND),
189

190
   // V_POSTFIX
191
   (I_TARGET | I_SUBKIND),
192

193
   // V_LOCALPARAM
194
   (I_IDENT | I_VALUE | I_TYPE),
195

196
   // V_CASE
197
   (I_SUBKIND | I_VALUE | I_STMTS),
198

199
   // V_CASE_ITEM
200
   (I_PARAMS | I_STMTS),
201

202
   // V_INST_LIST
203
   (I_PARAMS | I_STMTS | I_IDENT),
204

205
   // V_PARAM_ASSIGN
206
   (I_IDENT | I_VALUE),
207

208
   // V_INST_BODY
209
   (I_IDENT | I_IDENT2 | I_PORTS | I_STMTS | I_DECLS),
210
};
211

212
static const char *kind_text_map[V_LAST_NODE_KIND] = {
213
   "V_MODULE",     "V_PORT_DECL",   "V_REF",           "V_ALWAYS",
214
   "V_TIMING",     "V_NBASSIGN",    "V_EVENT",         "V_INITIAL",
215
   "V_SEQ_BLOCK",  "V_SYS_TCALL",   "V_STRING",        "V_NUMBER",
216
   "V_NET_DECL",   "V_ASSIGN",      "V_DIMENSION",     "V_IF",
217
   "V_COND",       "V_VAR_DECL",    "V_DELAY_CONTROL", "V_BINARY",
218
   "V_BASSIGN",    "V_UNARY",       "V_GATE_INST",     "V_STRENGTH",
219
   "V_MOD_INST",   "V_BIT_SELECT",  "V_SYS_FCALL",     "V_FOREVER",
220
   "V_SPECIFY",    "V_PRIMITIVE",   "V_UDP_TABLE",     "V_UDP_ENTRY",
221
   "V_DATA_TYPE",  "V_TYPE_DECL",   "V_ENUM_DECL",     "V_ENUM_NAME",
222
   "V_UNION_DECL", "V_STRUCT_DECL", "V_EVENT_CONTROL", "V_EMPTY",
223
   "V_REPEAT",     "V_WHILE",       "V_DO_WHILE",      "V_TASK_DECL",
224
   "V_FUNC_DECL",  "V_WAIT",        "V_PARAM_DECL",    "V_COND_EXPR",
225
   "V_REAL",       "V_CONCAT",      "V_FOR_LOOP",      "V_FOR_INIT",
226
   "V_FOR_STEP",   "V_PREFIX",      "V_POSTFIX",       "V_LOCALPARAM",
227
   "V_CASE",       "V_CASE_ITEM",   "V_INST_LIST",     "V_PARAM_ASSIGN",
228
   "V_INST_BODY",
229
};
230

231
static const change_allowed_t change_allowed[] = {
232
   { -1, -1 }
233
};
234

235
object_class_t vlog_object = {
236
   .name           = "vlog",
237
   .change_allowed = change_allowed,
238
   .has_map        = has_map,
239
   .kind_text_map  = kind_text_map,
240
   .tag            = OBJECT_TAG_VLOG,
241
   .last_kind      = V_LAST_NODE_KIND,
242
   .has_loc        = true,
243
   .gc_roots       = { V_MODULE, V_PRIMITIVE },
244
   .gc_num_roots   = 2
245
};
246

247
struct _vlog_node {
248
   object_t object;
249
};
250

251
static inline vlog_node_t vlog_array_nth(item_t *item, unsigned n)
12,382✔
252
{
253
   object_t *o = obj_array_nth(item->obj_array, n);
12,382✔
254
   return container_of(o, struct _vlog_node, object);
12,382✔
255
}
256

257
static inline void vlog_array_add(item_t *item, vlog_node_t v)
5,866✔
258
{
259
   obj_array_add(&(item->obj_array), &(v->object));
5,866✔
260
}
5,866✔
261

262
vlog_node_t vlog_new(vlog_kind_t kind)
8,737✔
263
{
264
   object_t *o = object_new(NULL, &vlog_object, kind);
8,737✔
265
   return container_of(o, struct _vlog_node, object);
8,737✔
266
}
267

268
vlog_kind_t vlog_kind(vlog_node_t v)
50,085✔
269
{
270
   return v->object.kind;
50,085✔
271
}
272

UNCOV
273
const char *vlog_kind_str(vlog_kind_t kind)
×
274
{
UNCOV
275
   return kind_text_map[kind];
×
276
}
277

278
ident_t vlog_ident(vlog_node_t v)
6,707✔
279
{
280
   item_t *item = lookup_item(&vlog_object, v, I_IDENT);
6,707✔
281
   assert(item->ident != NULL);
6,707✔
282
   return item->ident;
6,707✔
283
}
284

285
void vlog_set_ident(vlog_node_t v, ident_t i)
4,094✔
286
{
287
   lookup_item(&vlog_object, v, I_IDENT)->ident = i;
4,094✔
288
}
4,094✔
289

290
bool vlog_has_ident(vlog_node_t v)
52✔
291
{
292
   return lookup_item(&vlog_object, v, I_IDENT)->ident != NULL;
52✔
293
}
294

295
ident_t vlog_ident2(vlog_node_t v)
450✔
296
{
297
   item_t *item = lookup_item(&vlog_object, v, I_IDENT2);
450✔
298
   assert(item->ident != NULL);
450✔
299
   return item->ident;
450✔
300
}
301

302
void vlog_set_ident2(vlog_node_t v, ident_t i)
521✔
303
{
304
   lookup_item(&vlog_object, v, I_IDENT2)->ident = i;
521✔
305
}
521✔
306

307
const loc_t *vlog_loc(vlog_node_t v)
6,254✔
308
{
309
   assert(v != NULL);
6,254✔
310
   return &(v->object.loc);
6,254✔
311
}
312

313
void vlog_set_loc(vlog_node_t v, const loc_t *loc)
9,241✔
314
{
315
   assert(v != NULL);
9,241✔
316
   assert(loc != NULL);
9,241✔
317
   v->object.loc = *loc;
9,241✔
318
}
9,241✔
319

320
vlog_node_t vlog_ref(vlog_node_t v)
5,513✔
321
{
322
   item_t *item = lookup_item(&vlog_object, v, I_REF);
5,513✔
323
   assert(item->object != NULL);
5,513✔
324
   return container_of(item->object, struct _vlog_node, object);
5,513✔
325
}
326

327
bool vlog_has_ref(vlog_node_t v)
1,501✔
328
{
329
   return lookup_item(&vlog_object, v, I_REF)->object != NULL;
1,501✔
330
}
331

332
void vlog_set_ref(vlog_node_t v, vlog_node_t d)
1,837✔
333
{
334
   lookup_item(&vlog_object, v, I_REF)->object = &(d->object);
1,837✔
335
   object_write_barrier(&(v->object), &(d->object));
1,837✔
336
}
1,837✔
337

338
unsigned vlog_stmts(vlog_node_t v)
2,581✔
339
{
340
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
2,581✔
341
   return obj_array_count(item->obj_array);
2,581✔
342
}
343

344
vlog_node_t vlog_stmt(vlog_node_t v, unsigned n)
4,954✔
345
{
346
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
4,954✔
347
   return vlog_array_nth(item, n);
4,954✔
348
}
349

350
void vlog_add_stmt(vlog_node_t v, vlog_node_t s)
2,635✔
351
{
352
   assert(s != NULL);
2,635✔
353
   vlog_array_add(lookup_item(&vlog_object, v, I_STMTS), s);
2,635✔
354
   object_write_barrier(&(v->object), &(s->object));
2,635✔
355
}
2,635✔
356

357
unsigned vlog_ports(vlog_node_t v)
619✔
358
{
359
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
619✔
360
   return obj_array_count(item->obj_array);
619✔
361
}
362

363
vlog_node_t vlog_port(vlog_node_t v, unsigned n)
694✔
364
{
365
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
694✔
366
   return vlog_array_nth(item, n);
694✔
367
}
368

369
void vlog_add_port(vlog_node_t v, vlog_node_t p)
361✔
370
{
371
   assert(p != NULL);
361✔
372
   assert(p->object.kind == V_REF);
361✔
373
   vlog_array_add(lookup_item(&vlog_object, v, I_PORTS), p);
361✔
374
   object_write_barrier(&(v->object), &(p->object));
361✔
375
}
361✔
376

377
unsigned vlog_params(vlog_node_t v)
2,327✔
378
{
379
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
2,327✔
380
   return obj_array_count(item->obj_array);
2,327✔
381
}
382

383
vlog_node_t vlog_param(vlog_node_t v, unsigned n)
3,118✔
384
{
385
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
3,118✔
386
   return vlog_array_nth(item, n);
3,118✔
387
}
388

389
void vlog_add_param(vlog_node_t v, vlog_node_t p)
1,254✔
390
{
391
   assert(p != NULL);
1,254✔
392
   vlog_array_add(lookup_item(&vlog_object, v, I_PARAMS), p);
1,254✔
393
   object_write_barrier(&(v->object), &(p->object));
1,254✔
394
}
1,254✔
395

396
unsigned vlog_ranges(vlog_node_t v)
2,445✔
397
{
398
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
2,445✔
399
   return obj_array_count(item->obj_array);
2,445✔
400
}
401

402
vlog_node_t vlog_range(vlog_node_t v, unsigned n)
550✔
403
{
404
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
550✔
405
   return vlog_array_nth(item, n);
550✔
406
}
407

408
void vlog_add_range(vlog_node_t v, vlog_node_t r)
86✔
409
{
410
   assert(r != NULL);
86✔
411
   assert(r->object.kind == V_DIMENSION);
86✔
412
   vlog_array_add(lookup_item(&vlog_object, v, I_RANGES), r);
86✔
413
   object_write_barrier(&(v->object), &(r->object));
86✔
414
}
86✔
415

416
unsigned vlog_decls(vlog_node_t v)
652✔
417
{
418
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
652✔
419
   return obj_array_count(item->obj_array);
652✔
420
}
421

422
vlog_node_t vlog_decl(vlog_node_t v, unsigned n)
2,613✔
423
{
424
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
2,613✔
425
   return vlog_array_nth(item, n);
2,613✔
426
}
427

428
void vlog_add_decl(vlog_node_t v, vlog_node_t d)
1,296✔
429
{
430
   assert(d != NULL);
1,296✔
431
   vlog_array_add(lookup_item(&vlog_object, v, I_DECLS), d);
1,296✔
432
   object_write_barrier(&(v->object), &(d->object));
1,296✔
433
}
1,296✔
434

435
unsigned vlog_conds(vlog_node_t v)
344✔
436
{
437
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
344✔
438
   return obj_array_count(item->obj_array);
344✔
439
}
440

441
vlog_node_t vlog_cond(vlog_node_t v, unsigned n)
453✔
442
{
443
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
453✔
444
   return vlog_array_nth(item, n);
453✔
445
}
446

447
void vlog_add_cond(vlog_node_t v, vlog_node_t c)
234✔
448
{
449
   assert(c != NULL && c->object.kind == V_COND);
234✔
450
   vlog_array_add(lookup_item(&vlog_object, v, I_CONDS), c);
234✔
451
   object_write_barrier(&(v->object), &(c->object));
234✔
452
}
234✔
453

454
unsigned vlog_subkind(vlog_node_t v)
1,503✔
455
{
456
   return lookup_item(&vlog_object, v, I_SUBKIND)->ival;
1,503✔
457
}
458

459
void vlog_set_subkind(vlog_node_t v, unsigned sub)
1,794✔
460
{
461
   lookup_item(&vlog_object, v, I_SUBKIND)->ival = sub;
1,794✔
462
}
1,794✔
463

464
vlog_node_t vlog_value(vlog_node_t v)
3,290✔
465
{
466
   item_t *item = lookup_item(&vlog_object, v, I_VALUE);
3,290✔
467
   assert(item->object != NULL);
3,290✔
468
   return container_of(item->object, struct _vlog_node, object);
3,290✔
469
}
470

471
bool vlog_has_value(vlog_node_t v)
699✔
472
{
473
   return lookup_item(&vlog_object, v, I_VALUE)->object != NULL;
699✔
474
}
475

476
void vlog_set_value(vlog_node_t v, vlog_node_t e)
1,513✔
477
{
478
   lookup_item(&vlog_object, v, I_VALUE)->object = &(e->object);
1,513✔
479
   object_write_barrier(&(v->object), &(e->object));
1,513✔
480
}
1,513✔
481

482
vlog_node_t vlog_target(vlog_node_t v)
1,163✔
483
{
484
   item_t *item = lookup_item(&vlog_object, v, I_TARGET);
1,163✔
485
   assert(item->object != NULL);
1,163✔
486
   return container_of(item->object, struct _vlog_node, object);
1,163✔
487
}
488

489
void vlog_set_target(vlog_node_t v, vlog_node_t e)
540✔
490
{
491
   lookup_item(&vlog_object, v, I_TARGET)->object = &(e->object);
540✔
492
   object_write_barrier(&(v->object), &(e->object));
540✔
493
}
540✔
494

495
vlog_node_t vlog_delay(vlog_node_t v)
98✔
496
{
497
   item_t *item = lookup_item(&vlog_object, v, I_DELAY);
98✔
498
   assert(item->object != NULL);
98✔
499
   return container_of(item->object, struct _vlog_node, object);
98✔
500
}
501

502
bool vlog_has_delay(vlog_node_t v)
792✔
503
{
504
   return lookup_item(&vlog_object, v, I_DELAY)->object != NULL;
792✔
505
}
506

507
void vlog_set_delay(vlog_node_t v, vlog_node_t d)
50✔
508
{
509
   lookup_item(&vlog_object, v, I_DELAY)->object = &(d->object);
50✔
510
   object_write_barrier(&(v->object), &(d->object));
50✔
511
}
50✔
512

513
vlog_node_t vlog_type(vlog_node_t v)
2,561✔
514
{
515
   item_t *item = lookup_item(&vlog_object, v, I_TYPE);
2,561✔
516
   assert(item->object != NULL);
2,561✔
517
   return container_of(item->object, struct _vlog_node, object);
2,561✔
518
}
519

UNCOV
520
bool vlog_has_type(vlog_node_t v)
×
521
{
UNCOV
522
   return lookup_item(&vlog_object, v, I_TYPE)->object != NULL;
×
523
}
524

525
void vlog_set_type(vlog_node_t v, vlog_node_t t)
740✔
526
{
527
   lookup_item(&vlog_object, v, I_TYPE)->object = &(t->object);
740✔
528
   object_write_barrier(&(v->object), &(t->object));
740✔
529
}
740✔
530

531
const char *vlog_text(vlog_node_t v)
744✔
532
{
533
   item_t *item = lookup_item(&vlog_object, v, I_TEXT);
744✔
534
   assert(item->text != NULL);
744✔
535
   return item->text;
744✔
536
}
537

538
void vlog_set_text(vlog_node_t v, const char *text)
546✔
539
{
540
   lookup_item(&vlog_object, v, I_TEXT)->text = xstrdup(text);
546✔
541
}
546✔
542

543
number_t vlog_number(vlog_node_t v)
1,787✔
544
{
545
   return lookup_item(&vlog_object, v, I_NUMBER)->number;
1,787✔
546
}
547

548
void vlog_set_number(vlog_node_t v, number_t n)
1,104✔
549
{
550
   lookup_item(&vlog_object, v, I_NUMBER)->number = n;
1,104✔
551
}
1,104✔
552

553
vlog_node_t vlog_left(vlog_node_t v)
1,124✔
554
{
555
   item_t *item = lookup_item(&vlog_object, v, I_LEFT);
1,124✔
556
   assert(item->object != NULL);
1,124✔
557
   return container_of(item->object, struct _vlog_node, object);
1,124✔
558
}
559

560
void vlog_set_left(vlog_node_t v, vlog_node_t e)
399✔
561
{
562
   lookup_item(&vlog_object, v, I_LEFT)->object = &(e->object);
399✔
563
   object_write_barrier(&(v->object), &(e->object));
399✔
564
}
399✔
565

566
vlog_node_t vlog_right(vlog_node_t v)
1,124✔
567
{
568
   item_t *item = lookup_item(&vlog_object, v, I_RIGHT);
1,124✔
569
   assert(item->object != NULL);
1,124✔
570
   return container_of(item->object, struct _vlog_node, object);
1,124✔
571
}
572

573
void vlog_set_right(vlog_node_t v, vlog_node_t e)
399✔
574
{
575
   lookup_item(&vlog_object, v, I_RIGHT)->object = &(e->object);
399✔
576
   object_write_barrier(&(v->object), &(e->object));
399✔
577
}
399✔
578

579
double vlog_dval(vlog_node_t v)
1✔
580
{
581
   return lookup_item(&vlog_object, v, I_DVAL)->dval;
1✔
582
}
583

584
void vlog_set_dval(vlog_node_t v, double d)
6✔
585
{
586
   lookup_item(&vlog_object, v, I_DVAL)->dval = d;
6✔
587
}
6✔
588

589
void vlog_visit(vlog_node_t v, vlog_visit_fn_t fn, void *context)
252✔
590
{
591
   vlog_visit_only(v, fn, context, V_LAST_NODE_KIND);
252✔
592
}
252✔
593

594
void vlog_visit_only(vlog_node_t v, vlog_visit_fn_t fn, void *context,
252✔
595
                     vlog_kind_t kind)
596
{
597
   assert(v != NULL);
252✔
598

599
   object_visit_ctx_t ctx = {
252✔
600
      .count      = 0,
601
      .postorder  = (object_visit_fn_t)fn,
602
      .preorder   = NULL,
603
      .context    = context,
604
      .kind       = kind,
605
      .tag        = OBJECT_TAG_VLOG,
606
      .generation = object_next_generation(),
252✔
607
      .deep       = false
608
   };
609

610
   object_visit(&(v->object), &ctx);
252✔
611
}
252✔
612

613
vlog_node_t vlog_rewrite(vlog_node_t v, vlog_rewrite_fn_t fn, void *context)
271✔
614
{
615
   object_arena_t *arena = object_arena(&(v->object));
271✔
616
   if (arena_frozen(arena))
271✔
617
      return v;
618

619
   object_rewrite_ctx_t ctx = {
271✔
620
      .generation = object_next_generation(),
271✔
621
      .context    = context,
622
      .arena      = arena,
623
   };
624

625
   ctx.post_fn[OBJECT_TAG_VLOG] = (object_rewrite_post_fn_t)fn;
271✔
626

627
   object_t *result = object_rewrite(&(v->object), &ctx);
271✔
628
   free(ctx.cache);
271✔
629
   return container_of(result, struct _vlog_node, object);
271✔
630
}
631

632
vlog_node_t vlog_copy(vlog_node_t v, vlog_copy_pred_t pred, void *ctx)
138✔
633
{
634
   object_copy_ctx_t *copy LOCAL = xcalloc_flex(sizeof(object_copy_ctx_t),
138✔
635
                                                1, sizeof(object_t *));
636
   copy->generation   = object_next_generation();
138✔
637
   copy->pred_context = ctx;
138✔
638
   copy->nroots       = 1;
138✔
639
   copy->roots[0]     = &(v->object);
138✔
640

641
   copy->should_copy[OBJECT_TAG_VLOG] = (object_copy_pred_t)pred;
138✔
642

643
   object_copy(copy);
138✔
644

645
   return container_of(copy->roots[0], struct _vlog_node, object);
138✔
646
}
647

648
object_t *vlog_to_object(vlog_node_t v)
1,329✔
649
{
650
   return &(v->object);
1,329✔
651
}
652

653
vlog_node_t vlog_from_object(object_t *obj)
5,868✔
654
{
655
   if (obj != NULL && obj->tag == OBJECT_TAG_VLOG)
5,868✔
656
      return container_of(obj, struct _vlog_node, object);
657
   else
658
      return NULL;
5,507✔
659
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc