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

nasa / trick / 19944979756

04 Dec 2025 09:46PM UTC coverage: 55.922% (+0.02%) from 55.899%
19944979756

push

github

web-flow
Don't use TMM to allocate argv (#1980)

* Don't use TMM for storing argv

* Formatting fixes

* Fix comment on `get_argv()`

* More const and string compare changes

* Error on more than one `-OO?` flag

* Fix loop bounds

38 of 46 new or added lines in 2 files covered. (82.61%)

2 existing lines in 1 file now uncovered.

12470 of 22299 relevant lines covered (55.92%)

299228.71 hits per line

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

58.74
/trick_source/sim_services/CommandLineArguments/CommandLineArguments.cpp
1
/*
2
   PURPOSE: ( Handle the simulation command line args )
3

4
   REFERENCE: ( Trick Simulation Environment )
5

6
   ASSUMPTIONS AND LIMITATIONS: ( None )
7

8
   CLASS: ( N/A )
9

10
   LIBRARY DEPENDENCY: ( None )
11

12
   PROGRAMMERS: ( Keith Vetter LinCom 6/2003 ) */
13

14

15
#include <cerrno>
16
#include <cstdio>
17
#include <cstdlib>
18
#include <cstring>
19
#include <ctime>
20
#include <iostream>
21
#include <pwd.h>
22
#include <string>
23
#include <sys/stat.h>
24
#include <sys/types.h>
25
#include <unistd.h>
26
#include <vector>
27

28
#include "trick/CommandLineArguments.hh"
29
#include "trick/memorymanager_c_intf.h"
30

31
Trick::CommandLineArguments * the_cmd_args ;
32

33
Trick::CommandLineArguments::CommandLineArguments()
228✔
34
    : argc(0)
228✔
35
{
36
    the_cmd_args = this ;
228✔
37

38
    output_dir = std::string(".");
228✔
39
    default_dir = std::string(".");
228✔
40
}
228✔
41

42
int Trick::CommandLineArguments::get_argc() {
740✔
43
    return(argc) ;
740✔
44
}
45

46
std::vector<std::string>& Trick::CommandLineArguments::get_argv() { return (argv); }
740✔
47

48
std::string Trick::CommandLineArguments::get_output_dir() {
×
49
    return(output_dir) ;
×
50
}
51

52
std::string & Trick::CommandLineArguments::get_output_dir_ref() {
1,503✔
53
    return(output_dir) ;
1,503✔
54
}
55

56
std::string Trick::CommandLineArguments::get_user_output_dir() {
×
57
    return(user_output_dir) ;
×
58
}
59

60
std::string & Trick::CommandLineArguments::get_user_output_dir_ref() {
325✔
61
    return(user_output_dir) ;
325✔
62
}
63

64
std::string Trick::CommandLineArguments::get_input_file() {
×
65
    return(input_file) ;
×
66
}
67

68
std::string & Trick::CommandLineArguments::get_input_file_ref() {
252,047✔
69
    return(input_file) ;
252,047✔
70
}
71

72
std::string Trick::CommandLineArguments::get_default_dir() {
×
73
    return(default_dir) ;
×
74
}
75

76
std::string & Trick::CommandLineArguments::get_default_dir_ref() {
251,684✔
77
    return(default_dir) ;
251,684✔
78
}
79

80
std::string Trick::CommandLineArguments::get_cmdline_name() {
×
81
    return(cmdline_name) ;
×
82
}
83

84
std::string & Trick::CommandLineArguments::get_cmdline_name_ref() {
251,679✔
85
    return(cmdline_name) ;
251,679✔
86
}
87

88
// Helper function - create a full path with error checking along the way
89
int Trick::CommandLineArguments::create_path(const std::string& dirname) {
7✔
90
    size_t cur_index = 0;
7✔
91

92
    std::string full_dir (dirname);
14✔
93

94
    // These syscalls don't seem to take care of home special character, so do it manually
95
    // I think the shell should handle it before it gets here, but just in case check for it
96
    if (dirname.at(0) == '~') {
7✔
97
        struct passwd *pw = getpwuid(getuid());
×
98
        full_dir = std::string(pw->pw_dir) + dirname.substr(1, dirname.size());
×
99
    }
100

101
    while (cur_index != full_dir.size()) {
32✔
102
        cur_index = full_dir.find('/', cur_index+1);
26✔
103
        if (cur_index == std::string::npos) {
26✔
104
            cur_index = full_dir.size();
6✔
105
        }
106
        std::string cur_dir = full_dir.substr(0, cur_index);
26✔
107

108
        struct stat info;
109
        if(stat( cur_dir.c_str(), &info ) != 0) {
26✔
110
            // does not exist - make it
111
            if (mkdir(cur_dir.c_str(), 0775) == -1) {
11✔
112
                std::cerr << "Error creating directory " << cur_dir << std::endl;
×
113
                return 1;
×
114
            }
115
        } else {
116
            // Does exist
117
            if(info.st_mode & S_IFDIR) {
15✔
118
                // Is a directory
119
                if (info.st_mode & S_IWUSR) {
14✔
120
                    // Perfect, nothing to do here
121
                } else {
122
                    // Not writeable
123
                    std::cerr << "Intermediate directory " << cur_dir << " is not writable, unable to create output directory." << std::endl;
×
124
                    return 1;
×
125
                }
126
            } else {
127
                // Does exist, but is a file
128
                std::cerr << "Intermediate directory " << cur_dir << " is not a directory, unable to create output directory." << std::endl;
1✔
129
                return 1;
1✔
130
            }
131
        }
132
    }
133
    return 0;
6✔
134
}
135

136
/**
137
@details
138
-# Save the number of command line arguments.
139
-# Save the command line arguments.
140
-# Determine the directory and simulation executable name from the first
141
   command line argument
142
   -# If no directory is specified
143
      -# Save the simulation executable name as the full first argument
144
      -# Get the current working directory
145
      -# Save the current working directory as the default input directory.
146
   -# If a relative or full directory is present in the command line arguments
147
      -# split the command line argument on the last "/" character
148
      -# Save the back half of the split as the simulation executable name
149
      -# Save the current working directory
150
      -# Change the current working directory to the first half of the split
151
         command line argument.
152
      -# Get the current working directory
153
      -# Save the current working directory as the default input directory.
154
      -# Change the current working directory to the saved working directory
155
-# If present, the second argument will be the run directory and the input file.
156
   -# Save the run input file  name as the full second argument
157
   -# Split the second argument on the last "/" character
158
   -# If no directory is specified set the default output and current output
159
      directories to the current directory
160
   -# Else set the default and the current output directories to the first
161
      half of the split
162
-# Search the remaining command line arguments for "-O" or "-OO"
163
   -# If found set the output direcory to the following argument
164
   -# Attempt to create the output directory if it does not exist.
165
      -# Exit if the simulation cannot be created.
166
*/
167
int Trick::CommandLineArguments::process_sim_args(int nargs , char **args) {
184✔
168

169
    argc = nargs;
184✔
170
    argv.clear();
184✔
171
    argv.reserve(argc);
184✔
172
    for (int ii = 0; ii < argc; ii++) {
555✔
173
        argv.emplace_back(args[ii]);
371✔
174
    }
175

176
    default_dir = argv[0] ;
184✔
177

178
    char* buf  = (char*)malloc(4096);
184✔
179
    char* buf2 = (char*)malloc(4096);
184✔
180

181
    size_t found = default_dir.find_last_of('/');
184✔
182

183
    if ( found == std::string::npos ) {
184✔
184
        cmdline_name = default_dir ;
×
185
        getcwd(buf, (size_t) 256);
×
186
        default_dir = buf ;
×
187
    } else {
188
        cmdline_name = default_dir.substr(found + 1) ;
184✔
189

190
        // save the current directory
191
        getcwd(buf, (size_t) 256);
184✔
192

193
        // change to the default directory
194
        chdir(default_dir.substr(0,found).c_str());
184✔
195

196
        // get the full path default directory
197
        getcwd(buf2, (size_t) 256);
184✔
198
        default_dir = buf2 ;
184✔
199

200
        // change back to the current directory
201
        chdir(buf);
184✔
202
    }
203

204
    free(buf) ;
184✔
205
    free(buf2) ;
184✔
206

207
    if ( argc > 1 ) {
184✔
208

209
        /* First occurrence of "RUN_*" is the input file name: '<Run_dir>/<file_name>'.
210
           If not found, defaults to first argument */
211

212
        input_file = argv[1];
184✔
213
        run_dir = argv[1];
184✔
214

215
        for (const auto& arg : argv) {
375✔
216
            if (arg.find("RUN_") != std::string::npos) {
368✔
217
                input_file = arg;
177✔
218
                run_dir    = arg;
177✔
219
                break;
177✔
220
            }
221
        }
222

223
        if (access(input_file.c_str(), F_OK) != 0) {
184✔
224
          input_file = "";
×
NEW
225
          if (argv[1] != "trick_version" && argv[1] != "sie" && argv[1] != "-help" && argv[1] != "--help"
×
NEW
226
              && argv[1] != "-h" && argv[1] != "help") {
×
NEW
227
              std::cerr << "\nERROR: Invalid input file or command line argument." << std::endl;
×
NEW
228
              exit(1);
×
229
          }
230
        }
231

232
        found = run_dir.find_last_of('/');
184✔
233
        if ( found != std::string::npos ) {
184✔
234
            run_dir.erase(found) ;
184✔
235
        } else {
236
            run_dir = "." ;
×
237
        }
238
        /* check existence of run directory */
239
        if (access(run_dir.c_str(), F_OK) != 0) {
184✔
240
            std::cerr << "\nERROR: while accessing input file directory \"" << run_dir << "\" : " << std::strerror(errno) << std::endl ;
×
241
            exit(1);
×
242
        }
243

244
        output_dir = run_dir ;
184✔
245

246
        const std::string flag_output_dir      = "-O";
368✔
247
        const std::string flag_output_dir_more = "-OO";
368✔
248
        bool output_dir_is_set                 = false;
184✔
249

250
        for (size_t ii = 0; ii < argv.size(); ii++) {
555✔
251
            if (argv[ii] == flag_output_dir || argv[ii] == flag_output_dir_more) {
371✔
252
                if (output_dir_is_set) {
1✔
NEW
253
                    std::cerr << "\nERROR: Multiple -O or -OO flags found" << "\n";
×
NEW
254
                    exit(1);
×
255
                }
256
                if (ii == argv.size() - 1) {
1✔
NEW
257
                    std::cerr << "\nERROR: No directory specified after -O or -OO argument" << "\n";
×
NEW
258
                    exit(1);
×
259
                }
260

261
                /* Output data directory */
262
                output_dir_is_set = true;
1✔
263
                user_output_dir   = argv[ii + 1];
1✔
264
                output_dir        = user_output_dir;
1✔
265
                if (argv[ii] == flag_output_dir_more) {
1✔
266
                    output_dir = output_dir + "/" + run_dir;
1✔
267
                }
268
            }
269
        }
270

271
        /* Create output directory if necessary. */
272
        if (access(output_dir.c_str(), F_OK) != 0) {
184✔
273
            if (create_path(output_dir) != 0) {
1✔
274
                std::cerr << "\nERROR: While trying to create output directory \"" << output_dir << "\" : " << std::strerror(errno) << std::endl ;
×
275
                exit(1) ;
×
276
            }
277
        } else {
278
            /* check permissions on output directory */
279
            if (access(output_dir.c_str(), (W_OK|X_OK) ) == -1) {
183✔
280
                std::cerr << "\nERROR: while writing to output directory \"" << output_dir << "\" : " << std::strerror(errno) << std::endl ;
×
281
                exit(2) ;
×
282
            }
283
        }
284
    }
285

286
    return(0) ;
184✔
287

288
}
289

290

291
/**
292
@design
293
-# Get the current system date and time.
294
-# Set the subdirectory within the current output directory to
295
   DATA_<year>_<month>_<day>_<hour>_<minute>_<second>
296
   -# Attempt to create the output directory if it does not exist.
297
      -# Exit if the simulation cannot be created.
298
*/
299
int Trick::CommandLineArguments::output_dir_timestamped_on() {
×
300

301
    time_t date ;
302
    struct tm *curr_time ;
303
    char temp_str[256] ;
304

305
    date = time(NULL) ;
×
306
    curr_time = localtime(&date) ;
×
307

308
    snprintf(temp_str, sizeof(temp_str), "DATA_%4d_%02d_%02d_%02d_%02d_%02d",
×
309
            curr_time->tm_year + 1900 , curr_time->tm_mon + 1 , curr_time->tm_mday,
×
310
            curr_time->tm_hour , curr_time->tm_min , curr_time->tm_sec );
311

312
    time_stamp_dir = std::string(temp_str) ;
×
313

314
    if ( ! user_output_dir.empty() ) {
×
315
        output_dir = user_output_dir + "/" + time_stamp_dir ;
×
316
    } else {
317
        output_dir = run_dir + "/" + time_stamp_dir ;
×
318
    }
319

320
    /* Create directories if necessary. */
321
    if (access(output_dir.c_str(), F_OK) != 0) {
×
322
        if (mkdir(output_dir.c_str(), 0775) == -1) {
×
323
            std::cerr << "\nERROR: While trying to create dir \"" << output_dir << "\" Exiting!" << std::endl ;
×
324
            exit(1) ;
×
325
        }
326
    }
327

328
    output_dir_timestamped = 1 ;
×
329
    return(0) ;
×
330
}
331

332
/**
333
@design
334
-# If the user had specified an output directory reset
335
   the output directory to the user specified directory
336
-# Else set the output directory to the run directory.
337
*/
338
int Trick::CommandLineArguments::output_dir_timestamped_off() {
×
339

340
    if ( ! user_output_dir.empty() ) {
×
341
        output_dir = user_output_dir ;
×
342
    } else {
343
        output_dir = run_dir ;
×
344
    }
345

346
    output_dir_timestamped = 0 ;
×
347
    return(0) ;
×
348

349
}
350

351
/**
352
@design
353
-#  Sets the value of output_dir
354
*/
355
void Trick::CommandLineArguments::set_output_dir(std::string output_directory) {
×
356
    output_dir = output_directory;
×
357
}
×
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

© 2025 Coveralls, Inc