trick/trick_source/sim_services/CommandLineArguments/CommandLineArguments.cpp
Scott Fennell f6fa9cdf3e #506 added additional check on run directory to prevent creation as defaul… (#566)
* added additional check on run directory to prevent creation as default output directory

* #506 edited error messages to include strerror
2018-03-14 15:18:37 -05:00

276 lines
8.0 KiB
C++

/*
PURPOSE: ( Handle the simulation command line args )
REFERENCE: ( Trick Simulation Environment )
ASSUMPTIONS AND LIMITATIONS: ( None )
CLASS: ( N/A )
LIBRARY DEPENDENCY: ( None )
PROGRAMMERS: ( Keith Vetter LinCom 6/2003 ) */
#include <iostream>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <cstring>
#include <cerrno>
#include "trick/CommandLineArguments.hh"
#include "trick/memorymanager_c_intf.h"
Trick::CommandLineArguments * the_cmd_args ;
Trick::CommandLineArguments::CommandLineArguments() {
the_cmd_args = this ;
output_dir = std::string(".") ;
default_dir = std::string(".") ;
}
int Trick::CommandLineArguments::get_argc() {
return(argc) ;
}
char ** Trick::CommandLineArguments::get_argv() {
return(argv) ;
}
std::string Trick::CommandLineArguments::get_output_dir() {
return(output_dir) ;
}
std::string & Trick::CommandLineArguments::get_output_dir_ref() {
return(output_dir) ;
}
std::string Trick::CommandLineArguments::get_user_output_dir() {
return(user_output_dir) ;
}
std::string & Trick::CommandLineArguments::get_user_output_dir_ref() {
return(user_output_dir) ;
}
std::string Trick::CommandLineArguments::get_input_file() {
return(input_file) ;
}
std::string & Trick::CommandLineArguments::get_input_file_ref() {
return(input_file) ;
}
std::string Trick::CommandLineArguments::get_default_dir() {
return(default_dir) ;
}
std::string & Trick::CommandLineArguments::get_default_dir_ref() {
return(default_dir) ;
}
std::string Trick::CommandLineArguments::get_cmdline_name() {
return(cmdline_name) ;
}
std::string & Trick::CommandLineArguments::get_cmdline_name_ref() {
return(cmdline_name) ;
}
/**
@details
-# Save the number of command line arguments.
-# Save the command line arguments.
-# Determine the directory and simulation executable name from the first
command line argument
-# If no directory is specified
-# Save the simulation executable name as the full first argument
-# Get the current working directory
-# Save the current working directory as the default input directory.
-# If a relative or full directory is present in the command line arguments
-# split the command line argument on the last "/" character
-# Save the back half of the split as the simulation executable name
-# Save the current working directory
-# Change the current working directory to the first half of the split
command line argument.
-# Get the current working directory
-# Save the current working directory as the default input directory.
-# Change the current working directory to the saved working directory
-# If present, the second argument will be the run directory and the input file.
-# Save the run input file name as the full second argument
-# Split the second argument on the last "/" character
-# If no directory is specified set the default output and current output
directories to the current directory
-# Else set the default and the current output directories to the first
half of the split
-# Search the remaining command line arguments for "-O" or "-OO"
-# If found set the output direcory to the following argument
-# Attempt to create the output directory if it does not exist.
-# Exit if the simulation cannot be created.
*/
int Trick::CommandLineArguments::process_sim_args(int nargs , char **args) {
char *buf, *buf2;
size_t found ;
int ii ;
argc = nargs ;
argv = (char **)TMM_declare_var_1d("char *", argc) ;
for ( ii = 0 ; ii < argc ; ii++ ) {
argv[ii] = TMM_strdup(args[ii]) ;
}
buf = (char *)malloc(4096) ;
buf2 = (char *)malloc(4096) ;
default_dir = argv[0] ;
found = default_dir.find_last_of("/") ;
if ( found == std::string::npos ) {
cmdline_name = default_dir ;
getcwd(buf, (size_t) 256);
default_dir = buf ;
} else {
cmdline_name = default_dir.substr(found + 1) ;
// save the current directory
getcwd(buf, (size_t) 256);
// change to the default directory
chdir(default_dir.substr(0,found).c_str());
// get the full path default directory
getcwd(buf2, (size_t) 256);
default_dir = buf2 ;
// change back to the current directory
chdir(buf);
}
free(buf) ;
free(buf2) ;
if ( argc > 1 ) {
/* First argument is the input file name: '<Run_dir>/<file_name>' */
input_file = argv[1] ;
run_dir = argv[1] ;
found = run_dir.find_last_of("/") ;
if ( found != std::string::npos ) {
run_dir.erase(found) ;
} else {
run_dir = "." ;
}
/* check existence of run directory */
if (access(run_dir.c_str(), F_OK) != 0) {
std::cerr << "\nERROR: while accessing input file directory \"" << run_dir << "\" : " << std::strerror(errno) << std::endl ;
exit(1);
}
output_dir = run_dir ;
for (ii = 2; ii < argc; ii++) {
if (!strncmp("-OO", argv[ii], (size_t) 3) || !strncmp("-O", argv[ii], (size_t) 2)) {
if (ii == ( argc - 1 )) {
std::cerr << "\nERROR: No directory specified after -O or -OO argument" << std::endl ;
exit(1) ;
}
/* Output data directory */
output_dir = user_output_dir = argv[++ii];
}
}
/* Create output directory if necessary. */
if (access(output_dir.c_str(), F_OK) != 0) {
if (mkdir(output_dir.c_str(), 0775) == -1) {
std::cerr << "\nERROR: While trying to create output directory \"" << output_dir << "\" : " << std::strerror(errno) << std::endl ;
exit(1) ;
}
} else {
/* check permissions on output directory */
if (access(output_dir.c_str(), (W_OK|X_OK) ) == -1) {
std::cerr << "\nERROR: while writing to output directory \"" << output_dir << "\" : " << std::strerror(errno) << std::endl ;
exit(2) ;
}
}
}
return(0) ;
}
/**
@design
-# Get the current system date and time.
-# Set the subdirectory within the current output directory to
DATA_<year>_<month>_<day>_<hour>_<minute>_<second>
-# Attempt to create the output directory if it does not exist.
-# Exit if the simulation cannot be created.
*/
int Trick::CommandLineArguments::output_dir_timestamped_on() {
time_t date ;
struct tm *curr_time ;
char temp_str[256] ;
date = time(NULL) ;
curr_time = localtime(&date) ;
sprintf(temp_str, "DATA_%4d_%02d_%02d_%02d_%02d_%02d",
curr_time->tm_year + 1900 , curr_time->tm_mon + 1 , curr_time->tm_mday,
curr_time->tm_hour , curr_time->tm_min , curr_time->tm_sec );
time_stamp_dir = std::string(temp_str) ;
if ( ! user_output_dir.empty() ) {
output_dir = user_output_dir + "/" + time_stamp_dir ;
} else {
output_dir = run_dir + "/" + time_stamp_dir ;
}
/* Create directories if necessary. */
if (access(output_dir.c_str(), F_OK) != 0) {
if (mkdir(output_dir.c_str(), 0775) == -1) {
std::cerr << "\nERROR: While trying to create dir \"" << output_dir << "\" Exiting!" << std::endl ;
exit(1) ;
}
}
output_dir_timestamped = 1 ;
return(0) ;
}
/**
@design
-# If the user had specified an output directory reset
the output directory to the user specified directory
-# Else set the output directory to the run directory.
*/
int Trick::CommandLineArguments::output_dir_timestamped_off() {
if ( ! user_output_dir.empty() ) {
output_dir = user_output_dir ;
} else {
output_dir = run_dir ;
}
output_dir_timestamped = 0 ;
return(0) ;
}
/**
@design
-# Sets the value of output_dir
*/
void Trick::CommandLineArguments::set_output_dir(std::string output_directory) {
output_dir = output_directory;
}