Coverage Report

Created: 2025-08-28 06:37

/src/hdf5/src/H5Tdbg.c
Line
Count
Source (jump to first uncovered line)
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*-------------------------------------------------------------------------
14
 *
15
 * Created:         H5Tdbg.c
16
 *
17
 * Purpose:         Dump debugging information about a datatype
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#include "H5Tmodule.h" /* This source code file is part of the H5T module */
27
28
/***********/
29
/* Headers */
30
/***********/
31
#include "H5private.h"  /* Generic Functions                        */
32
#include "H5Eprivate.h" /* Error handling                           */
33
#include "H5Tpkg.h"     /* Datatypes                                */
34
35
/****************/
36
/* Local Macros */
37
/****************/
38
39
/******************/
40
/* Local Typedefs */
41
/******************/
42
43
/********************/
44
/* Package Typedefs */
45
/********************/
46
47
/********************/
48
/* Local Prototypes */
49
/********************/
50
51
/*********************/
52
/* Package Variables */
53
/*********************/
54
55
/*****************************/
56
/* Library Private Variables */
57
/*****************************/
58
59
/*******************/
60
/* Local Variables */
61
/*******************/
62
63
/*-------------------------------------------------------------------------
64
 * Function:    H5T__print_path_stats
65
 *
66
 * Purpose:     Print statistics about a conversion path.  Statistics are
67
 *              printed only if all the following conditions are true:
68
 *
69
 *              1. The library was compiled with H5T_DEBUG defined.
70
 *              2. Data type debugging is turned on at run time.
71
 *              3. The path was called at least one time.
72
 *
73
 *              The optional NPRINT argument keeps track of the number of
74
 *              conversions paths for which statistics have been shown. If
75
 *              its value is zero then table headers are printed before the
76
 *              first line of output.
77
 *
78
 * Return:      SUCCEED/FAIL
79
 *
80
 *-------------------------------------------------------------------------
81
 */
82
herr_t
83
H5T__print_path_stats(H5T_path_t H5_ATTR_UNUSED *path, int H5_ATTR_UNUSED *nprint /*in,out*/)
84
183
{
85
183
    FUNC_ENTER_PACKAGE_NOERR
86
87
#ifdef H5T_DEBUG
88
    if (H5DEBUG(T) && path->stats.ncalls > 0) {
89
        hsize_t nbytes;
90
        char    bandwidth[32];
91
        struct {
92
            char *user;
93
            char *system;
94
            char *elapsed;
95
        } timestrs = {H5_timer_get_time_string(path->stats.times.user),
96
                      H5_timer_get_time_string(path->stats.times.system),
97
                      H5_timer_get_time_string(path->stats.times.elapsed)};
98
99
        if (nprint && 0 == (*nprint)++) {
100
            fprintf(H5DEBUG(T), "H5T: type conversion statistics:\n");
101
            fprintf(H5DEBUG(T), "   %-16s %10s %10s %8s %8s %8s %10s\n", "Conversion", "Elmts", "Calls",
102
                    "User", "System", "Elapsed", "Bandwidth");
103
            fprintf(H5DEBUG(T), "   %-16s %10s %10s %8s %8s %8s %10s\n", "----------", "-----", "-----",
104
                    "----", "------", "-------", "---------");
105
        } /* end if */
106
107
        if (path->src && path->dst)
108
            nbytes = MAX(H5T_get_size(path->src), H5T_get_size(path->dst));
109
        else if (path->src)
110
            nbytes = H5T_get_size(path->src);
111
        else if (path->dst)
112
            nbytes = H5T_get_size(path->dst);
113
        else
114
            nbytes = 0;
115
        nbytes *= path->stats.nelmts;
116
        H5_bandwidth(bandwidth, sizeof(bandwidth), (double)nbytes, path->stats.times.elapsed);
117
        fprintf(H5DEBUG(T), "   %-16s %10" PRIdHSIZE " %10u %8s %8s %8s %10s\n", path->name,
118
                path->stats.nelmts, path->stats.ncalls, timestrs.user, timestrs.system, timestrs.elapsed,
119
                bandwidth);
120
        free(timestrs.user);
121
        free(timestrs.system);
122
        free(timestrs.elapsed);
123
    }
124
#endif
125
126
183
    FUNC_LEAVE_NOAPI(SUCCEED)
127
183
} /* end H5T__print_path_stats() */
128
129
/*-------------------------------------------------------------------------
130
 * Function:    H5T_debug
131
 *
132
 * Purpose:     Prints information about a data type.
133
 *
134
 * Return:      SUCCEED/FAIL
135
 *
136
 *-------------------------------------------------------------------------
137
 */
138
herr_t
139
H5T_debug(const H5T_t *dt, FILE *stream)
140
0
{
141
0
    const char *s1 = "";
142
0
    const char *s2 = "";
143
0
    unsigned    i;
144
0
    herr_t      ret_value = SUCCEED; /* Return value */
145
146
0
    FUNC_ENTER_NOAPI_NOINIT
147
148
    /* Check args */
149
0
    assert(dt);
150
0
    assert(stream);
151
152
0
    switch (dt->shared->type) {
153
0
        case H5T_NO_CLASS:
154
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "no class");
155
0
            break;
156
157
0
        case H5T_INTEGER:
158
0
            s1 = "int";
159
0
            break;
160
161
0
        case H5T_FLOAT:
162
0
            s1 = "float";
163
0
            break;
164
165
0
        case H5T_TIME:
166
0
            s1 = "time";
167
0
            break;
168
169
0
        case H5T_STRING:
170
0
            s1 = "str";
171
0
            break;
172
173
0
        case H5T_BITFIELD:
174
0
            s1 = "bits";
175
0
            break;
176
177
0
        case H5T_OPAQUE:
178
0
            s1 = "opaque";
179
0
            break;
180
181
0
        case H5T_COMPOUND:
182
0
            s1 = "struct";
183
0
            break;
184
185
0
        case H5T_REFERENCE:
186
0
            switch (dt->shared->u.atomic.u.r.rtype) {
187
0
                case H5R_OBJECT1:
188
0
                    s1 = "object reference (old)";
189
0
                    break;
190
0
                case H5R_OBJECT2:
191
0
                    s1 = "object reference (new)";
192
0
                    break;
193
0
                case H5R_DATASET_REGION1:
194
0
                    s1 = "region reference (old)";
195
0
                    break;
196
0
                case H5R_DATASET_REGION2:
197
0
                    s1 = "region reference (new)";
198
0
                    break;
199
0
                case H5R_ATTR:
200
0
                    s1 = "attribute reference";
201
0
                    break;
202
0
                case H5R_BADTYPE:
203
0
                case H5R_MAXTYPE:
204
0
                default:
205
0
                    s1 = "invalid reference";
206
0
                    break;
207
0
            }
208
0
            break;
209
210
0
        case H5T_ENUM:
211
0
            s1 = "enum";
212
0
            break;
213
214
0
        case H5T_VLEN:
215
0
            if (H5T_IS_VL_STRING(dt->shared))
216
0
                s1 = "str";
217
0
            else
218
0
                s1 = "vlen";
219
0
            break;
220
221
0
        case H5T_ARRAY:
222
0
            s1 = "array";
223
0
            break;
224
225
0
        case H5T_COMPLEX:
226
0
            s1 = "complex number";
227
0
            break;
228
229
0
        case H5T_NCLASSES:
230
0
        default:
231
0
            s1 = "";
232
0
            break;
233
0
    } /* end switch */
234
235
0
    switch (dt->shared->state) {
236
0
        case H5T_STATE_TRANSIENT:
237
0
            s2 = "[transient]";
238
0
            break;
239
240
0
        case H5T_STATE_RDONLY:
241
0
            s2 = "[constant]";
242
0
            break;
243
244
0
        case H5T_STATE_IMMUTABLE:
245
0
            s2 = "[predefined]";
246
0
            break;
247
248
0
        case H5T_STATE_NAMED:
249
0
            s2 = "[named,closed]";
250
0
            break;
251
252
0
        case H5T_STATE_OPEN:
253
0
            s2 = "[named,open]";
254
0
            break;
255
0
        default:
256
0
            assert(0 && "This Should never be executed!");
257
0
    } /* end switch */
258
259
0
    fprintf(stream, "%s%s {nbytes=%lu", s1, s2, (unsigned long)(dt->shared->size));
260
261
0
    if (H5T_IS_ATOMIC(dt->shared)) {
262
0
        uint64_t tmp;
263
264
0
        switch (dt->shared->u.atomic.order) {
265
0
            case H5T_ORDER_ERROR:
266
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "order error");
267
0
                break;
268
269
0
            case H5T_ORDER_BE:
270
0
                s1 = "BE";
271
0
                break;
272
273
0
            case H5T_ORDER_LE:
274
0
                s1 = "LE";
275
0
                break;
276
277
0
            case H5T_ORDER_VAX:
278
0
                s1 = "VAX";
279
0
                break;
280
281
0
            case H5T_ORDER_NONE:
282
0
                s1 = "NONE";
283
0
                break;
284
285
0
            case H5T_ORDER_MIXED:
286
0
            default:
287
0
                s1 = "order?";
288
0
                break;
289
0
        } /* end switch */
290
291
0
        fprintf(stream, ", %s", s1);
292
293
0
        if (dt->shared->u.atomic.offset)
294
0
            fprintf(stream, ", offset=%lu", (unsigned long)(dt->shared->u.atomic.offset));
295
0
        if (dt->shared->u.atomic.prec != 8 * dt->shared->size)
296
0
            fprintf(stream, ", prec=%lu", (unsigned long)(dt->shared->u.atomic.prec));
297
298
0
        switch (dt->shared->type) {
299
0
            case H5T_NO_CLASS:
300
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "no class");
301
0
                break;
302
303
0
            case H5T_INTEGER:
304
0
                switch (dt->shared->u.atomic.u.i.sign) {
305
0
                    case H5T_SGN_ERROR:
306
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "sign error");
307
0
                        break;
308
309
0
                    case H5T_SGN_NONE:
310
0
                        s1 = "unsigned";
311
0
                        break;
312
313
0
                    case H5T_SGN_2:
314
0
                        s1 = NULL;
315
0
                        break;
316
317
0
                    case H5T_NSGN:
318
0
                    default:
319
0
                        s1 = "sign?";
320
0
                        break;
321
322
0
                } /* end switch */
323
0
                if (s1)
324
0
                    fprintf(stream, ", %s", s1);
325
0
                break;
326
327
0
            case H5T_FLOAT:
328
0
                switch (dt->shared->u.atomic.u.f.norm) {
329
0
                    case H5T_NORM_ERROR:
330
0
                        HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "norm error");
331
0
                        break;
332
333
0
                    case H5T_NORM_IMPLIED:
334
0
                        s1 = "implied";
335
0
                        break;
336
337
0
                    case H5T_NORM_MSBSET:
338
0
                        s1 = "msbset";
339
0
                        break;
340
341
0
                    case H5T_NORM_NONE:
342
0
                        s1 = "no-norm";
343
0
                        break;
344
345
0
                    default:
346
0
                        s1 = "norm?";
347
0
                        break;
348
0
                } /* end switch */
349
350
0
                fprintf(stream, ", sign=%lu+1", (unsigned long)(dt->shared->u.atomic.u.f.sign));
351
0
                fprintf(stream, ", mant=%lu+%lu (%s)", (unsigned long)(dt->shared->u.atomic.u.f.mpos),
352
0
                        (unsigned long)(dt->shared->u.atomic.u.f.msize), s1);
353
0
                fprintf(stream, ", exp=%lu+%lu", (unsigned long)(dt->shared->u.atomic.u.f.epos),
354
0
                        (unsigned long)(dt->shared->u.atomic.u.f.esize));
355
0
                tmp = dt->shared->u.atomic.u.f.ebias >> 32;
356
0
                if (tmp) {
357
0
                    size_t hi = (size_t)tmp;
358
0
                    size_t lo = (size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
359
0
                    fprintf(stream, " bias=0x%08lx%08lx", (unsigned long)hi, (unsigned long)lo);
360
0
                }
361
0
                else {
362
0
                    size_t lo = (size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
363
0
                    fprintf(stream, " bias=0x%08lx", (unsigned long)lo);
364
0
                }
365
0
                break;
366
367
0
            case H5T_TIME:
368
0
            case H5T_STRING:
369
0
            case H5T_BITFIELD:
370
0
            case H5T_OPAQUE:
371
0
            case H5T_COMPOUND:
372
0
            case H5T_REFERENCE:
373
0
            case H5T_ENUM:
374
0
            case H5T_VLEN:
375
0
            case H5T_ARRAY:
376
0
            case H5T_COMPLEX:
377
0
            case H5T_NCLASSES:
378
0
            default:
379
                /* No additional info */
380
0
                break;
381
0
        } /* end switch */
382
0
    }
383
0
    else if (H5T_COMPOUND == dt->shared->type) {
384
        /* Compound data type */
385
0
        for (i = 0; i < dt->shared->u.compnd.nmembs; i++) {
386
0
            fprintf(stream, "\n\"%s\" @%lu", dt->shared->u.compnd.memb[i].name,
387
0
                    (unsigned long)(dt->shared->u.compnd.memb[i].offset));
388
0
            fprintf(stream, " ");
389
0
            H5T_debug(dt->shared->u.compnd.memb[i].type, stream);
390
0
        } /* end for */
391
0
        fprintf(stream, "\n");
392
0
    }
393
0
    else if (H5T_VLEN == dt->shared->type) {
394
0
        switch (dt->shared->u.vlen.loc) {
395
0
            case H5T_LOC_BADLOC:
396
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid datatype location");
397
0
                break;
398
399
0
            case H5T_LOC_MEMORY:
400
0
                fprintf(stream, ", loc=memory");
401
0
                break;
402
403
0
            case H5T_LOC_DISK:
404
0
                fprintf(stream, ", loc=disk");
405
0
                break;
406
407
0
            case H5T_LOC_MAXLOC:
408
0
            default:
409
0
                fprintf(stream, ", loc=UNKNOWN");
410
0
                break;
411
0
        } /* end switch */
412
413
0
        if (H5T_IS_VL_STRING(dt->shared))
414
            /* Variable length string datatype */
415
0
            fprintf(stream, ", variable-length");
416
0
        else {
417
            /* Variable length sequence datatype */
418
0
            fprintf(stream, " VLEN ");
419
0
            H5T_debug(dt->shared->parent, stream);
420
0
            fprintf(stream, "\n");
421
0
        } /* end else */
422
0
    }
423
0
    else if (H5T_ENUM == dt->shared->type) {
424
0
        size_t base_size;
425
426
        /* Enumeration data type */
427
0
        fprintf(stream, " ");
428
0
        H5T_debug(dt->shared->parent, stream);
429
0
        base_size = dt->shared->parent->shared->size;
430
0
        for (i = 0; i < dt->shared->u.enumer.nmembs; i++) {
431
0
            size_t k;
432
433
0
            fprintf(stream, "\n\"%s\" = 0x", dt->shared->u.enumer.name[i]);
434
0
            for (k = 0; k < base_size; k++)
435
0
                fprintf(stream, "%02" PRIx8, *((uint8_t *)dt->shared->u.enumer.value + (i * base_size) + k));
436
0
        } /* end for */
437
0
        fprintf(stream, "\n");
438
0
    }
439
0
    else if (H5T_OPAQUE == dt->shared->type) {
440
0
        fprintf(stream, ", tag=\"%s\"", dt->shared->u.opaque.tag);
441
0
    }
442
0
    else if (H5T_COMPLEX == dt->shared->type) {
443
0
        fprintf(stream, ", homogeneous");
444
0
        switch (dt->shared->u.cplx.form) {
445
0
            case H5T_COMPLEX_RECTANGULAR:
446
0
                fprintf(stream, ", rectangular form");
447
0
                break;
448
0
            case H5T_COMPLEX_POLAR:
449
0
                fprintf(stream, ", polar form");
450
0
                break;
451
0
            case H5T_COMPLEX_EXPONENTIAL:
452
0
                fprintf(stream, ", exponential form");
453
0
                break;
454
0
            default:
455
0
                fprintf(stream, ", invalid form");
456
0
                break;
457
0
        }
458
0
    }
459
0
    else {
460
        /* Unknown */
461
0
        fprintf(stream, "unknown class %d\n", (int)(dt->shared->type));
462
0
    }
463
0
    fprintf(stream, "}");
464
465
0
done:
466
0
    FUNC_LEAVE_NOAPI(ret_value)
467
0
} /* end H5T_debug() */