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

tbeu / matio / #1024

10 Apr 2026 06:26PM UTC coverage: 73.391% (-0.05%) from 73.44%
#1024

push

travis-ci

tbeu
Add support for MCOS

178 of 2125 new or added lines in 7 files covered. (8.38%)

1191 existing lines in 6 files now uncovered.

11355 of 15472 relevant lines covered (73.39%)

52260.04 hits per line

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

89.45
/src/matvar_struct.c
1
/*
2
 * Copyright (c) 2015-2026, The matio contributors
3
 * Copyright (c) 2012-2014, Christopher C. Hulbert
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are met:
8
 *
9
 * 1. Redistributions of source code must retain the above copyright notice, this
10
 *    list of conditions and the following disclaimer.
11
 *
12
 * 2. Redistributions in binary form must reproduce the above copyright notice,
13
 *    this list of conditions and the following disclaimer in the documentation
14
 *    and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27

28
#include "matio_private.h"
29
#include <stdlib.h>
30
#include <string.h>
31
#if defined(_MSC_VER) || defined(__MINGW32__)
32
#define strdup _strdup
33
#endif
34

35
static matvar_t *
36
VarCreateStruct(const char *name, int rank, const size_t *dims, const char *const *fields,
26✔
37
                unsigned nfields)
38
{
39
    size_t nelems = 1;
26✔
40
    int j;
26✔
41
    matvar_t *matvar;
26✔
42

43
    if ( NULL == dims )
26✔
44
        return NULL;
45

46
    matvar = Mat_VarCalloc();
26✔
47
    if ( NULL == matvar )
26✔
48
        return NULL;
49

50
    matvar->compression = MAT_COMPRESSION_NONE;
26✔
51
    if ( NULL != name )
26✔
52
        matvar->name = strdup(name);
26✔
53
    matvar->rank = rank;
26✔
54
    matvar->dims = (size_t *)malloc(matvar->rank * sizeof(*matvar->dims));
26✔
55
    for ( j = 0; j < matvar->rank; j++ ) {
80✔
56
        matvar->dims[j] = dims[j];
54✔
57
        nelems *= dims[j];
54✔
58
    }
59
    matvar->class_type = MAT_C_STRUCT;
26✔
60
    matvar->data_type = MAT_T_STRUCT;
26✔
61

62
    matvar->data_size = sizeof(matvar_t *);
26✔
63

64
    if ( nfields ) {
26✔
65
        matvar->internal->num_fields = nfields;
23✔
66
        matvar->internal->fieldnames =
23✔
67
            (char **)malloc(nfields * sizeof(*matvar->internal->fieldnames));
23✔
68
        if ( NULL == matvar->internal->fieldnames ) {
23✔
69
            Mat_VarFree(matvar);
×
70
            matvar = NULL;
×
71
        } else {
72
            size_t i;
73
            for ( i = 0; i < nfields; i++ ) {
84✔
74
                if ( NULL == fields[i] ) {
61✔
75
                    Mat_VarFree(matvar);
×
76
                    matvar = NULL;
×
77
                    break;
×
78
                } else {
79
                    matvar->internal->fieldnames[i] = strdup(fields[i]);
61✔
80
                }
81
            }
82
        }
83
        if ( NULL != matvar && nelems > 0 ) {
23✔
84
            size_t nelems_x_nfields;
22✔
85
            int err = Mul(&nelems_x_nfields, nelems, nfields);
22✔
86
            err |= Mul(&matvar->nbytes, nelems_x_nfields, matvar->data_size);
22✔
87
            if ( err ) {
22✔
88
                Mat_VarFree(matvar);
×
89
                return NULL;
×
90
            }
91
            matvar->data = calloc(nelems_x_nfields, matvar->data_size);
22✔
92
        }
93
    }
94

95
    return matvar;
96
}
97

98
/** @brief Creates a structure MATLAB variable with the given name and fields
99
 *
100
 * @ingroup MAT
101
 * @param name Name of the structure variable to create
102
 * @param rank Rank of the variable
103
 * @param dims array of dimensions of the variable of size rank
104
 * @param fields Array of @c nfields fieldnames
105
 * @param nfields Number of fields in the structure
106
 * @return Pointer to the new structure MATLAB variable on success, NULL on error
107
 */
108
matvar_t *
109
Mat_VarCreateStruct(const char *name, int rank, const size_t *dims, const char *const *fields,
×
110
                    unsigned nfields)
111
{
112
    return VarCreateStruct(name, rank, dims, fields, nfields);
×
113
}
114

115
/** @brief Creates a structure MATLAB variable with the given name and fields
116
 *
117
 * @ingroup MAT
118
 * @param name Name of the structure variable to create
119
 * @param rank Rank of the variable
120
 * @param dims array of dimensions of the variable of size rank
121
 * @param fields NULL-terminated array of fieldnames
122
 * @return Pointer to the new structure MATLAB variable on success, NULL on error
123
 */
124
matvar_t *
125
Mat_VarCreateStruct2(const char *name, int rank, const size_t *dims, const char *const *fields)
26✔
126
{
127
    unsigned count = 0;
26✔
128
    if ( NULL == fields )
26✔
129
        return VarCreateStruct(name, rank, dims, fields, count);
3✔
130

131
    while ( fields[count] ) {
84✔
132
        count++;
61✔
133
    }
134
    return VarCreateStruct(name, rank, dims, fields, count);
23✔
135
}
136

137
/** @brief Adds a field to a structure
138
 *
139
 * Adds the given field to the structure. fields should be an array of matvar_t
140
 * pointers of the same size as the structure (i.e. 1 field per structure
141
 * element).
142
 * @ingroup MAT
143
 * @param matvar Pointer to the Structure MAT variable
144
 * @param fieldname Name of field to be added
145
 * @retval 0 on success
146
 * @deprecated Use Mat_VarAddStructField2 instead.
147
 */
148
int
149
Mat_VarAddStructField(matvar_t *matvar, const char *fieldname)
2✔
150
{
151
    int err;
2✔
152
    int cnt = 0;
2✔
153
    size_t i, nfields, nelems = 1;
2✔
154
    matvar_t **new_data, **old_data;
2✔
155
    char **fieldnames;
2✔
156

157
    if ( matvar == NULL || fieldname == NULL )
2✔
158
        return -1;
159

160
    err = Mat_MulDims(matvar, &nelems);
2✔
161
    if ( err )
2✔
162
        return -1;
163

164
    nfields = matvar->internal->num_fields + 1;
2✔
165
    fieldnames = (char **)realloc(matvar->internal->fieldnames,
2✔
166
                                  nfields * sizeof(*matvar->internal->fieldnames));
167
    if ( NULL == fieldnames )
2✔
168
        return -1;
169
    matvar->internal->num_fields = nfields;
2✔
170
    matvar->internal->fieldnames = fieldnames;
2✔
171
    matvar->internal->fieldnames[nfields - 1] = strdup(fieldname);
2✔
172

173
    {
174
        size_t nelems_x_nfields;
2✔
175
        err = Mul(&nelems_x_nfields, nelems, nfields);
2✔
176
        err |= Mul(&matvar->nbytes, nelems_x_nfields, sizeof(*new_data));
2✔
177
        if ( err ) {
2✔
178
            matvar->nbytes = 0;
×
179
            return -1;
×
180
        }
181
    }
182
    new_data = (matvar_t **)malloc(matvar->nbytes);
2✔
183
    if ( new_data == NULL ) {
2✔
184
        matvar->nbytes = 0;
×
185
        return -1;
×
186
    }
187

188
    old_data = (matvar_t **)matvar->data;
2✔
189
    for ( i = 0; i < nelems; i++ ) {
6✔
190
        size_t f;
191
        for ( f = 0; f < nfields - 1; f++ )
6✔
192
            new_data[cnt++] = old_data[i * (nfields - 1) + f];
2✔
193
        new_data[cnt++] = NULL;
4✔
194
    }
195

196
    free(matvar->data);
2✔
197
    matvar->data = new_data;
2✔
198

199
    return 0;
2✔
200
}
201

202
/** @brief Returns the number of fields in a structure variable
203
 *
204
 * Returns the number of fields in the given structure.
205
 * @ingroup MAT
206
 * @param matvar Structure matlab variable
207
 * @returns Number of fields
208
 */
209
unsigned
210
Mat_VarGetNumberOfFields(const matvar_t *matvar)
6✔
211
{
212
    int nfields;
6✔
213
    if ( matvar == NULL ||
6✔
214
         (matvar->class_type != MAT_C_STRUCT && matvar->class_type != MAT_C_OBJECT) ||
5✔
215
         NULL == matvar->internal ) {
5✔
216
        nfields = 0;
217
    } else {
218
        nfields = matvar->internal->num_fields;
5✔
219
    }
220
    return nfields;
6✔
221
}
222

223
/** @brief Returns the fieldnames of a structure variable
224
 *
225
 * Returns the fieldnames for the given structure. The returned pointers are
226
 * internal to the structure and should not be free'd.
227
 * @ingroup MAT
228
 * @param matvar Structure matlab variable
229
 * @returns Array of fieldnames
230
 */
231
char *const *
232
Mat_VarGetStructFieldnames(const matvar_t *matvar)
3✔
233
{
234
    if ( matvar == NULL ||
3✔
235
         (matvar->class_type != MAT_C_STRUCT && matvar->class_type != MAT_C_OBJECT) ||
2✔
236
         NULL == matvar->internal ) {
2✔
237
        return NULL;
238
    } else {
239
        return matvar->internal->fieldnames;
2✔
240
    }
241
}
242

243
/** @brief Finds a field of a structure by the field's index
244
 *
245
 * Returns a pointer to the structure field at the given 0-relative index.
246
 * @ingroup MAT
247
 * @param matvar Pointer to the Structure MAT variable
248
 * @param field_index 0-relative index of the field.
249
 * @param index linear index of the structure array
250
 * @return Pointer to the structure field on success, NULL on error
251
 */
252
matvar_t *
253
Mat_VarGetStructFieldByIndex(const matvar_t *matvar, size_t field_index, size_t index)
800✔
254
{
255
    int err;
800✔
256
    matvar_t *field = NULL;
800✔
257
    size_t nelems = 1, nfields;
800✔
258

259
    if ( matvar == NULL || matvar->data == NULL ||
800✔
260
         (matvar->class_type != MAT_C_STRUCT && matvar->class_type != MAT_C_OBJECT) ||
800✔
261
         matvar->data_size == 0 )
800✔
262
        return NULL;
263

264
    err = Mat_MulDims(matvar, &nelems);
800✔
265
    if ( err )
800✔
266
        return NULL;
267

268
    nfields = matvar->internal->num_fields;
800✔
269

270
    if ( nelems > 0 && index >= nelems ) {
800✔
UNCOV
271
        Mat_Critical("Mat_VarGetStructField: structure index out of bounds");
×
272
    } else if ( nfields > 0 ) {
800✔
273
        if ( field_index > nfields ) {
800✔
UNCOV
274
            Mat_Critical("Mat_VarGetStructField: field index out of bounds");
×
275
        } else {
276
            field = *((matvar_t **)matvar->data + index * nfields + field_index);
800✔
277
        }
278
    }
279

280
    return field;
281
}
282

283
/** @brief Finds a field of a structure by the field's name
284
 *
285
 * Returns a pointer to the structure field at the given 0-relative index.
286
 * @ingroup MAT
287
 * @param matvar Pointer to the Structure MAT variable
288
 * @param field_name Name of the structure field
289
 * @param index linear index of the structure array
290
 * @return Pointer to the structure field on success, NULL on error
291
 */
292
matvar_t *
293
Mat_VarGetStructFieldByName(const matvar_t *matvar, const char *field_name, size_t index)
301✔
294
{
295
    int i, nfields, field_index, err;
301✔
296
    matvar_t *field = NULL;
301✔
297
    size_t nelems = 1;
301✔
298

299
    if ( matvar == NULL || matvar->data == NULL ||
301✔
300
         (matvar->class_type != MAT_C_STRUCT && matvar->class_type != MAT_C_OBJECT) ||
301✔
301
         matvar->data_size == 0 )
301✔
302
        return NULL;
303

304
    err = Mat_MulDims(matvar, &nelems);
301✔
305
    if ( err )
301✔
306
        return NULL;
307

308
    nfields = matvar->internal->num_fields;
301✔
309
    field_index = -1;
301✔
310
    for ( i = 0; i < nfields; i++ ) {
615✔
311
        if ( !strcmp(matvar->internal->fieldnames[i], field_name) ) {
615✔
312
            field_index = i;
313
            break;
314
        }
315
    }
316

317
    if ( index >= nelems ) {
301✔
UNCOV
318
        Mat_Critical("Mat_VarGetStructField: structure index out of bounds");
×
319
    } else if ( field_index >= 0 ) {
301✔
320
        field = *((matvar_t **)matvar->data + index * nfields + field_index);
301✔
321
    }
322

323
    return field;
324
}
325

326
/** @brief Finds a field of a structure
327
 *
328
 * Returns a pointer to the structure field at the given 0-relative index.
329
 * @ingroup MAT
330
 * @param matvar Pointer to the Structure MAT variable
331
 * @param name_or_index Name of the field, or the 1-relative index of the field
332
 * If the index is used, it should be the address of an integer variable whose
333
 * value is the index number.
334
 * @param opt MAT_BY_NAME if the name_or_index is the name or MAT_BY_INDEX if
335
 *            the index was passed.
336
 * @param index linear index of the structure to find the field of
337
 * @return Pointer to the Structure Field on success, NULL on error
338
 */
339
matvar_t *
340
Mat_VarGetStructField(const matvar_t *matvar, void *name_or_index, int opt, int index)
801✔
341
{
342
    int err, nfields;
801✔
343
    matvar_t *field = NULL;
801✔
344
    size_t nelems = 1;
801✔
345

346
    err = Mat_MulDims(matvar, &nelems);
801✔
347
    nfields = matvar->internal->num_fields;
801✔
348
    if ( index < 0 || (nelems > 0 && (size_t)index >= nelems) )
801✔
349
        err = 1;
350
    else if ( nfields < 1 )
801✔
UNCOV
351
        err = 1;
×
352

353
    if ( !err && (opt == MAT_BY_INDEX) ) {
801✔
354
        size_t field_index = *(int *)name_or_index;
800✔
355
        if ( field_index > 0 )
800✔
356
            field = Mat_VarGetStructFieldByIndex(matvar, field_index - 1, index);
800✔
357
    } else if ( !err && (opt == MAT_BY_NAME) ) {
1✔
358
        field = Mat_VarGetStructFieldByName(matvar, (const char *)name_or_index, index);
1✔
359
    }
360

361
    return field;
801✔
362
}
363

364
/** @brief Indexes a structure
365
 *
366
 * Finds structures of a structure array given a start, stride, and edge for
367
 * each dimension.  The structures are placed in a new structure array.  If
368
 * copy_fields is non-zero, the indexed structures are copied and should be
369
 * freed, but if copy_fields is zero, the indexed structures are pointers to
370
 * the original, but should still be freed. The structures have a flag set
371
 * so that the structure fields are not freed.
372
 *
373
 * Note that this function is limited to structure arrays with a rank less than
374
 * 10.
375
 *
376
 * @ingroup MAT
377
 * @param matvar Structure matlab variable
378
 * @param start vector of length rank with 0-relative starting coordinates for
379
 *              each dimension.
380
 * @param stride vector of length rank with strides for each dimension.
381
 * @param edge vector of length rank with the number of elements to read in
382
 *              each dimension.
383
 * @param copy_fields 1 to copy the fields, 0 to just set pointers to them.
384
 * @returns A new structure array with fields indexed from @c matvar.
385
 */
386
matvar_t *
387
Mat_VarGetStructs(const matvar_t *matvar, const int *start, const int *stride, const int *edge,
1✔
388
                  int copy_fields)
389
{
390
    size_t i, N, I, nfields, field,
1✔
391
        idx[10] =
1✔
392
            {
393
                0,
394
            },
395
        cnt[10] =
1✔
396
            {
397
                0,
398
            },
399
        dimp[10] = {
1✔
400
            0,
401
        };
402
    matvar_t **fields, *struct_slab;
1✔
403
    int j;
1✔
404

405
    if ( matvar == NULL || start == NULL || stride == NULL || edge == NULL ) {
1✔
406
        return NULL;
407
    } else if ( matvar->rank > 9 ) {
1✔
408
        return NULL;
409
    } else if ( matvar->class_type != MAT_C_STRUCT && matvar->class_type != MAT_C_OBJECT ) {
1✔
410
        return NULL;
411
    }
412

413
    struct_slab = Mat_VarDuplicate(matvar, 0);
1✔
414
    if ( !copy_fields )
1✔
415
        struct_slab->mem_conserve = 1;
1✔
416

417
    nfields = matvar->internal->num_fields;
1✔
418

419
    dimp[0] = matvar->dims[0];
1✔
420
    N = edge[0];
1✔
421
    I = start[0];
1✔
422
    struct_slab->dims[0] = edge[0];
1✔
423
    idx[0] = start[0];
1✔
424
    for ( j = 1; j < matvar->rank; j++ ) {
4✔
425
        idx[j] = start[j];
3✔
426
        dimp[j] = dimp[j - 1] * matvar->dims[j];
3✔
427
        N *= edge[j];
3✔
428
        I += start[j] * dimp[j - 1];
3✔
429
        struct_slab->dims[j] = edge[j];
3✔
430
    }
431
    I *= nfields;
1✔
432
    struct_slab->nbytes = N * nfields * sizeof(matvar_t *);
1✔
433
    struct_slab->data = malloc(struct_slab->nbytes);
1✔
434
    if ( struct_slab->data == NULL ) {
1✔
UNCOV
435
        Mat_VarFree(struct_slab);
×
UNCOV
436
        return NULL;
×
437
    }
438
    fields = (matvar_t **)struct_slab->data;
439
    for ( i = 0; i < N; i += edge[0] ) {
13✔
440
        for ( j = 0; j < edge[0]; j++ ) {
24✔
441
            for ( field = 0; field < nfields; field++ ) {
36✔
442
                if ( copy_fields )
24✔
UNCOV
443
                    fields[(i + j) * nfields + field] =
×
UNCOV
444
                        Mat_VarDuplicate(*((matvar_t **)matvar->data + I), 1);
×
445
                else
446
                    fields[(i + j) * nfields + field] = *((matvar_t **)matvar->data + I);
24✔
447
                I++;
24✔
448
            }
449
            I += (stride[0] - 1) * nfields;
12✔
450
        }
451
        idx[0] = start[0];
12✔
452
        I = idx[0];
12✔
453
        cnt[1]++;
12✔
454
        idx[1] += stride[1];
12✔
455
        for ( j = 1; j < matvar->rank; j++ ) {
48✔
456
            if ( cnt[j] == (size_t)edge[j] ) {
36✔
457
                cnt[j] = 0;
9✔
458
                idx[j] = start[j];
9✔
459
                if ( j < matvar->rank - 1 ) {
9✔
460
                    cnt[j + 1]++;
8✔
461
                    idx[j + 1] += stride[j + 1];
8✔
462
                }
463
            }
464
            I += idx[j] * dimp[j - 1];
36✔
465
        }
466
        I *= nfields;
12✔
467
    }
468
    return struct_slab;
469
}
470

471
/** @brief Indexes a structure
472
 *
473
 * Finds structures of a structure array given a single (linear)start, stride,
474
 * and edge.  The structures are placed in a new structure array.  If
475
 * copy_fields is non-zero, the indexed structures are copied and should be
476
 * freed, but if copy_fields is zero, the indexed structures are pointers to
477
 * the original, but should still be freed since the mem_conserve flag is set
478
 * so that the structures are not freed.
479
 * MAT file version must be 5.
480
 * @ingroup MAT
481
 * @param matvar Structure matlab variable
482
 * @param start starting index (0-relative)
483
 * @param stride stride (1 reads consecutive elements)
484
 * @param edge Number of elements to read
485
 * @param copy_fields 1 to copy the fields, 0 to just set pointers to them.
486
 * @returns A new structure with fields indexed from matvar
487
 */
488
matvar_t *
489
Mat_VarGetStructsLinear(const matvar_t *matvar, int start, int stride, int edge, int copy_fields)
3✔
490
{
491
    matvar_t *struct_slab;
3✔
492

493
    if ( matvar == NULL || matvar->rank > 10 ) {
3✔
494
        struct_slab = NULL;
495
    } else {
496
        int i, I, field, nfields;
3✔
497
        matvar_t **fields;
3✔
498

499
        struct_slab = Mat_VarDuplicate(matvar, 0);
3✔
500
        if ( !copy_fields )
3✔
501
            struct_slab->mem_conserve = 1;
3✔
502

503
        nfields = matvar->internal->num_fields;
3✔
504

505
        struct_slab->nbytes = (size_t)edge * nfields * sizeof(matvar_t *);
3✔
506
        struct_slab->data = malloc(struct_slab->nbytes);
3✔
507
        if ( struct_slab->data == NULL ) {
3✔
UNCOV
508
            Mat_VarFree(struct_slab);
×
UNCOV
509
            return NULL;
×
510
        }
511
        struct_slab->dims[0] = edge;
3✔
512
        struct_slab->dims[1] = 1;
3✔
513
        fields = (matvar_t **)struct_slab->data;
3✔
514
        I = start * nfields;
3✔
515
        for ( i = 0; i < edge; i++ ) {
13✔
516
            if ( copy_fields ) {
10✔
UNCOV
517
                for ( field = 0; field < nfields; field++ ) {
×
UNCOV
518
                    fields[i * nfields + field] =
×
UNCOV
519
                        Mat_VarDuplicate(*((matvar_t **)matvar->data + I), 1);
×
UNCOV
520
                    I++;
×
521
                }
522
            } else {
523
                for ( field = 0; field < nfields; field++ ) {
40✔
524
                    fields[i * nfields + field] = *((matvar_t **)matvar->data + I);
30✔
525
                    I++;
30✔
526
                }
527
            }
528
            I += (stride - 1) * nfields;
10✔
529
        }
530
    }
531
    return struct_slab;
532
}
533

534
/** @brief Sets the structure field to the given variable
535
 *
536
 * Sets the structure field specified by the 0-relative field index
537
 * @c field_index for the given 0-relative structure index @c index to
538
 * @c field.
539
 * @ingroup MAT
540
 * @param matvar Pointer to the structure MAT variable
541
 * @param field_index 0-relative index of the field.
542
 * @param index linear index of the structure array
543
 * @param field New field variable
544
 * @return Pointer to the previous field (NULL if no previous field)
545
 */
546
matvar_t *
547
Mat_VarSetStructFieldByIndex(matvar_t *matvar, size_t field_index, size_t index, matvar_t *field)
4✔
548
{
549
    int err;
4✔
550
    matvar_t *old_field = NULL;
4✔
551
    size_t nelems = 1, nfields;
4✔
552

553
    if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || matvar->data == NULL )
4✔
554
        return NULL;
555

556
    err = Mat_MulDims(matvar, &nelems);
4✔
557
    if ( err )
4✔
558
        return NULL;
559

560
    nfields = matvar->internal->num_fields;
4✔
561

562
    if ( index < nelems && field_index < nfields ) {
4✔
563
        matvar_t **fields = (matvar_t **)matvar->data;
4✔
564
        old_field = fields[index * nfields + field_index];
4✔
565
        fields[index * nfields + field_index] = field;
4✔
566
        if ( NULL != field->name ) {
4✔
567
            free(field->name);
4✔
568
        }
569
        field->name = strdup(matvar->internal->fieldnames[field_index]);
4✔
570
    }
571

572
    return old_field;
573
}
574

575
/** @brief Sets the structure field to the given variable
576
 *
577
 * Sets the specified structure fieldname at the given 0-relative @c index to
578
 * @c field.
579
 * @ingroup MAT
580
 * @param matvar Pointer to the Structure MAT variable
581
 * @param field_name Name of the structure field
582
 * @param index linear index of the structure array
583
 * @param field New field variable
584
 * @return Pointer to the previous field (NULL if no previous field)
585
 */
586
matvar_t *
587
Mat_VarSetStructFieldByName(matvar_t *matvar, const char *field_name, size_t index, matvar_t *field)
780✔
588
{
589
    int err, i, nfields, field_index;
780✔
590
    matvar_t *old_field = NULL;
780✔
591
    size_t nelems = 1;
780✔
592

593
    if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || matvar->data == NULL )
780✔
594
        return NULL;
595

596
    err = Mat_MulDims(matvar, &nelems);
780✔
597
    if ( err )
780✔
598
        return NULL;
599

600
    nfields = matvar->internal->num_fields;
780✔
601
    field_index = -1;
780✔
602
    for ( i = 0; i < nfields; i++ ) {
1,184✔
603
        if ( !strcmp(matvar->internal->fieldnames[i], field_name) ) {
1,184✔
604
            field_index = i;
605
            break;
606
        }
607
    }
608

609
    if ( index < nelems && field_index >= 0 ) {
780✔
610
        matvar_t **fields = (matvar_t **)matvar->data;
780✔
611
        old_field = fields[index * nfields + field_index];
780✔
612
        fields[index * nfields + field_index] = field;
780✔
613
        if ( NULL != field->name ) {
780✔
614
            free(field->name);
16✔
615
        }
616
        field->name = strdup(matvar->internal->fieldnames[field_index]);
780✔
617
    }
618

619
    return old_field;
620
}
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