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

nasa / trick / 18506258460

14 Oct 2025 06:25PM UTC coverage: 55.802% (-0.02%) from 55.826%
18506258460

push

github

web-flow
Added an optional alloc_name string parameter to declare_operatornew_var function also a new call in the C interface. (#1973)

0 of 9 new or added lines in 2 files covered. (0.0%)

4 existing lines in 2 files now uncovered.

12358 of 22146 relevant lines covered (55.8%)

255975.98 hits per line

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

51.96
/trick_source/sim_services/MemoryManager/MemoryManager_declare_var.cpp
1
#include <stdlib.h>
2
#include <iostream>
3

4
#include <sstream>
5
#include <dlfcn.h>
6
#include <string.h>
7
#include "trick/MemoryManager.hh"
8
#include "trick/ADefParseContext.hh"
9

10
/**
11
 @page examples_declare_var Examples of declare_var
12

13
 Allocation of an anonymous singleton of type double:
14
 \code double *D = (double*)trick_MM->declare_var("double"); \endcode
15

16
 Allocation of an anonymous array of 3 doubles:
17
 \code double *D = (double*)trick_MM->declare_var("double[3]"); \endcode
18

19
 Allocation of an anonymous array of 3 pointers to double:
20
 \code double **D = (double**)trick_MM->declare_var("double*[3]"); \endcode
21

22
 Allocation of an anonymous 2 dimensional array of doubles:
23
 \code double (*A)[3][4] = (double(*)[3][4])trick_MM->declare_var("double[3][4]"); \endcode
24

25
 Allocation of a named singleton of type double:
26
 \code double *D = (double*)trick_MM->declare_var("double mydbl"); \endcode
27

28
 Allocation of a named array of 3 Pointers to double:
29
 \code double **D = (double**)trick_MM->declare_var("double* mydbl[3]"); \endcode
30

31
 Allocation of a named singleton of user-defined type "BAR":
32
 \code BAR *D = (BAR*)trick_MM->declare_var("BAR mydbl"); \endcode
33

34
 Allocation of a named 2 dimensional array of user-defined type "BAR" in namespace "FOO":
35
 \code FOO::BAR (*A)[3][4] = (FOO::BAR(*)[3][4])trick_MM->declare_var("FOO::BAR my_array[3][4]"); \endcode
36
 */
37

38
// PUBLIC MEMBER FUNCTION: void* Trick::MemoryManager::declare_var(TRICK_TYPE type,std::string user_type_name, int n_stars, std::string var_name, int n_cdims, int *cdims);
39
void* Trick::MemoryManager::declare_var( TRICK_TYPE type,
6,653✔
40
                                        std::string user_type_name,
41
                                        int n_stars,
42
                                        std::string var_name,
43
                                        int n_cdims,
44
                                        int *cdims) {
45
    int size;
46
    char* allocation_name;
47
    int n_elems;
48
    Language language;
49
    TRICK_ALLOC_TYPE allocation_type;
50
    void* address;
51
    ATTRIBUTES* sub_attr;
52
    ALLOC_INFO *new_alloc;
53
    VARIABLE_MAP::iterator variable_pos;
6,653✔
54

55
    if (debug_level > 1) {
6,653✔
56
        std::cout << __FUNCTION__ << ": Parameters: " << std::endl;
×
57
        std::cout << "           type = " << type << std::endl;
×
58
        std::cout << "           user_type_name = " << user_type_name << std::endl;
×
59
        std::cout << "           n_stars = " << n_stars << std::endl;
×
60
        std::cout << "           var_name = " << var_name << std::endl;
×
61
        std::cout << "           n_cdims = " << n_cdims << std::endl;
×
62
    }
63

64
    /** @par Design Details:
65
     This function is implemented using the following algorithm:
66
     */
67

68
    /** @li If this is a named allocation then determine whether the given variable name is already in use. */
69
    if (var_name != "") {
6,653✔
70
        pthread_mutex_lock(&mm_mutex);
4,664✔
71
        variable_pos = variable_map.find( var_name);
4,664✔
72
        if (variable_pos != variable_map.end()) {
4,664✔
73
            std::stringstream message;
×
74
            message << "Variable \""<< var_name <<"\" already declared.\n";
×
75
            emitError(message.str());
×
76
            pthread_mutex_unlock(&mm_mutex);
×
77
            return ((void*)NULL);
×
78
        }
79
        pthread_mutex_unlock(&mm_mutex);
4,664✔
80
        allocation_name = strdup( var_name.c_str());
4,664✔
81
    } else {
82
        allocation_name = NULL;
1,989✔
83
    }
84

85
    /** @li Calculate the number of elements to be allocated. The number of elements is
86
            the product of the sizes of the constrained dimensions. */
87
    n_elems = 1;
6,653✔
88
    for (int ii = 0; ii < n_cdims ; ii++ ) {
12,643✔
89
        n_elems = n_elems * cdims[ii];
5,990✔
90
    }
91
    if (n_elems == 0) {
6,653✔
92
        std::stringstream message;
×
93
        message << "In the following declaration, ";
×
94
        message << "one or more of the constrained dimensions is zero." ;
×
95
        message << std::endl;
×
96

97
        // Print declaration.
98
        message << make_decl_string( type, user_type_name, n_stars, var_name, n_cdims, cdims);
×
99
        emitError(message.str()) ;
×
100
        return ((void*)NULL);
×
101
    }
102

103
    /** @li From the TRICK_TYPE, user_type_name and the number of pointers (asterisks),
104
            determine the size and the attributes of an element. */
105
    if ( get_type_attributes(type, user_type_name, n_stars, sub_attr, size) != 0) {
6,653✔
106
        std::stringstream message;
×
107
        message << "get_type_attributes failed for type: ";
×
108
        message << trickTypeCharString(type, user_type_name.c_str());
×
109
        message << std::endl;
×
110
        emitError(message.str()) ;
×
111

112
        return ((void*)NULL);
×
113
    }
114

115
    /** @li Allocate memory for the variable. */
116
    if ( (type == TRICK_STRUCTURED) &&
6,653✔
117
         (sub_attr->language == Language_CPP) &&
737✔
118
         (n_stars == 0 ) ) {
119

120
        if ((address = io_src_allocate_class( user_type_name.c_str(), n_elems)) == NULL) {
572✔
121
            std::stringstream message;
×
122
            message << "io_src_allocate_class (";
×
123
            message << user_type_name << "," << n_elems ;
×
124
            message << ") failed to allocate any memory.";
×
125
            emitError(message.str()) ;
×
126

127
            return ((void*)NULL);
×
128
        }
129
        language = Language_CPP;
572✔
130
        /* io_src_allocate_class allocates objects using calloc (only).  */
131
        allocation_type = TRICK_ALLOC_MALLOC;
572✔
132

133
    } else if ((type == TRICK_STRING) && (n_stars == 0 ) ) {
6,081✔
134

135
        std::string *s = (std::string*)calloc(n_elems, sizeof(std::string));
3,210✔
136
        for (int ii=0 ; ii<n_elems ; ii++) {
7,096✔
137
            new( &s[ii]) std::string();
3,886✔
138
        }
139
        address = s;
3,210✔
140

141
        if (address == NULL) {
3,210✔
142
            return ((void*)NULL);
×
143
        }
144
        language = Language_CPP;
3,210✔
145
    } else {
146
        if ( (address = calloc( (size_t)n_elems, (size_t)size ) ) == NULL) {
2,871✔
147
            emitError("Out of memory.") ;
×
148
            return ((void*)NULL);
×
149
        }
150
        language = Language_C;
2,871✔
151
    }
152

153
    /** @li Allocate and populate an ALLOC_INFO record for the allocation. */
154
    if ((new_alloc = (ALLOC_INFO*)calloc(1, sizeof(ALLOC_INFO))) != NULL) {
6,653✔
155

156
        new_alloc->start = address;
6,653✔
157
        new_alloc->end = ( (char*)new_alloc->start) + (n_elems * size) - 1;
6,653✔
158
        new_alloc->name = allocation_name;
6,653✔
159
        new_alloc->stcl = TRICK_LOCAL;
6,653✔
160
        new_alloc->size = size;
6,653✔
161
        new_alloc->language = language;
6,653✔
162
        new_alloc->type = type;
6,653✔
163
        new_alloc->alloc_type = allocation_type;
6,653✔
164

165
        if ((type == TRICK_STRUCTURED) || (type == TRICK_ENUMERATED)) {
6,653✔
166
            new_alloc->user_type_name = strdup( user_type_name.c_str());
766✔
167
        } else {
168
            new_alloc->user_type_name = NULL ;
5,887✔
169
        }
170

171
        new_alloc->attr = sub_attr;
6,653✔
172
        new_alloc->num = n_elems;
6,653✔
173

174
        new_alloc->num_index = 0;
6,653✔
175
        for (int ii = 0; ii < n_cdims ; ii++ ) {
12,643✔
176
            new_alloc->index[new_alloc->num_index] = cdims[ii];
5,990✔
177
            new_alloc->num_index ++ ;
5,990✔
178
        }
179
        for (int ii = 0 ; ii < n_stars ; ii++) {
7,185✔
180
            new_alloc->index[new_alloc->num_index] = 0;
532✔
181
            new_alloc->num_index ++ ;
532✔
182
        }
183

184
        new_alloc->id = alloc_info_map_counter++ ;
6,653✔
185

186
        /** @li Insert the <address, ALLOC_INFO> key-value pair into the alloc_info_map.*/
187
        pthread_mutex_lock(&mm_mutex);
6,653✔
188
        alloc_info_map[address] = new_alloc;
6,653✔
189

190
        /** @li If this is a named allocation: then insert the <variable-name, ALLOC_INFO>
191
            key-value pair into the variable map.*/
192
        if (new_alloc->name) {
6,653✔
193
            variable_map[new_alloc->name] = new_alloc;
4,664✔
194
        }
195
        pthread_mutex_unlock(&mm_mutex);
6,653✔
196
    } else {
197
        emitError("Out of memory.\n") ;
×
198
        return ((void*)NULL);
×
199
    }
200

201
    /** @li If debug is enabled, show what happened.*/
202
    if (debug_level) {
6,653✔
203
        int i;
204
        std::cout << std::endl;
×
205
        std::cout << "Allocation: " << new_alloc->num << " element(s) of type(" ;
×
206
        std::cout << trickTypeCharString(type, user_type_name.c_str()) ;
×
207
        for (i=0;i<n_stars;i++) std::cout << "*";
×
208
        std::cout << "), size(" << size << ") @ addr(" << address << ")." ;
×
209
        std::cout << std::endl << std::endl;
×
210
        std::cout.flush();
×
211
    }
212

213
    /** @li Return the address of the allocation. */
214
    return (address);
6,653✔
215
}
216

217
// PUBLIC MEMBER FUNCTION: void* Trick::MemoryManager::declare_var( const char *alloc_definition);
218
void* Trick::MemoryManager::declare_var( const char *alloc_definition) {
3,557✔
219

220
    void* address = NULL;
3,557✔
221

222
    Trick::ADefParseContext* context = NULL;
3,557✔
223
    std::stringstream alloc_decl_sstream;
3,557✔
224

225
    /** @par Design Details:
226
     This function is implemented using the following algorithm:
227
     */
228

229
    alloc_decl_sstream << alloc_definition;
3,557✔
230

231
    /** @li Create a parse context. */
232
    context = new Trick::ADefParseContext( &alloc_decl_sstream);
3,557✔
233

234
    /** @li Call ADEF_parse to parse the allocation definition. */
235
    if (context != NULL) {
3,557✔
236
        if ( ADEF_parse( context) == 0) {
3,557✔
237

238
            /** @li Call the general form of declare_var to perform the allocation. */
239
            address = declare_var( context->type,
3,555✔
240
                                  context->user_type_name,
3,555✔
241
                                  context->n_stars,
242
                                  context->var_name,
3,555✔
243
                                  context->n_cdims,
244
                                  context->cdims);
3,555✔
245

246
            /** @li Delete the parse context. */
247
            delete( context);
3,555✔
248
        } else {
249
            std::stringstream message;
2✔
250
            message << "Invalid declaration (failed to parse): \"" << alloc_definition << "\".";
2✔
251
            emitError(message.str());
2✔
252
        }
253
    }
254
    /** @li Return the address of the allocation. */
255
    return ( address);
7,114✔
256
}
257

258
// PUBLIC MEMBER FUNCTION: void* Trick::MemoryManager::declare_var( const char *element_definition, int n_elems);
259

260
void* Trick::MemoryManager::declare_var( const char *element_definition, int n_elems) {
889✔
261

262
    void* address = NULL;
889✔
263
    int cdims[8];
264
    int n_cdims;
265

266
    Trick::ADefParseContext* context = NULL;
889✔
267
    std::stringstream alloc_decl_sstream;
889✔
268

269
    /** We know that our array will be at least one dimensional and that dimension contains n_elems elements. */
270
    cdims[0] = n_elems;
889✔
271
    n_cdims = 1;
889✔
272

273
    alloc_decl_sstream << element_definition;
889✔
274

275
    /** @li Create a parse context. */
276
    context = new Trick::ADefParseContext( &alloc_decl_sstream);
889✔
277

278
    if (context != NULL) {
889✔
279

280
    /** @li Parse the allocation definition and ensure that the dimension is at least one less than the maximum of 8. */
281
        if (( ADEF_parse( context) == 0) && (context->n_cdims < 8) ){
889✔
282

283
            /** @li Add the dimensions of the element definition. */
284
            for (int ii=0 ; ii < context->n_cdims ; ii++) {
889✔
285
                cdims[ii+1] = context->cdims[ii];
×
286
                n_cdims ++;
×
287
            }
288

289
            /** @li Call the general form of declare_var to perform the allocation. */
290
            address = declare_var( context->type,
889✔
291
                                   context->user_type_name,
889✔
292
                                   context->n_stars,
293
                                   context->var_name,
889✔
294
                                   n_cdims,
295
                                   cdims);
296

297
            /** @li Delete the parse context. */
298
            delete( context);
889✔
299
        } else {
300
            std::stringstream message;
×
301
            message << "declare_var( \"" << element_definition << "\"," << n_elems <<").";
×
302
            emitError(message.str());
×
303
        }
304
    }
305
    /** @li Return the address of the allocation. */
306
    return ( address);
1,778✔
307
}
308

309
// PUBLIC MEMBER FUNCTION: void* Trick::MemoryManager::declare_operatornew_var(std::string user_type_name, unsigned int alloc_size , unsigned int element_size, std::string alloc_name );
310

NEW
311
void* Trick::MemoryManager::declare_operatornew_var( std::string user_type_name, unsigned int alloc_size , unsigned int element_size , std::string alloc_name ) {
×
312
    TRICK_TYPE type = TRICK_STRUCTURED ;
×
313
    int size_ref = 1 ;
×
314
    void* address;
315
    int aligned;
316
    ATTRIBUTES* sub_attr;
317
    ALLOC_INFO *new_alloc;
318

319
    if (debug_level > 1) {
×
320
        std::cout << __FUNCTION__ << ": Parameters: " << std::endl;
×
321
        std::cout << "           user_type_name = " << user_type_name << std::endl;
×
322
        std::cout << "               alloc_size = " << alloc_size << std::endl;
×
323
        std::cout << "             element_size = " << element_size << std::endl;
×
324
    }
325

326
    /** @li From the TRICK_TYPE, user_type_name and the number of pointers (asterisks),
327
            determine the size and the attributes of an element. */
328
    if ( get_type_attributes(type, user_type_name, 0, sub_attr, size_ref ) != 0) {
×
329
        std::stringstream message;
×
330
        message << "get_type_attributes failed for type: " << TRICK_STRUCTURED
×
331
                << " " << user_type_name.c_str() << ".";
×
332
        emitError(message.str());
×
333
        return ((void*)NULL);
×
334
    }
335

336
    if ( (address = calloc( 1, alloc_size ) ) == NULL) {
×
337
        emitError("Out of memory.") ;
×
338
        return ((void*)NULL);
×
339
    }
340

341
    aligned = alloc_size % element_size ;
×
342

343
    /** @li Allocate and populate an ALLOC_INFO record for the allocation. */
344
    if ((new_alloc = (ALLOC_INFO*)calloc(1, sizeof(ALLOC_INFO))) != NULL) {
×
345

346
        new_alloc->start = (char *)address + aligned ;
×
347
        new_alloc->end = ( (char*)new_alloc->start) + alloc_size - 1 - aligned ;
×
NEW
348
        if (alloc_name != "") {
×
NEW
349
            new_alloc->name = strdup(alloc_name.c_str());
×
350
        } else {
NEW
351
            new_alloc->name = NULL;
×
352
        }
353
        new_alloc->stcl = TRICK_LOCAL;
×
354
        new_alloc->size = element_size ;
×
355
        new_alloc->sentinel_bytes = aligned ;
×
356
        new_alloc->language = Language_CPP ;
×
357
        new_alloc->type = TRICK_STRUCTURED ;
×
358

359
        new_alloc->user_type_name = strdup( user_type_name.c_str());
×
360

361
        new_alloc->attr = sub_attr;
×
362
        new_alloc->num = alloc_size / element_size ;
×
363

364
        new_alloc->num_index = 1;
×
365
        new_alloc->index[0] = new_alloc->num ;
×
366

367
        new_alloc->id = alloc_info_map_counter++ ;
×
368

369
        /** @li Insert the <address, ALLOC_INFO> key-value pair into the alloc_info_map.*/
370
        pthread_mutex_lock(&mm_mutex);
×
371
        alloc_info_map[address] = new_alloc;
×
372
        pthread_mutex_unlock(&mm_mutex);
×
373
    } else {
374
        emitError("Out of memory.") ;
×
375
        return ((void*)NULL);
×
376
    }
377

378
    /** @li If debug is enabled, show what happened.*/
379
    if (debug_level ) {
×
380
        std::cout << std::endl;
×
381
        std::cout << "Allocation: " << new_alloc->num << " element(s) of type(" ;
×
382
        std::cout << user_type_name ;
×
383
        std::cout << "), size(" << new_alloc->size << ") @ addr(" << address << ") sentinel_bytes = " << new_alloc->sentinel_bytes ;
×
384
        std::cout << std::endl << std::endl;
×
385
        std::cout.flush();
×
386
    }
387

388
    /** @li Return the address of the allocation. */
389
    return (address);
×
390
}
391

392
// PUBLIC MEMBER FUNCTION: size_t Trick::MemoryManager::sizeof_type( const char* var_definition);
393

394
size_t Trick::MemoryManager::sizeof_type( const char* var_definition) {
21✔
395

396
    int size = 0 ;
21✔
397
    int n_elems = 0 ;
21✔
398
    ATTRIBUTES* sub_attr;
399

400
    Trick::ADefParseContext* context = NULL;
21✔
401
    std::stringstream alloc_decl_sstream;
21✔
402

403
    alloc_decl_sstream << var_definition;
21✔
404
    context = new Trick::ADefParseContext( &alloc_decl_sstream);
21✔
405
    if (context != NULL) {
21✔
406
        if ( ADEF_parse( context) == 0) {
21✔
407

408
            get_type_attributes(context->type, context->user_type_name, context->n_stars, sub_attr, size);
21✔
409

410
            n_elems = 1;
21✔
411
            for (int ii=0; ii<context->n_cdims ; ii++) {
31✔
412
                n_elems *= context->cdims[ii];
10✔
413
            }
414
        } else {
415
            std::stringstream message;
×
416
            message << "Invalid variable definition \"" << var_definition << "\" in sizeof_type.";
×
417
            emitError(message.str());
×
418
        }
419
        delete( context);
21✔
420
    }
421

422
    return (size_t)(n_elems * size);
42✔
423
}
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