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

nasa / trick / 19876823462

02 Dec 2025 11:24PM UTC coverage: 55.656% (-0.2%) from 55.811%
19876823462

Pull #1996

github

web-flow
Merge c94873ee2 into b0776a3f7
Pull Request #1996: Add vs support for stl vector, deque, and array containers of supported data types

29 of 100 new or added lines in 6 files covered. (29.0%)

4 existing lines in 3 files now uncovered.

12418 of 22312 relevant lines covered (55.66%)

260316.9 hits per line

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

45.83
/trick_source/sim_services/MemoryManager/MemoryManager_ref_dim.cpp
1
#include <stdio.h>
2
#include <sys/types.h>
3
#include <string.h>
4
#include <sstream>
5
#include <array>
6
#include <algorithm>
7
#include <regex>
8

9
#include "trick/MemoryManager.hh"
10
#include "trick/vval.h"
11
#include "trick/attributes.h"
12
#include "trick/reference.h"
13
#include "trick/parameter_types.h"
14

15
/*
16
 Updates R, a reference to an arrayed object, to a reference to the indexed sub-element of that arrayed object.
17
*/
18
int Trick::MemoryManager::ref_dim( REF2* R, V_DATA* V) {
21,754✔
19

20
    int jj;
21
    int item_size;
22
    int index_value = vval_int(V);
21,754✔
23

24
    if (R->ref_type != REF_ADDRESS) {
21,754✔
25
        emitError("Attempt to index into a non-address reference is bogus in ref_dim.") ;
×
26
        return (1);
×
27
    }
28

29
    // Special handling for STL vectors, deques, and arrays - use the generated accessor function that
30
    // calls [] operator for element access
31
    if (R->attr->type == TRICK_STL &&
21,754✔
32
        (R->attr->stl_type == TRICK_STL_VECTOR ||
1✔
NEW
33
         R->attr->stl_type == TRICK_STL_DEQUE ||
×
NEW
34
         R->attr->stl_type == TRICK_STL_ARRAY) &&
×
35
        R->num_index == 0) {
1✔
36
        // Use the generated accessor functions to get vector/ deque/ array size and element address
37
        // These functions are generated by ICG and know the actual vector/ deque/ array type
38

39
        if (R->attr->get_stl_size == NULL || R->attr->get_stl_element == NULL) {
1✔
NEW
40
            emitError("STL vector accessor functions are NULL in ref_dim.");
×
NEW
41
            return (TRICK_PARAMETER_ARRAY_SIZE);
×
42
        }
43

44
        // Currently supported STL element types
45
        static constexpr std::array<TRICK_TYPE, 14> supported_stl_elem_types = {
46
            TRICK_STRING,
47
            //TRICK_CHARACTER,
48
            //TRICK_UNSIGNED_CHARACTER,
49
            TRICK_ENUMERATED,
50
            TRICK_SHORT,
51
            TRICK_UNSIGNED_SHORT,
52
            TRICK_INTEGER,
53
            TRICK_UNSIGNED_INTEGER,
54
            TRICK_LONG,
55
            TRICK_UNSIGNED_LONG,
56
            TRICK_FLOAT,
57
            TRICK_DOUBLE,
58
            TRICK_LONG_LONG,
59
            TRICK_UNSIGNED_LONG_LONG,
60
            TRICK_BOOLEAN,
61
            TRICK_STRUCTURED
62
        };
63

64
        // Check if element type is supported
65
        if (std::find(supported_stl_elem_types.begin(), 
1✔
66
                      supported_stl_elem_types.end(), 
67
                      R->attr->stl_elem_type) == supported_stl_elem_types.end()) {
2✔
NEW
68
            emitError("Unsupported STL element type in ref_dim.");
×
NEW
69
            return (TRICK_PARAMETER_ARRAY_SIZE);
×
70
        }
71

72
        // Get the number of elements using the type-safe accessor function
73
        size_t num_elements = R->attr->get_stl_size(R->address);
1✔
74

75
        // Check bounds
76
        if (index_value < 0 || (size_t)index_value >= num_elements) {
1✔
NEW
77
            if (debug_level > 1) {
×
NEW
78
                std::stringstream message;
×
NEW
79
                message << index_value << " is out of bounds for STL vector/ deque/ array " << R->reference
×
NEW
80
                        << " (size=" << num_elements << ").";
×
NEW
81
                emitError(message.str());
×
82
            }
NEW
83
            return (TRICK_PARAMETER_ARRAY_SIZE);
×
84
        }
85

86
        // Get the address of the indexed element using the type-safe accessor function
87
        R->address = R->attr->get_stl_element(R->address, index_value);
1✔
88

89
        // For structured types, ref_name will handle the attribute lookup dynamically
90
        // For enumerated types, we need to update attr to point to the enum attributes
91
        // For primitive types, increment num_index as normal
92
        if (R->attr->stl_elem_type == TRICK_ENUMERATED && R->attr->stl_elem_type_name != NULL) {
1✔
93
            // Increment num_index first
NEW
94
            R->num_index++;
×
95
            // Look up the enum attributes using the element type name
NEW
96
            ENUMERATION_MAP::iterator enum_pos = enumeration_map.find(R->attr->stl_elem_type_name);
×
NEW
97
            if (enum_pos != enumeration_map.end()) {
×
98
                // Create a temporary attribute structure for the enum element
99
                static ATTRIBUTES temp_enum_attr;
NEW
100
                memset(&temp_enum_attr, 0, sizeof(ATTRIBUTES));
×
NEW
101
                temp_enum_attr.type = TRICK_ENUMERATED;
×
NEW
102
                temp_enum_attr.type_name = R->attr->stl_elem_type_name;
×
NEW
103
                temp_enum_attr.attr = enum_pos->second; // Point to ENUM_ATTR array
×
NEW
104
                temp_enum_attr.size = R->attr->size; // Size of element type
×
NEW
105
                temp_enum_attr.num_index = R->num_index; // Match the incremented indexing level
×
NEW
106
                temp_enum_attr.units = (char*)"1"; // Default units for enums
×
NEW
107
                R->attr = &temp_enum_attr;
×
NEW
108
            }
×
109
        } else if (R->attr->stl_elem_type != TRICK_STRUCTURED) {
1✔
110
            R->num_index++;
1✔
111
        }
112
        // For primitive types, the variable server and other code handle STL types
113
        // by checking stl_elem_type when type == TRICK_STL
114

115
        return (TRICK_NO_ERROR);
1✔
116
    }
117

118
    R->num_index_left--;
21,753✔
119
    if (R->num_index_left < 0) {
21,753✔
120
        /* if we have too many dimensions, flag an error */
121
        emitError("Too many dimensions in ref_dim.\n") ;
×
122
        return (TRICK_PARAMETER_ARRAY_SIZE);
×
123
    }
124

125
    /*Calculate the size of the items in this array. */
126
    item_size =  R->attr->size;
21,753✔
127
    for (jj = (R->attr->num_index - 1); jj > R->num_index; jj--) {
23,096✔
128
        if (R->attr->index[jj].size > 0) {
1,343✔
129
            item_size *= R->attr->index[jj].size;
635✔
130
        } else {
131
            item_size = sizeof(void *);
708✔
132
            R->pointer_present = 1 ;
708✔
133
        }
134
    }
135

136
    /* if current dimension is a constrained ... */
137
    if (R->attr->index[R->num_index].size != 0) {
21,753✔
138

139
        /* for constrained dimensions, we can check the validity of the index value */
140
        if (index_value >= R->attr->index[R->num_index].size || index_value < 0) {
21,641✔
141
            /* print out of bounds error message if MM debug_level is greater than 1 */
142
            if (debug_level > 1) {
3✔
143
                emitError("Memory Manager ERROR: Array index out of bounds.") ;
×
144
            }
145
            return (TRICK_PARAMETER_ARRAY_SIZE);
3✔
146
        }
147

148
    } else {
149

150
        /* for unconstrained dimensions, we can check that the index value is non-negative
151
           and that it is less than the size of the array */
152
        if (index_value >= (get_size(*(void**)(R->address))) || index_value < 0) {
112✔
153

154
            if (index_value >= 0 && get_size(*(void**)(R->address)) == 0) {
×
155
                // Special case (do nothing here):
156
                //   For regular pointers as an equivalent to ->
157
                //   For array pointers that are not yet allocated
158
                // If a pointer is not allocated regardless of regular pointer or array pointer, an error message will be emitted below
159
                //   However, if the pointer is already assigned to a valid address, the error message will NOT be emitted below
160
            } else {
161
                /* print out of bounds error message if MM debug_level is greater than 1 */
162
                if (debug_level > 1) {
×
163
                    std::stringstream message;
×
164
                    message << index_value << " is out of bounds for " << R->reference << " (size=" << get_size(*(void**)(R->address)) << ").";
×
165
                    emitError(message.str());
×
166
                }
167
                return (TRICK_PARAMETER_ARRAY_SIZE);
×
168
            }
169
        }
170

171
        R->pointer_present = 1 ;
112✔
172
        if ( R->create_add_path ) {
112✔
173
            ADDRESS_NODE * address_node ;
174

175
            address_node = new ADDRESS_NODE ;
112✔
176
            address_node->operator_ = AO_DEREFERENCE ;
112✔
177
            address_node->operand.address = NULL ;
112✔
178
            DLL_AddTail(address_node , R->address_path) ;
112✔
179
        }
180

181
        // Dereference the pointer.
182
        R->address = *(void**)R->address;
112✔
183
        if ( R->address == NULL) {
112✔
184
            std::stringstream message;
×
185
            message << "Reference (" << R->reference << ") address is NULL in ref_dim.";
×
186
            emitError(message.str());
×
187
            return(TRICK_PARAMETER_ADDRESS_NULL) ;
×
188
        }
189

190
        // Get allocation information for the address
191
        ALLOC_INFO *alloc_info = get_alloc_info_of(R->address);
112✔
192

193
        // Skip if allocation name is NULL
194
        if (alloc_info != NULL && alloc_info->name != NULL) {
112✔
195
            // Get the reference name from the address that R points if exists and contains & at front
196
            // Otherwise, the pointer is not assigned to anything else rather itself is allocated
197
            std::string ref_name = ref_name_from_address(R->address);
×
198
            if (!ref_name.empty() && ref_name.front() == '&') {
×
199
                ref_name = ref_name.substr(1);
×
200

201
                // Get the reference attributes for what the pointer points to
202
                REF2 *ref2 = ref_attributes((char*)ref_name.c_str());
×
203

204
                // Check if the reference that the pointer points to is valid. Return error if not.
205
                if (ref2 == NULL) {
×
206
                    std::stringstream message;
×
207
                    message << "Reference (" << R->reference << ") is not allocated in ref_dim.";
×
208
                    emitError(message.str());
×
209
                    return(TRICK_PARAMETER_ADDRESS_NULL);
×
210
                }
211

212
                // Only check bounds if ref2 is array-ed
213
                if (ref2->num_index > 0) {
×
214
                    // Check if the pointer points to a static array or a dynamic array and if array index is out of bounds
215
                    if (ref2->attr && ref2->attr->index[ref2->attr->num_index-1].size != 0) { // Static array case
×
216
                        // Check if the index is out of bounds if the pointer points to a static array
217
                        if (index_value >= ref2->attr->index[ref2->attr->num_index-1].size || index_value < 0) {
×
218
                            /* print out of bounds error message if MM debug_level is greater than 1 */
219
                            if (debug_level > 1) {
×
220
                                emitError("Memory Manager ERROR: Array index out of bounds.") ;
×
221
                            }
222
                            free(ref2);
×
223
                            return (TRICK_PARAMETER_ARRAY_SIZE);
×
224
                        }
225
                    } else { // Dynamic array case
226
                        // Check if the index is out of bounds if the pointer points to a dynamic array
227
                        if (index_value >= (get_size(*(void**)(R->address)))) {
×
228
                            /* print out of bounds error message if MM debug_level is greater than 1 */
229
                            if (debug_level > 1) {
×
230
                                std::stringstream message;
×
231
                                message << index_value << " is out of bounds for " << R->reference << " (size=" << get_size(*(void**)(R->address)) << ").";
×
232
                                emitError(message.str());
×
233
                            }
234
                            free(ref2);
×
235
                            return (TRICK_PARAMETER_ARRAY_SIZE);
×
236
                        }
237
                    }
238
                }
239
            } // if (!ref_name.empty() && ref_name.front() == '&') {
240
        } // if (alloc_info->name != NULL) {
241
    } // if (R->attr->index[R->num_index].size != 0) {
242

243
    if ( R->create_add_path ) {
21,750✔
244

245
        ADDRESS_NODE * address_node ;
246

247
        if ( index_value > 0 ) {
9,798✔
248
            address_node = (ADDRESS_NODE *)DLL_GetAt(DLL_GetTailPosition(R->address_path), R->address_path) ;
9,191✔
249
            switch ( address_node->operator_ ) {
9,191✔
250
                case AO_ADDRESS:
9,079✔
251
                    address_node->operand.address = (void *)((char *)address_node->operand.address +  index_value * item_size) ;
9,079✔
252
                    break ;
9,079✔
253
                case AO_DEREFERENCE:
112✔
254
                    address_node = new ADDRESS_NODE ;
112✔
255
                    address_node->operator_ = AO_OFFSET ;
112✔
256
                    address_node->operand.offset = index_value * item_size ;
112✔
257
                    DLL_AddTail(address_node , R->address_path) ;
112✔
258
                    break ;
112✔
259
                case AO_OFFSET:
×
260
                    address_node->operand.offset += index_value * item_size ;
×
261
                    break ;
×
262
            }
263
        }
264
    }
265

266
    R->address =  (void*)((char*)R->address + index_value * item_size);
21,750✔
267
    R->num_index++;
21,750✔
268

269
    return (TRICK_NO_ERROR);
21,750✔
270
}
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