mirror of
https://github.com/nasa/trick.git
synced 2025-01-31 00:24:03 +00:00
Merge branch 'master' of https://github.com/nasa/trick
This commit is contained in:
commit
2e4034d9e6
@ -9,3 +9,5 @@ Link documentation for Trick internals, processes, and plans here.
|
||||
- [Testing](Testing)
|
||||
- [How to make a new Trick release on GitHub](How-To-Make-A-Release)
|
||||
- [Tooling and Sanitizers](Tooling-and-Sanitizers)
|
||||
- [Python Environment](Python-Environment-Issues)
|
||||
|
||||
|
57
docs/developer_docs/Python-Environment-Issues.md
Normal file
57
docs/developer_docs/Python-Environment-Issues.md
Normal file
@ -0,0 +1,57 @@
|
||||
| [Home](/trick) → [Developer Docs](Developer-Docs-Home) → Python Environment Issues |
|
||||
|------------------------------------------------------------------|
|
||||
|
||||
# Python Environment in Trick
|
||||
|
||||
In the `./configure` step, Trick finds the Python environment that is used as the embedded interpreter to execute input files and events.
|
||||
|
||||
The configure script first tries to find the Python executable and the python<version>-config script. If the `--with-python=[DIR]` option is used, it will only look in that given directory. Otherwise, it will use the system path. The python<version>-config script is used to find the location of Python.h, installed python libraries, etc.
|
||||
|
||||
## Help! The packages that I installed with pip are not being found by my Trick input files!
|
||||
|
||||
This often happens when a machine has multiple Python installations, particularly on Mac with brew python vs system python. To debug this:
|
||||
|
||||
Find where the `python` and `pip` (or `python3` and `pip3`) symlinks are – this is the version that Trick will pick up unless you have specified something else using the `--with-python=<directory>` configure option.
|
||||
|
||||
```
|
||||
which python3
|
||||
which pip
|
||||
```
|
||||
|
||||
These should match. cd into that directory. It was `/usr/local/bin` for me, which is the default Brew install directory for python.
|
||||
|
||||
Read the path for the symlinks for `python3`, `pip3`, and `python3-config` (or whichever preferred version). These paths should match as well, but often this is the problem.
|
||||
|
||||
```
|
||||
readlink python3
|
||||
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3
|
||||
readlink pip3
|
||||
/usr/local/Cellar/python@3.11/3.11.3/bin/pip3
|
||||
```
|
||||
|
||||
Brew is supposed to be able to detect problems like this with `brew doctor`. Mine detected that `python3.11` was unlinked:
|
||||
|
||||
```
|
||||
Warning: You have unlinked kegs in your Cellar.
|
||||
Leaving kegs unlinked can lead to build-trouble and cause formulae that depend on
|
||||
those kegs to fail to run properly once built. Run `brew link` on these:
|
||||
python@3.11
|
||||
```
|
||||
|
||||
Run with the `--overwrite` flag:
|
||||
|
||||
```
|
||||
brew link --overwrite python@3.11
|
||||
```
|
||||
|
||||
Running readlink should now show the correct Brew install (the one with Cellar in the path) for all the Python executables.
|
||||
|
||||
Trick will search for the python3 and python3-config executables first on the user provided directory (if given) --with-python=<directory> and then along the system path. It then uses python3-config to find installed modules and the CPython headers and libraries. Trick assumes that these symlinks point to the same Python install, and when this assumption is violated it can cause problems with finding pip installed libaries.
|
||||
|
||||
This is a common problem for systems with multiple Python installs, particularly for Macs with Brew python and Xcode python. Another option is just to completely remove the Python install in /Library/Frameworks/Python.framework.
|
||||
|
||||
Helpful links:
|
||||
|
||||
https://faun.pub/the-right-way-to-set-up-python-on-your-mac-e923ffe8cf8e
|
||||
|
||||
https://stackoverflow.com/questions/5157678/how-do-i-use-brew-installed-python-as-the-default-python
|
@ -11,7 +11,7 @@ Trick requires various free third party utilities in order to function. All the
|
||||
|---------------:|:-------:|:-----------------------:|:---------------------------------------------------------:|:------------------------------------------------------|
|
||||
| [gcc] and g++ | 4.8+ | C/C++ Compiler | Compiles Trick and Trick simulations. | |
|
||||
| [clang]/[llvm] | <=14 | C/C++ Compiler | Utilized by the interface code generator. | Trick Versions <= 19.3 should use LLVM <= 9 |
|
||||
| [python] | 2.7+ | Programming Language | Lets the user interact with a simulation. | Trick has been tested up to python 3.9 as of 02/21 |
|
||||
| [python] | 2.7+ | Programming Language | Lets the user interact with a simulation. | Trick has been tested up to python 3.11 as of 04/23 |
|
||||
| [perl] | 5.6+ | Programming Language | Allows executable scripts in the bin directory to run. | |
|
||||
| [java] | 11+ | Programming Language | Necessary for Trick GUIs. | |
|
||||
| [swig] | 2.x-3.x | Language Interfacing | Connects the python input processor with Trick's C code. | 3.0+ required for some unit tests in make test target. SWIG 4.x is compatible with Trick, but has some issues https://github.com/nasa/trick/issues/1288 |
|
||||
|
@ -12,6 +12,7 @@ S_main_${TRICK_HOST_CPU}.exe [trick_version] [sie]
|
||||
RUN_<name>/<input_file_name> [-d]
|
||||
[-O <output_file_path>]
|
||||
[-OO <output_file_path>]
|
||||
[--read-only-sim]
|
||||
[-u <user_defined_arguments>]
|
||||
```
|
||||
|
||||
@ -21,6 +22,7 @@ S_main_${TRICK_HOST_CPU}.exe [trick_version] [sie]
|
||||
- The '-d' argument is optional and, if specified, starts the simulation in an input file verification mode. In this mode the entire input file is read, echoed to standard out, and then the simulation exits without calling any jobs listed in the S_define file. This mode helps debug input file syntax errors.
|
||||
- The '-O <output_file_path>' option allows the user to specify the directory to which simulation data log files will be written. If this option is omitted, the RUN_<name> directory is used.
|
||||
- The '-OO <output_file_path>' option allows the user to specify the directory to which ALL simulation output files will be written. If this option is omitted, the RUN_<name> directory is used.
|
||||
- The '--read-only-sim' flag can be used to redirect all files written at simulation runtime into the output directory.
|
||||
- The '-u' option specifies that all remaining arguments are meant to be used by user supplied jobs. All arguments after the -u can be accessed internal to the simulation jobs by calling the get_cmnd_args() function of the executive as illustrated below. In a master/slave simulation, the master's -u args will be passed to the slave.
|
||||
|
||||
The following code example shows how a function can access the command line arguments during execution.
|
||||
|
@ -71,7 +71,12 @@ MathWorks developed a package to generate Trick friendly code from their models.
|
||||
<a name="coreflightsoftware"></a>
|
||||
|
||||
### Core Flight Software (CFS)
|
||||
Trick and CFS can work together, but the software interfacing Trick and CFS is neither actively maintained nor open source.
|
||||
|
||||
cFS support for Trick is provided by the following external projects:
|
||||
|
||||
* [TVS-IO](https://github.com/nasa/tvsio) is an open-source, Core Flight Software (cFS) application that provides for two-way communication between a **cFS** Software Bus Network (SBN) and a Trick simulation.
|
||||
|
||||
* Another soon to be released capability, presumably called TrickCFS should also be available soon as open-source software. Stay-tuned.
|
||||
|
||||
<a name="ifoundabugwithtrickhowdoitellsomeone"></a>
|
||||
|
||||
|
@ -139,6 +139,9 @@ namespace Trick {
|
||||
*/
|
||||
void set_output_dir(std::string output_directory) ;
|
||||
|
||||
// Helper method to create full path
|
||||
static int create_path(const std::string& dirname);
|
||||
|
||||
} ;
|
||||
|
||||
}
|
||||
|
@ -43,9 +43,11 @@ namespace Trick {
|
||||
void sie_print_json() ;
|
||||
void sie_append_runtime_objs() ;
|
||||
void runtime_objects_print(std::fstream & sie_out) ;
|
||||
std::string get_runtime_sie_dir();
|
||||
|
||||
private:
|
||||
|
||||
// These are called at trick-cp time
|
||||
void top_level_objects_print(std::ofstream & sie_out) ;
|
||||
void top_level_objects_json(std::ofstream & sie_out) ;
|
||||
|
||||
@ -53,6 +55,8 @@ namespace Trick {
|
||||
Trick::AttributesMap * class_attr_map ; /* ** -- This is be ignored by ICG */
|
||||
Trick::EnumAttributesMap * enum_attr_map ; /* ** -- This is be ignored by ICG */
|
||||
|
||||
bool move_runtime_generation;
|
||||
|
||||
} ;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ void sie_class_attr_map_print_xml(void) ;
|
||||
void sie_enum_attr_map_print_xml(void) ;
|
||||
void sie_top_level_objects_print_xml(void) ;
|
||||
void sie_append_runtime_objs(void) ;
|
||||
std::string sie_get_runtime_sie_dir(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -229,6 +229,7 @@ class SieSimObject : public Trick::SimObject {
|
||||
Trick::Sie sie ;
|
||||
|
||||
SieSimObject() {
|
||||
{TRK} P0 ("default_data") sie.process_sim_args() ;
|
||||
// We now append runtime objects when sie is requested by variable server instead.
|
||||
// {TRK} P65535 ("initialization") sie.sie_append_runtime_objs() ;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ monte_carlo.mc_master.add_variable(mc_var)
|
||||
|
||||
|
||||
# give some crazy initial values to the class
|
||||
mc_var = trick.MonteCarloVariableRandomNormal( "test.x_normal_trunc[1]", 99565644453, 10, 3.5)
|
||||
mc_var = trick.MonteCarloVariableRandomNormal( "test.x_normal_trunc[1]", 995656444, 10, 3.5)
|
||||
mc_var.thisown = False
|
||||
# give very small truncate_low distrubution value
|
||||
mc_var.truncate_low(0.1)
|
||||
@ -43,7 +43,7 @@ monte_carlo.mc_master.add_variable(mc_var)
|
||||
|
||||
|
||||
# give some crazy initial values to the class
|
||||
mc_var = trick.MonteCarloVariableRandomNormal( "test.x_normal_trunc[2]", 99565644453, 10, 3.5)
|
||||
mc_var = trick.MonteCarloVariableRandomNormal( "test.x_normal_trunc[2]", 995656444, 10, 3.5)
|
||||
mc_var.thisown = False
|
||||
# give negative truncate_high distrubution value
|
||||
mc_var.truncate_high(-50.2)
|
||||
|
9
test/SIM_test_output_dir/.gitignore
vendored
Normal file
9
test/SIM_test_output_dir/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.trick
|
||||
MONTE_RUN_*
|
||||
*log.csv
|
||||
S_main*
|
||||
*.resource
|
||||
S_source.hh
|
||||
build
|
||||
makefile
|
||||
trick.zip
|
7
test/SIM_test_output_dir/RUN_test/input.py
Normal file
7
test/SIM_test_output_dir/RUN_test/input.py
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
trick.stop(15.0);
|
||||
# trick.real_time_enable()
|
||||
# trick.sim_control_panel_set_enabled(True)
|
||||
|
||||
trick.sie_append_runtime_objs()
|
34
test/SIM_test_output_dir/S_define
Normal file
34
test/SIM_test_output_dir/S_define
Normal file
@ -0,0 +1,34 @@
|
||||
/************************TRICK HEADER*************************
|
||||
PURPOSE:
|
||||
()
|
||||
LIBRARY DEPENDENCIES:
|
||||
*************************************************************/
|
||||
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "starter.h"
|
||||
|
||||
class StarterSimObject : public Trick::SimObject {
|
||||
|
||||
public:
|
||||
Starter starter;
|
||||
|
||||
StarterSimObject() {
|
||||
("default_data") trick_ret = starter.default_data();
|
||||
("initialization") trick_ret = starter.init();
|
||||
(5.0, "scheduled") trick_ret = starter.scheduled();
|
||||
("shutdown") starter.shutdown();
|
||||
// ("derivative") trick_ret = starter.deriv();
|
||||
// ("integration") trick_ret = starter.integ();
|
||||
}
|
||||
};
|
||||
|
||||
StarterSimObject starterSimObject;
|
||||
|
||||
IntegLoop integLoop (0.01) starterSimObject;
|
||||
/*
|
||||
void create_connections() {
|
||||
integLoop.getIntegrator(Runge_Kutta_4, <NUMBER_OF_VARIABLES>);
|
||||
}
|
||||
*/
|
||||
|
8
test/SIM_test_output_dir/S_overrides.mk
Normal file
8
test/SIM_test_output_dir/S_overrides.mk
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
TRICK_CFLAGS += -I./models
|
||||
TRICK_CXXFLAGS += -I./models
|
||||
|
||||
clean: output_clean
|
||||
|
||||
output_clean:
|
||||
rm -rf sim_output
|
44
test/SIM_test_output_dir/models/dynamic_obj.h
Normal file
44
test/SIM_test_output_dir/models/dynamic_obj.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*************************************************************************
|
||||
PURPOSE: (A sim object that is allocated at runtime)
|
||||
LIBRARY DEPENDENCY:
|
||||
(
|
||||
)
|
||||
**************************************************************************/
|
||||
|
||||
#include "sim_services/SimObject/include/SimObject.hh"
|
||||
|
||||
class DynamicObj : public Trick::SimObject {
|
||||
// This class should be allocated dynamically
|
||||
public:
|
||||
DynamicObj() {}
|
||||
int doSomething () {
|
||||
// Do something that we can test for here i guess
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls all jobs that are not "dynamic_event" class
|
||||
* @param curr_job - the current job instance
|
||||
* @return always 0
|
||||
*/
|
||||
virtual int call_function( Trick::JobData * curr_job ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls all jobs that are "dynamic_event" class
|
||||
* @param curr_job - the current job instance
|
||||
* @return always 0
|
||||
*/
|
||||
virtual double call_function_double( Trick::JobData * curr_job ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int a;
|
||||
std::string b;
|
||||
double * c;
|
||||
|
||||
|
||||
};
|
||||
|
66
test/SIM_test_output_dir/models/starter.cpp
Normal file
66
test/SIM_test_output_dir/models/starter.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include <cstdio>
|
||||
#include "starter.h"
|
||||
#include "trick/integrator_c_intf.h"
|
||||
#include "trick/exec_proto.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/mm_macros.hh"
|
||||
|
||||
Starter::Starter() {
|
||||
|
||||
}
|
||||
|
||||
int Starter::default_data() {
|
||||
// Allocate a dynamic object
|
||||
DynamicObj * obj = new DynamicObj() ;
|
||||
obj->a = 5;
|
||||
obj->b = "Hello world!";
|
||||
obj->c = (double *) malloc (sizeof(double) * 3);
|
||||
obj->c[0] = 0.0;
|
||||
obj->c[1] = 1.0;
|
||||
obj->c[2] = 2.0;
|
||||
|
||||
TMM_declare_ext_var(obj, TRICK_STRUCTURED,"DynamicObj", 0, "DynamicObj_alloc", 0, NULL) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Starter::init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Starter::scheduled() {
|
||||
message_publish(MSG_NORMAL, "Hello World!\n");
|
||||
return 0;
|
||||
}
|
||||
int Starter::deriv() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Starter::integ() {
|
||||
|
||||
int ipass;
|
||||
load_state(
|
||||
NULL /* list is NULL terminated */
|
||||
);
|
||||
|
||||
/* LOAD THE POSITION AND VELOCITY STATE DERIVATIVES */
|
||||
load_deriv(
|
||||
NULL /* list is NULL terminated */
|
||||
);
|
||||
|
||||
/* Call the Trick integrate service */
|
||||
ipass = integrate();
|
||||
|
||||
/* unload new state */
|
||||
unload_state(
|
||||
NULL /* list is NULL terminated */
|
||||
);
|
||||
|
||||
/* returns 0 if integerate() was successful */
|
||||
return ipass;
|
||||
}
|
||||
|
||||
int Starter::shutdown() {
|
||||
return 0;
|
||||
}
|
21
test/SIM_test_output_dir/models/starter.h
Normal file
21
test/SIM_test_output_dir/models/starter.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*************************************************************************
|
||||
PURPOSE: (Starter class)
|
||||
LIBRARY DEPENDENCY:
|
||||
(
|
||||
(starter.cpp)
|
||||
)
|
||||
**************************************************************************/
|
||||
|
||||
#include "dynamic_obj.h"
|
||||
|
||||
class Starter {
|
||||
public:
|
||||
Starter();
|
||||
int default_data();
|
||||
int init();
|
||||
int scheduled();
|
||||
int deriv();
|
||||
int integ();
|
||||
int shutdown();
|
||||
|
||||
};
|
20
test/SIM_test_output_dir/ref_files/check_file_endings.py
Normal file
20
test/SIM_test_output_dir/ref_files/check_file_endings.py
Normal file
@ -0,0 +1,20 @@
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print ("Usage: check_file_endings.py <ref_file> <cmp_file>")
|
||||
exit(1)
|
||||
|
||||
ref_file = sys.argv[1]
|
||||
cmp_file = sys.argv[2]
|
||||
|
||||
ref_lines = reversed(list(open(ref_file)))
|
||||
cmp_lines = reversed(list(open(cmp_file)))
|
||||
|
||||
for ref_line, cmp_line in zip(ref_lines, cmp_lines):
|
||||
if (ref_line != cmp_line):
|
||||
print("Difference in files: ", ref_line, "vs", cmp_line)
|
||||
exit(1)
|
||||
|
||||
print("Success!")
|
||||
exit(0)
|
||||
|
@ -0,0 +1,5 @@
|
||||
<!--
|
||||
Runtime Allocations
|
||||
Do not edit this comment or file content past this point
|
||||
-->
|
||||
</sie>
|
@ -0,0 +1,35 @@
|
||||
<!--
|
||||
Runtime Allocations
|
||||
Do not edit this comment or file content past this point
|
||||
-->
|
||||
<top_level_object
|
||||
name="DynamicObj_alloc"
|
||||
type="DynamicObj"
|
||||
alloc_memory_init="0">
|
||||
</top_level_object>
|
||||
|
||||
<top_level_object
|
||||
name="trick_frame"
|
||||
type="Trick__FrameDataRecordGroup"
|
||||
alloc_memory_init="0">
|
||||
</top_level_object>
|
||||
|
||||
<top_level_object
|
||||
name="trick_frame_trick_jobs"
|
||||
type="Trick__FrameDataRecordGroup"
|
||||
alloc_memory_init="0">
|
||||
</top_level_object>
|
||||
|
||||
<top_level_object
|
||||
name="trick_frame_userjobs_main"
|
||||
type="Trick__FrameDataRecordGroup"
|
||||
alloc_memory_init="0">
|
||||
</top_level_object>
|
||||
|
||||
<top_level_object
|
||||
name="trick_injector_executor_0"
|
||||
type="InjectorExecSimObject"
|
||||
alloc_memory_init="0">
|
||||
</top_level_object>
|
||||
|
||||
</sie>
|
@ -284,6 +284,18 @@ SIM_events:
|
||||
returns: 255
|
||||
|
||||
|
||||
|
||||
SIM_test_output_dir:
|
||||
path: test/SIM_test_output_dir
|
||||
build_args: "-t"
|
||||
binary: "T_main_{cpu}_test.exe"
|
||||
runs:
|
||||
RUN_test/input.py -OO sim_output --read-only-sim:
|
||||
returns: 0
|
||||
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_compiletime_S_sie.resource test/SIM_test_output_dir/S_sie.resource'
|
||||
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_runtime_S_sie.resource test/SIM_test_output_dir/sim_output/S_sie.resource'
|
||||
|
||||
|
||||
# The variable server client and SIM_amoeba sometimes fail to connect and need to be retried
|
||||
SIM_test_varserv:
|
||||
path: test/SIM_test_varserv
|
||||
|
@ -20,6 +20,9 @@
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "trick/CommandLineArguments.hh"
|
||||
#include "trick/memorymanager_c_intf.h"
|
||||
@ -84,6 +87,54 @@ std::string & Trick::CommandLineArguments::get_cmdline_name_ref() {
|
||||
return(cmdline_name) ;
|
||||
}
|
||||
|
||||
// Helper function - create a full path with error checking along the way
|
||||
int Trick::CommandLineArguments::create_path(const std::string& dirname) {
|
||||
size_t cur_index = 0;
|
||||
|
||||
std::string full_dir (dirname);
|
||||
|
||||
// These syscalls don't seem to take care of home special character, so do it manually
|
||||
// I think the shell should handle it before it gets here, but just in case check for it
|
||||
if (dirname.at(0) == '~') {
|
||||
struct passwd *pw = getpwuid(getuid());
|
||||
full_dir = std::string(pw->pw_dir) + dirname.substr(1, dirname.size());
|
||||
}
|
||||
|
||||
while (cur_index != full_dir.size()) {
|
||||
cur_index = full_dir.find('/', cur_index+1);
|
||||
if (cur_index == std::string::npos) {
|
||||
cur_index = full_dir.size();
|
||||
}
|
||||
std::string cur_dir = full_dir.substr(0, cur_index);
|
||||
|
||||
struct stat info;
|
||||
if(stat( cur_dir.c_str(), &info ) != 0) {
|
||||
// does not exist - make it
|
||||
if (mkdir(cur_dir.c_str(), 0775) == -1) {
|
||||
std::cerr << "Error creating directory " << cur_dir << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
// Does exist
|
||||
if(info.st_mode & S_IFDIR) {
|
||||
// Is a directory
|
||||
if (info.st_mode & S_IWUSR) {
|
||||
// Perfect, nothing to do here
|
||||
} else {
|
||||
// Not writeable
|
||||
std::cerr << "Intermediate directory " << cur_dir << " is not writable, unable to create output directory." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
// Does exist, but is a file
|
||||
std::cerr << "Intermediate directory " << cur_dir << " is not a directory, unable to create output directory." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@details
|
||||
-# Save the number of command line arguments.
|
||||
@ -209,7 +260,7 @@ int Trick::CommandLineArguments::process_sim_args(int nargs , char **args) {
|
||||
|
||||
/* Create output directory if necessary. */
|
||||
if (access(output_dir.c_str(), F_OK) != 0) {
|
||||
if (mkdir(output_dir.c_str(), 0775) == -1) {
|
||||
if (create_path(output_dir) != 0) {
|
||||
std::cerr << "\nERROR: While trying to create output directory \"" << output_dir << "\" : " << std::strerror(errno) << std::endl ;
|
||||
exit(1) ;
|
||||
}
|
||||
|
2
trick_source/sim_services/CommandLineArguments/test/.gitignore
vendored
Normal file
2
trick_source/sim_services/CommandLineArguments/test/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
create_path_test
|
||||
*.o
|
42
trick_source/sim_services/CommandLineArguments/test/Makefile
Normal file
42
trick_source/sim_services/CommandLineArguments/test/Makefile
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
#SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
include $(dir $(lastword $(MAKEFILE_LIST)))../../../../share/trick/makefiles/Makefile.common
|
||||
|
||||
# Replace -isystem with -I so ICG doesn't skip Trick headers
|
||||
TRICK_SYSTEM_CXXFLAGS := $(subst -isystem,-I,$(TRICK_SYSTEM_CXXFLAGS))
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
TRICK_CXXFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wextra -std=c++11 ${TRICK_SYSTEM_CXXFLAGS} ${TRICK_TEST_FLAGS}
|
||||
|
||||
# so it seems like there's some weirdness linking in the bitfield objects since they are C
|
||||
MM_OBJECTS = $(TRICK_HOME)/trick_source/sim_services/MemoryManager/object_${TRICK_HOST_CPU}/extract_bitfield.o \
|
||||
$(TRICK_HOME)/trick_source/sim_services/MemoryManager/object_${TRICK_HOST_CPU}/extract_unsigned_bitfield.o
|
||||
|
||||
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick_mm -ltrick_units -ltrick -ltrick_mm -ltrick_units -ltrick
|
||||
TRICK_EXEC_LINK_LIBS += -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib -lgtest -lgtest_main -lpthread
|
||||
|
||||
|
||||
# All tests produced by this Makefile. Remember to add new tests you
|
||||
# created to the list.
|
||||
TESTS = create_path_test
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
all : $(TESTS)
|
||||
|
||||
test: $(TESTS)
|
||||
./create_path_test --gtest_output=xml:${TRICK_HOME}/trick_test/create_path_test.xml
|
||||
|
||||
clean :
|
||||
rm -f $(TESTS) *.o *.gcno *.gcda
|
||||
|
||||
create_path_test.o : create_path_test.cpp
|
||||
$(TRICK_CXX) $(TRICK_CXXFLAGS) -c $<
|
||||
|
||||
create_path_test : create_path_test.o $(MM_OBJECTS)
|
||||
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
|
@ -0,0 +1,99 @@
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "trick/CommandLineArguments.hh"
|
||||
|
||||
namespace Trick {
|
||||
|
||||
|
||||
// Clean up the directory created
|
||||
void rm_dir(const std::string& dir) {
|
||||
const int result = remove( dir.c_str() );
|
||||
if( result != 0 && errno == 66){
|
||||
// Failed because directory is not empty
|
||||
// Remove stuff and try again
|
||||
DIR *temp_dir;
|
||||
struct dirent *ent;
|
||||
if ((temp_dir = opendir (dir.c_str())) != NULL) {
|
||||
// Go through everything in this directory
|
||||
while ((ent = readdir (temp_dir)) != NULL) {
|
||||
if (!(strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0 )) {
|
||||
// remove it
|
||||
rm_dir(dir + "/" + std::string(ent->d_name));
|
||||
}
|
||||
}
|
||||
closedir (temp_dir);
|
||||
}
|
||||
|
||||
// Try again
|
||||
remove( dir.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
bool dir_correct(const std::string& dir) {
|
||||
// Make sure that the directory exists and is writeable
|
||||
struct stat info;
|
||||
if(stat( dir.c_str(), &info ) == 0) {
|
||||
if (info.st_mode & S_IFDIR && info.st_mode & S_IWUSR ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TEST(CreatePathTest, BasicTest) {
|
||||
std::string dir = "a/b/c";
|
||||
ASSERT_EQ(CommandLineArguments::create_path(dir), 0);
|
||||
ASSERT_TRUE(dir_correct(dir));
|
||||
|
||||
rm_dir("a");
|
||||
}
|
||||
|
||||
TEST(CreatePathTest, PreExistingDir) {
|
||||
std::string dir = "pre_existing_output_dir";
|
||||
ASSERT_EQ(CommandLineArguments::create_path(dir), 0);
|
||||
ASSERT_TRUE(dir_correct(dir));
|
||||
}
|
||||
|
||||
TEST(CreatePathTest, PreExistingInPath) {
|
||||
std::string dir = "pre_existing_output_dir/a/b/c";
|
||||
ASSERT_EQ(CommandLineArguments::create_path(dir), 0);
|
||||
ASSERT_TRUE(dir_correct(dir));
|
||||
|
||||
rm_dir("pre_existing_output_dir/a");
|
||||
}
|
||||
|
||||
TEST(CreatePathTest, FileInPath) {
|
||||
std::string dir = "pre_existing_output_dir/some_file/a";
|
||||
ASSERT_EQ(CommandLineArguments::create_path(dir), 1);
|
||||
}
|
||||
|
||||
|
||||
TEST(CreatePathTest, AbsolutePath) {
|
||||
char buf[1024];
|
||||
getcwd(buf, 1024);
|
||||
std::string dir = std::string(buf) + "/a/b/c";
|
||||
ASSERT_EQ(CommandLineArguments::create_path(dir), 0);
|
||||
ASSERT_TRUE(dir_correct(dir));
|
||||
|
||||
rm_dir(std::string(buf) + std::string("/a"));
|
||||
}
|
||||
|
||||
TEST(CreatePathTest, dotdotinpath) {
|
||||
std::string dir = "../a/b/c";
|
||||
ASSERT_EQ(CommandLineArguments::create_path(dir), 0);
|
||||
ASSERT_TRUE(dir_correct(dir));
|
||||
|
||||
rm_dir("../a");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -22,6 +22,8 @@ Trick::Sie::Sie() {
|
||||
class_attr_map = Trick::AttributesMap::attributes_map() ;
|
||||
enum_attr_map = Trick::EnumAttributesMap::attributes_map() ;
|
||||
|
||||
move_runtime_generation = false;
|
||||
|
||||
the_sie = this ;
|
||||
}
|
||||
|
||||
@ -43,10 +45,17 @@ int Trick::Sie::process_sim_args() {
|
||||
// Silently exit the sim without printing the termination message
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
// Otherwise, go through the rest of the sim args and look for --read-only-sim
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("--read-only-sim", argv[i]) == 0) {
|
||||
// Set this flag to move runtime generation of sie into the output directory
|
||||
move_runtime_generation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
|
||||
}
|
||||
|
||||
void Trick::Sie::top_level_objects_print(std::ofstream & sie_out) {
|
||||
@ -136,10 +145,9 @@ void Trick::Sie::top_level_objects_json(std::ofstream & sie_out) {
|
||||
sie_out << " ]\n";
|
||||
}
|
||||
|
||||
|
||||
void Trick::Sie::sie_print_xml() {
|
||||
std::ofstream sie_out ;
|
||||
std::string file_name = std::string(command_line_args_get_default_dir()) + "/" + "S_sie.resource" ;
|
||||
std::string file_name = std::string(get_runtime_sie_dir()) + "/" + "S_sie.resource" ;
|
||||
sie_out.open(file_name.c_str()) ;
|
||||
sie_out << "<?xml version=\"1.0\"?>\n\n" ;
|
||||
sie_out << "<sie>\n\n" ;
|
||||
@ -150,10 +158,31 @@ void Trick::Sie::sie_print_xml() {
|
||||
sie_out.close() ;
|
||||
}
|
||||
|
||||
void copy_file (const std::string& original_filename, const std::string& copy_filename) {
|
||||
std::ifstream original;
|
||||
std::ofstream copy;
|
||||
|
||||
original.open(original_filename.c_str(), std::ios::binary);
|
||||
copy.open(copy_filename.c_str(), std::ios::binary);
|
||||
|
||||
copy << original.rdbuf();
|
||||
|
||||
original.close();
|
||||
copy.close();
|
||||
}
|
||||
|
||||
void Trick::Sie::sie_append_runtime_objs() {
|
||||
std::fstream sie_out ;
|
||||
std::string file_name = std::string(command_line_args_get_default_dir()) + "/" + "S_sie.resource" ;
|
||||
sie_out.open(file_name.c_str(), std::fstream::in | std::fstream::out) ;
|
||||
|
||||
if (move_runtime_generation) {
|
||||
std::string original_sie_filename = std::string(command_line_args_get_default_dir()) + "/" + "S_sie.resource" ;
|
||||
std::string copy_sie_filename = std::string(command_line_args_get_output_dir()) + "/" + "S_sie.resource" ;
|
||||
copy_file(original_sie_filename, copy_sie_filename);
|
||||
}
|
||||
|
||||
std::string sie_filename = get_runtime_sie_dir() + "/" + "S_sie.resource" ;
|
||||
|
||||
sie_out.open(sie_filename.c_str(), std::fstream::in | std::fstream::out) ;
|
||||
sie_out.seekg(-1, sie_out.end);
|
||||
const char * comment = "<!--\nRuntime Allocations\nDo not edit this comment or file content past this point\n-->\n";
|
||||
const int commentLength = 86;
|
||||
@ -180,9 +209,17 @@ void Trick::Sie::sie_append_runtime_objs() {
|
||||
sie_out.close();
|
||||
}
|
||||
|
||||
std::string Trick::Sie::get_runtime_sie_dir() {
|
||||
if (move_runtime_generation) {
|
||||
return std::string(command_line_args_get_output_dir()) ;
|
||||
} else {
|
||||
return std::string(command_line_args_get_default_dir()) ;
|
||||
}
|
||||
}
|
||||
|
||||
void Trick::Sie::sie_print_json() {
|
||||
std::ofstream sie_out ;
|
||||
std::string file_name = std::string(command_line_args_get_default_dir()) + "/" + "S_sie.json" ;
|
||||
std::string file_name = std::string(get_runtime_sie_dir()) + "/" + "S_sie.json" ;
|
||||
sie_out.open(file_name.c_str()) ;
|
||||
sie_out << "{\n" ;
|
||||
class_attr_map->print_json(sie_out) ;
|
||||
@ -195,7 +232,7 @@ void Trick::Sie::sie_print_json() {
|
||||
|
||||
void Trick::Sie::class_attr_map_print_xml() {
|
||||
std::ofstream sie_out ;
|
||||
std::string file_name = std::string(command_line_args_get_default_dir()) + "/" + "S_sie_class.xml" ;
|
||||
std::string file_name = std::string(get_runtime_sie_dir()) + "/" + "S_sie_class.xml" ;
|
||||
sie_out.open(file_name.c_str()) ;
|
||||
sie_out << "<?xml version=\"1.0\"?>\n\n" ;
|
||||
sie_out << "<sie>\n" ;
|
||||
@ -206,7 +243,7 @@ void Trick::Sie::class_attr_map_print_xml() {
|
||||
|
||||
void Trick::Sie::enum_attr_map_print_xml() {
|
||||
std::ofstream sie_out ;
|
||||
std::string file_name = std::string(command_line_args_get_default_dir()) + "/" + "S_sie_enum.xml" ;
|
||||
std::string file_name = std::string(get_runtime_sie_dir()) + "/" + "S_sie_enum.xml" ;
|
||||
sie_out.open(file_name.c_str()) ;
|
||||
sie_out << "<?xml version=\"1.0\"?>\n\n" ;
|
||||
sie_out << "<sie>\n" ;
|
||||
@ -217,7 +254,7 @@ void Trick::Sie::enum_attr_map_print_xml() {
|
||||
|
||||
void Trick::Sie::top_level_objects_print_xml() {
|
||||
std::ofstream sie_out ;
|
||||
std::string file_name = std::string(command_line_args_get_default_dir()) + "/" + "S_sie_top_level_objects.xml" ;
|
||||
std::string file_name = std::string(get_runtime_sie_dir()) + "/" + "S_sie_top_level_objects.xml" ;
|
||||
sie_out.open(file_name.c_str()) ;
|
||||
sie_out << "<?xml version=\"1.0\"?>\n\n" ;
|
||||
sie_out << "<sie>\n" ;
|
||||
|
@ -33,3 +33,10 @@ extern "C" void sie_append_runtime_objs(void) {
|
||||
the_sie->sie_append_runtime_objs() ;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" std::string sie_get_runtime_sie_dir(void) {
|
||||
if ( the_sie != NULL ) {
|
||||
return the_sie->get_runtime_sie_dir() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,20 +497,20 @@ int Trick::VariableServerThread::send_file(std::string file_name) {
|
||||
|
||||
int Trick::VariableServerThread::send_sie_resource() {
|
||||
sie_append_runtime_objs() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/S_sie.resource") ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/S_sie.resource") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_sie_class() {
|
||||
sie_class_attr_map_print_xml() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_class.xml") ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/" + "S_sie_class.xml") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_sie_enum() {
|
||||
sie_enum_attr_map_print_xml() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_enum.xml") ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/" + "S_sie_enum.xml") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_sie_top_level_objects() {
|
||||
sie_top_level_objects_print_xml() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_top_level_objects.xml") ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/" + "S_sie_top_level_objects.xml") ;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user