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

nasa / trick / 22077843399

16 Feb 2026 09:20PM UTC coverage: 55.628% (+0.02%) from 55.607%
22077843399

Pull #2032

github

web-flow
Merge fffa40b1c into 764b4b429
Pull Request #2032: Added 2D&3D array allocation support from Python and fixed the sim build error when TRICK_CONVERT_SWIG_FLAGS = -s.

12524 of 22514 relevant lines covered (55.63%)

296752.96 hits per line

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

59.84
/trick_source/sim_services/CheckPointAgent/PythonPrint.cpp
1
#include <string>
2
#include <cstring>
3
#include <iostream>
4
#include <iomanip>
5
#include <sstream>
6
#include <stdlib.h>
7
#include <math.h>
8

9
#include "trick/PythonPrint.hh"
10
#include "trick/memorymanager_c_intf.h"
11
#include "trick/parameter_types.h"
12
#include "trick/bitfield_proto.h"
13
#include "trick/message_proto.h"
14
#include "trick/message_type.h"
15

16
// MEMBER FUNCTION
17
bool Trick::PythonPrint::input_perm_check(ATTRIBUTES * attr __attribute__((unused))) {
×
18
    return true ;
×
19
}
20

21
// MEMBER FUNCTION
22
bool Trick::PythonPrint::output_perm_check(ATTRIBUTES * attr __attribute__((unused))) {
20✔
23
    return true ;
20✔
24
}
25

26

27
// MEMBER FUNCTION
28
void Trick::PythonPrint::write_decl(std::ostream& chkpnt_os, ALLOC_INFO *info) {
×
29
    (void)chkpnt_os ;
30
    (void)info ;
31
    return ;
×
32
}
33

34
// MEMBER FUNCTION
35
void Trick::PythonPrint::assign_rvalue(std::ostream& chkpnt_os, void* address, ATTRIBUTES* attr, int curr_dim, int offset) {
20✔
36

37
    chkpnt_os << left_side_name() << " = ";
20✔
38
    write_rvalue( chkpnt_os, (void*)address, attr, curr_dim, offset);
20✔
39
    chkpnt_os << ";" << std::endl;
20✔
40

41
    return ;
20✔
42
}
43

44
// MEMBER FUNCTION
45
int Trick::PythonPrint::restore( std::istream* checkpoint_stream) {
×
46
    (void)checkpoint_stream ;
47
    return 0 ;
×
48
}
49

50

51
// STATIC FUNCTION
52
static void write_quoted_str( std::ostream& os, const char* s, bool in_list) {
15✔
53
    int ii;
54
    int len = strlen(s);
15✔
55
    if ( in_list ) { os << "\"" ; }
15✔
56
    for (ii=0 ; ii<len ; ii++) {
111✔
57
        switch ((s)[ii]) {
96✔
58
        case '\n': os << "\\n"; break;
×
59
        case '\t': os << "\\t"; break;
×
60
        case '\b': os << "\\b"; break;
×
61
        case '\"': os << "\\\""; break;
×
62
        default  : os << s[ii] ; break;
96✔
63
        }
64
    }
65
    if ( in_list ) { os << "\"" ; }
15✔
66
}
15✔
67

68
void Trick::PythonPrint::write_singleton( std::ostream& chkpnt_os, void* address,
2,689✔
69
 ATTRIBUTES* attr, int offset, bool write_units , bool in_list ) {
70

71
    void* src_addr;
72

73
    switch(attr->type) {
2,689✔
74
        case TRICK_UNSIGNED_CHARACTER:
62✔
75
            src_addr = (char*)address + offset * sizeof(unsigned char);
62✔
76
            chkpnt_os << std::dec << (int)*(unsigned char*)src_addr ;
62✔
77
        break;
62✔
78
        case TRICK_BOOLEAN:
213✔
79
            src_addr = (char*)address + offset * sizeof(bool);
213✔
80
            if (*(bool*)src_addr) {
213✔
81
                chkpnt_os << "True" ;
100✔
82
            } else {
83
                chkpnt_os << "False" ;
113✔
84
            }
85
        break;
213✔
86
        case TRICK_CHARACTER:
30✔
87
            src_addr = (char*)address + offset * sizeof(char);
30✔
88
            if (isprint( *(char*)src_addr) ) {
30✔
89
                chkpnt_os << "'" << *(char*)src_addr << "'" ;
4✔
90
            } else {
91
                //unsigned int ch = *(unsigned char*)src_addr;
92
                //chkpnt_os << "'\\x" << hex << ch << "'" ;
93
                int ch = *(char*)src_addr;
26✔
94
                chkpnt_os << ch ;
26✔
95
            }
96
        break;
30✔
97
        case TRICK_WCHAR: {
×
98
            src_addr = (char*)address + offset * sizeof(wchar_t);
×
99
            char buff[16] = {0};
×
100
            wctomb(buff,*(wchar_t*)src_addr);
×
101
            chkpnt_os << std::dec << buff;
×
102
            }
103
            break;
×
104
        case TRICK_SHORT:
218✔
105
            src_addr = (char*)address + offset * sizeof(short);
218✔
106
            chkpnt_os << std::dec << *(short*)src_addr;
218✔
107
            break;
218✔
108
        case TRICK_UNSIGNED_SHORT:
218✔
109
            src_addr = (char*)address + offset * sizeof(unsigned short);
218✔
110
            chkpnt_os << std::dec << *(unsigned short*)src_addr;
218✔
111
            break;
218✔
112
        case TRICK_ENUMERATED: {
×
113
                int ii = 0;
×
114
                int found = 0;
×
115
                int value;
116
                ENUM_ATTR* enum_attr;
117

118
                if ((size_t)attr->size == sizeof(int)) {
×
119
                    src_addr = (char*)address + offset * sizeof(int);
×
120
                    value =  *(int*)src_addr;
×
121
                } else if ((size_t)attr->size == sizeof(short)) {
×
122
                    src_addr = (char*)address + offset * sizeof(short);
×
123
                    value =  *(short*)src_addr;
×
124
                } else {
125
                    std::cerr << __FUNCTION__ << " enumeration size error." << std::endl;
×
126
                    std::cerr.flush();
×
127
                    value = -1;
×
128
                }
129

130
                enum_attr = (ENUM_ATTR*)attr->attr;
×
131

132
                while ( !found && (enum_attr[ii].label[0] != '\0')) {
×
133
                   if (value == enum_attr[ii].value) {
×
134
                       chkpnt_os << enum_attr[ii].label;
×
135
                       found = 1;
×
136
                   }
137
                   ii++;
×
138
                }
139
                if (!found) {
×
140
                    chkpnt_os << std::dec << value;
×
141
                }
142

143
            } break;
×
144
        case TRICK_INTEGER:
370✔
145
            src_addr = (char*)address + offset * sizeof(int);
370✔
146
            chkpnt_os << std::dec << *(int*)src_addr;
370✔
147
            break;
370✔
148
        case TRICK_UNSIGNED_INTEGER:
218✔
149
            src_addr = (char*)address + offset * sizeof(unsigned int);
218✔
150
            chkpnt_os << std::dec << *(unsigned int*)src_addr;
218✔
151
            break;
218✔
152
        case TRICK_LONG:
218✔
153
            src_addr = (char*)address + offset * sizeof(long);
218✔
154
            chkpnt_os << std::dec << *(long*)src_addr;
218✔
155
            break;
218✔
156
        case TRICK_UNSIGNED_LONG:
218✔
157
            src_addr = (char*)address + offset * sizeof(unsigned long);
218✔
158
            chkpnt_os << std::dec << *(unsigned long*)src_addr;
218✔
159
            break;
218✔
160
        case TRICK_FLOAT:
218✔
161
            src_addr = (char*)address + offset * sizeof(float);
218✔
162
            if (fpclassify( *(float*)src_addr) != FP_NAN) {
218✔
163
                chkpnt_os << std::setprecision(8) << *(float*)src_addr;
218✔
164
            } else {
165
                chkpnt_os << "nan";
×
166
            }
167
            break;
218✔
168
        case TRICK_DOUBLE:
269✔
169
            src_addr = (char*)address + offset * sizeof(double);
269✔
170
            if (fpclassify(*(double*)src_addr) != FP_NAN) {
269✔
171
                chkpnt_os << std::setprecision(16) << *(double*)src_addr;
269✔
172
            } else {
173
                chkpnt_os << "nan";
×
174
            }
175
            break;
269✔
176
        case TRICK_BITFIELD: {
×
177
                int sbf = 0;
×
178
                src_addr = (char*)address + offset * (size_t)attr->size;
×
179
                if (attr->size == sizeof(int)) {
×
180
                     sbf = extract_bitfield_any( *(int*)src_addr, attr->size, attr->index[0].start, attr->index[0].size);
×
181
                } else if (attr->size == sizeof(short)) {
×
182
                     sbf = extract_bitfield_any( *(short*)src_addr, attr->size, attr->index[0].start, attr->index[0].size);
×
183
                } else if (attr->size == sizeof(char)) {
×
184
                     sbf = extract_bitfield_any( *(char*)src_addr, attr->size, attr->index[0].start, attr->index[0].size);
×
185
                } else {
186
                     message_publish(MSG_ERROR, "Checkpoint Agent INTERNAL ERROR:\n"
×
187
                                                "Unsupported bitfield size (%d) bytes.\n", attr->size) ;
188
                }
189
                chkpnt_os << std::dec << sbf;
×
190
            } break;
×
191
        case TRICK_UNSIGNED_BITFIELD: {
×
192
                int bf = 0;
×
193
                src_addr = (char*)address + offset * (size_t)attr->size;
×
194
                if (attr->size == sizeof(int)) {
×
195
                     bf = extract_unsigned_bitfield_any( *(unsigned int*)src_addr, attr->size, attr->index[0].start, attr->index[0].size);
×
196
                } else if (attr->size == sizeof(short)) {
×
197
                     bf = extract_unsigned_bitfield_any( *(unsigned short*)src_addr, attr->size, attr->index[0].start, attr->index[0].size);
×
198
                } else if (attr->size == sizeof(char)) {
×
199
                     bf = extract_unsigned_bitfield_any( *(unsigned char*)src_addr, attr->size, attr->index[0].start, attr->index[0].size);
×
200
                } else {
201
                     message_publish(MSG_ERROR, "Checkpoint Agent INTERNAL ERROR:\n"
×
202
                                                "Unsupported bitfield size (%d) bytes.\n", attr->size) ;
203
                }
204
                chkpnt_os << std::dec << bf;
×
205
            } break;
×
206
        case TRICK_LONG_LONG:
218✔
207
            src_addr = (char*)address + offset * sizeof(long long);
218✔
208
            chkpnt_os << std::dec << *(long long*)src_addr;
218✔
209
            break;
218✔
210
        case TRICK_UNSIGNED_LONG_LONG:
218✔
211
            src_addr = (char*)address + offset * sizeof(unsigned long long);
218✔
212
            chkpnt_os << std::dec << *(unsigned long long*)src_addr;
218✔
213
            break;
218✔
214
        case  TRICK_FILE_PTR:
×
215
            src_addr = (char*)address + offset * sizeof(void*);
×
216
            chkpnt_os << *(void**)src_addr;
×
217
            break;
×
218
        case TRICK_STRING:
1✔
219
            src_addr = (char*)address + offset * sizeof(std::string);
1✔
220
            write_quoted_str(chkpnt_os, (*(std::string*)src_addr).c_str(), in_list);
1✔
221
            break;
1✔
222
        case TRICK_OPAQUE_TYPE:
×
223
            chkpnt_os << "ERROR";
×
224
            break;
×
225
        default:
×
226
            chkpnt_os << "0";
×
227
            message_publish(MSG_ERROR, "Checkpoint Agent file %s: Unhandled Type (%d).\n", __FILE__, attr->type) ;
×
228
            break;
×
229
    }
230

231
    if ( write_units && attr->units != NULL && strcmp(attr->units, "1") ) {
2,689✔
232
            chkpnt_os << " " << attr->units ;
327✔
233
    }
234
}
2,689✔
235

236
// MEMBER FUNCTION
237
std::string Trick::PythonPrint::
118✔
238
    ref_string_from_ptr( void* pointer, ATTRIBUTES* attr, int curr_dim) {
239

240
    /** Notice that attr and curr_dim together specify the type. */
241

242
    std::string reference_string;
236✔
243

244
    if ((curr_dim >= attr->num_index) || (attr->index[curr_dim].size != 0)) {
118✔
245
        message_publish(MSG_ERROR, "Checkpoint Agent ERROR: ref_string_from_ptr called with a non-pointer type.\n") ;
×
246
    }
247

248
    if (pointer == NULL) {
118✔
249
        reference_string = "NULL";
116✔
250
    } else {
251
        ALLOC_INFO *alloc_info;
252

253
        /** Find the allocation that contains the pointer-address. */
254
        alloc_info = get_alloc_info_of( pointer);
2✔
255

256
        if (alloc_info != NULL) {
2✔
257
            std::stringstream workss;
2✔
258

259
            if ( *(void **)pointer == NULL ) {
2✔
260
                workss << "NULL" ;
×
261
            } else if (((curr_dim + 1) == attr->num_index) && (attr->type == TRICK_CHARACTER)) {
2✔
262
                workss << "\"" << *(char**)pointer << "\"" ;
1✔
263
            } else {
264
                workss << *(void **)pointer ;
1✔
265
            }
266

267
            reference_string = workss.str() ;
2✔
268

269
        } else if (((curr_dim + 1) == attr->num_index) && (attr->type == TRICK_CHARACTER)) {
×
270
            reference_string += (char*)pointer;
×
271
        } else if (((curr_dim + 1) == attr->num_index) && (attr->type == TRICK_WCHAR)) {
×
272
            message_publish(MSG_ERROR, "Checkpoint Agent INTERNAL ERROR: TRICK_WCHAR not fully supported yet.\n") ;
×
273
            reference_string = "NULL /* INTERNAL ERROR: TRICK_WCHAR not fully supported yet.*/";
×
274
        } else {
275
            message_publish(MSG_ERROR, "Checkpoint Agent ERROR: Pointer <%p> is not in Trick managed memory\n"
×
276
                                       "nor is it a character pointer.\n", pointer) ;
277
            reference_string = "NULL /*ERROR*/";
×
278
        }
279
    }
280
    return( reference_string);
236✔
281
}
282

283
// MEMBER FUNCTION
284
void Trick::PythonPrint::write_rvalue( std::ostream& chkpnt_os, void* address,
3,707✔
285
 ATTRIBUTES* attr, int curr_dim, int offset, bool write_units , bool in_list ) {
286

287
    // If the variable that we are pointing to is Un-arrayed
288
    if (curr_dim == attr->num_index) {
3,707✔
289

290
        write_singleton( chkpnt_os, address, attr, offset, write_units, in_list);
2,689✔
291

292
    // If the variable that we are pointing to is Arrayed
293
    } else if (curr_dim < attr->num_index) {
1,018✔
294

295
        // If the variable is a pointer
296
        if (attr->index[curr_dim].size == 0) {
1,018✔
297
            std::string ref_string;
236✔
298

299
            //void* pointer = *(void**)((char*)address + offset * sizeof(void*));
300

301
            void* pointer = (char*)address + offset * sizeof(void*);
118✔
302
            ref_string = ref_string_from_ptr( pointer, attr, curr_dim);
118✔
303

304
            chkpnt_os << ref_string.c_str() ;
118✔
305

306
        } else { // Fixed dimension
307

308
            char* src_addr;
309

310
            // If this is the final, fixed dimension
311
            if (((curr_dim + 1) == attr->num_index) ||
900✔
312
                (attr->index[curr_dim + 1].size == 0)) {
197✔
313

314
                int use_quoted_string;
315

316
                // If ALL but the last of the elements of a character array
317
                // "isprintable" AND the last is '\0' then print out the array
318
                // as a quoted string. Otherwise print out each of the characters.
319

320
                use_quoted_string = 1;
703✔
321
                if (attr->type == TRICK_CHARACTER) {
703✔
322
                    int ii = attr->index[curr_dim].size - 1;
18✔
323
                    src_addr = (char*)address + offset * attr->index[curr_dim].size;
18✔
324

325
                    if (src_addr[ii] != '\0' || src_addr[0] == '\0' ) {
18✔
326
                        use_quoted_string = 0;
4✔
327
                    }
328
                    ii--;
18✔
329
                    while ( use_quoted_string && (ii >= 0) ) {
164✔
330
                        use_quoted_string = isprint( src_addr[ii]) || src_addr[ii] == '\0' ;
146✔
331
                        ii--;
146✔
332
                    }
333
                }
334

335
                if ((attr->type == TRICK_CHARACTER) && use_quoted_string)  {
703✔
336
                    write_quoted_str(chkpnt_os, src_addr, in_list);
14✔
337
                } else {
338

339
                    int ii;
340
                    int array_len;
341

342
                    // Determine the number of array elements we need to print out
343
                    // to get all of the non-zero values.
344

345
                    array_len = attr->index[curr_dim].size ;
689✔
346
                    chkpnt_os << "[";
689✔
347

348
                    for (ii = 0; ii < array_len ; ii++ ) {
3,360✔
349

350
                        if (ii > 0) {
2,671✔
351
                            chkpnt_os << ", ";
1,982✔
352
                        }
353
                        write_rvalue( chkpnt_os, address, attr, curr_dim + 1,
5,342✔
354
                         offset * attr->index[curr_dim].size + ii, write_units, true);
2,671✔
355
                    }
356
                    chkpnt_os << "]";
689✔
357

358
                }
703✔
359

360
            } else { // Not the final fixed dimension.
361

362
                int ii;
363

364
                chkpnt_os << "[";
197✔
365

366
                for (ii=0 ; ii< attr->index[curr_dim].size ; ii++) {
692✔
367
                    if (ii > 0) {
495✔
368
                        chkpnt_os << ",";
298✔
369
                    }
370
                    write_rvalue( chkpnt_os, address, attr, curr_dim + 1,
990✔
371
                     offset * attr->index[curr_dim].size + ii, write_units, true);
495✔
372
                }
373

374
                chkpnt_os << "]";
197✔
375
            }
376
        }
377

378
    } else {
379
        chkpnt_os << "/*ERROR*/";
×
380

381
        message_publish(MSG_ERROR, "Checkpoint Agent ERROR: The specified current dimension \"%d\" is greater\n"
×
382
                                   "than the number of dimensions specified in the type ATTRIBUTES.\n", curr_dim) ;
383

384
        return;
×
385
    }
386
}
387

388
std::string Trick::PythonPrint::left_side_name() {
20✔
389

390
    std::string name ;
40✔
391
    int ii;
392
    int n_elements = leftside_stack.size();
20✔
393

394
    for (ii = 0; ii < n_elements ; ii++) {
40✔
395

396
        VarNameElement & element = leftside_stack[ii];
20✔
397

398
        switch( element.type) {
20✔
399

400
            case BASE_NAME: {
×
401
                name = element.name;
×
402
            } break;
×
403

404
            case ELEM_NAME: {
20✔
405
                name += '.' + element.name;
20✔
406
            } break;
20✔
407

408
            case ARRAY_INDEX: {
×
409
                std::stringstream index_string;
×
410
                index_string << element.index;
×
411
                name += '[';
×
412
                name += index_string.str();
×
413
                name += ']';
×
414
            } break;
×
415

416
            default: {
×
417
                message_publish(MSG_ERROR, "Checkpoint Agent ERROR: BADNESS!!\n") ;
×
418
            }
419
        }
420
    }
421
    return( name);
40✔
422
}
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