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

nasa / trick / 9699499942

27 Jun 2024 03:34PM UTC coverage: 55.827% (-0.01%) from 55.839%
9699499942

push

github

web-flow
Corrected .d file path for the clean target in Makefile.input file. (#1735)

0 of 1 new or added line in 1 file covered. (0.0%)

4 existing lines in 2 files now uncovered.

12264 of 21968 relevant lines covered (55.83%)

72591.94 hits per line

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

18.92
/trick_source/sim_services/JITInputFile/JITInputFile.cpp
1

2
#include <iostream>
3
#include <fstream>
4
#include <sstream>
5
#include <cstring>
6
#include <string>
7

8
#include <string.h>
9
#include <dlfcn.h>
10
#include <stdlib.h>
11
#include <sys/types.h>
12
#include <sys/stat.h>
13
#include <unistd.h>
14
#include <errno.h>
15

16

17
#include "trick/JITInputFile.hh"
18
#include "trick/command_line_protos.h"
19
#include "trick/message_type.h"
20
#include "trick/message_proto.h"
21
#include "trick/env_proto.h"
22
#include "trick/exec_proto.h"
23
#include "trick/exec_proto.hh"
24
#include "trick/TrickConstant.hh"
25

26
Trick::JITInputFile * the_jit = NULL ;
27

28
//TODO: Move JITLibInfo code into the JITLibInfo object.
29

30
Trick::JITInputFile::JITInputFile() {
177✔
31
    the_jit = this ;
177✔
32

33
    JITLibInfo li ;
177✔
34
    li.library_name = "S_main" ;
177✔
35
    li.handle = dlopen( NULL , RTLD_LAZY ) ;
177✔
36
    file_to_libinfo_map["S_main"] = li ;
177✔
37

38
}
177✔
39

40
/**
41
@details
42
-# Test if the input file on the command line ends in .cpp or .cc
43
-# If it does save the input file locally and clear the command line argument so
44
   the cpp input file will not go through the input processor.
45
*/
46
int Trick::JITInputFile::process_sim_args() {
177✔
47

48
    std::string cpp = ".cpp" ;
354✔
49
    std::string cc = ".cc" ;
177✔
50

51
    std::string & ifr = command_line_args_get_input_file_ref() ;
177✔
52
    if ( ! ifr.empty() ) {
177✔
53
        if (! ifr.compare( ifr.length() - cpp.length() , cpp.length(), cpp) or
354✔
54
            ! ifr.compare( ifr.length() -  cc.length() ,  cc.length(),  cc) ) {
177✔
55
            input_file = ifr ;
×
56
            ifr.clear() ;
×
57
        }
58
    }
59

60
    return 0 ;
354✔
61
}
62

63
/**
64
@details
65
-# If the incoming file name has already been successfully compiled, return 0
66
-# Get the basename of the input file
67
-# Get the root name of the input file (no extension)
68
-# Set all of the output file names based on the output directory and the input file root name
69
-# Make the output directory
70
-# Open the makefile for writing
71
-# Create a makefile that will compile the input file to a shared library
72
-# Call make to compile the library file.
73
-# Extract the return status from the system call.
74
-# If the compilation was unsuccessful, exec_terminate
75
-# The library compile successfully.  Add library name to map
76
*/
77
int Trick::JITInputFile::compile(std::string file_name) {
×
78

79
    std::ofstream outfile ;
×
80
    std::ostringstream ss ;
×
81

82
    std::string output_directory ;
×
83
    std::string object_fullpath_name ;
×
84
    std::string library_fullpath_name ;
×
85
    std::string makefile_fullpath_name ;
×
86
    std::string input_file_rootname ;
×
87
    std::string input_file_basename ;
×
88
    std::string dep_file_name ;
×
89
    struct stat output_dir_stat ;
90
    int ret ;
91
    size_t pos ;
92

93
    // If the incoming file name has already been successfully compiled, return now.
94
    if ( file_to_libinfo_map.find(file_name) != file_to_libinfo_map.end() ) {
×
95
        return 0 ;
×
96
    }
97

98
    // get the basename of the input file
99
    if ( (pos = file_name.find_last_of("/")) != std::string::npos ) {
×
100
        input_file_basename = file_name.substr(pos + 1 ) ;
×
101
    } else {
102
        input_file_basename = file_name ;
×
103
    }
104

105
    // get the root name of the input file (no extension)
106
    if ( (pos = input_file_basename.find_last_of(".")) != std::string::npos ) {
×
107
        input_file_rootname = input_file_basename.substr(0, pos) ;
×
108
    } else {
109
        input_file_rootname = input_file_basename ;
×
110
    }
111

112
    // set all of the output file names based on the output directory and the input file root name
113
    output_directory = std::string(command_line_args_get_output_dir()) + "/jitlib" ;
×
114
    makefile_fullpath_name = output_directory + "/Makefile." + input_file_rootname ;
×
115
    object_fullpath_name = output_directory + "/" + input_file_rootname + ".o" ;
×
116
    library_fullpath_name = output_directory + "/lib" + input_file_rootname + ".so" ;
×
117
    dep_file_name = output_directory + "/" + input_file_rootname + ".d" ;
×
118

119
    // make the output directory
120
    ret = stat( output_directory.c_str(), &output_dir_stat) ;
×
121
    if ( ret == -1 and errno == ENOENT ) {
×
122
        mkdir(output_directory.c_str(), 0775) ;
×
123
    } else if ( ret == 0 and ! S_ISDIR(output_dir_stat.st_mode)) {
×
124
        std::string error_message = "JITInputfile could not create directory " + output_directory ;
×
125
        exec_terminate_with_return(-1 , __FILE__ , __LINE__ , error_message.c_str() ) ;
×
126
    }
127

128
    // open the makefile for writing
129
    outfile.open(makefile_fullpath_name.c_str()) ;
×
130

131
    // create a makefile that will compile the input file to a shared library
132
    outfile << "# JITInputFile auto generated Makefile.  Paths are relative to the simulation directory" << std::endl ;
×
133
    outfile << "# To manually use this file go to sim directory and use \"make -f " << makefile_fullpath_name << " <makefile_target>\"" ;
×
134
    outfile << std::endl << std::endl ;
×
135
    // rule to link shared library
136
    outfile << library_fullpath_name << ": " << object_fullpath_name << std::endl ;
×
137
#ifdef __APPLE__
138
    outfile << "\t" << get_trick_env((char *)"TRICK_CXX") << " -shared -undefined dynamic_lookup -o $@ $< " << std::endl << std::endl ;
139
#else
140
    outfile << "\t" << get_trick_env((char *)"TRICK_CXX") << " -shared -o $@ $< " << std::endl << std::endl ;
×
141
#endif
142
    // rule to compile cpp file
143
    outfile << object_fullpath_name << ": " << file_name << std::endl ;
×
144
    outfile << "\t" << get_trick_env((char *)"TRICK_CXX") << " " << get_trick_env((char *)"TRICK_CXXFLAGS") ;
×
145
    outfile << " " << get_trick_env((char *)"TRICK_SYSTEM_CXXFLAGS") ;
×
146
    outfile << " -MMD -c -fPIC -o $@ $<" << std::endl << std::endl ;
×
147
    // rule to clean
148
    outfile << "clean:" << std::endl ;
×
149
    outfile << "\t rm -f " << object_fullpath_name << " " << library_fullpath_name ;
×
NEW
150
    outfile << " " << dep_file_name << std::endl << std::endl ;
×
151
    // dependency file
152
    outfile << "-include " << dep_file_name << std::endl ;
×
153

154
    outfile.close() ;
×
155

156
    // call make to compile the library file.
157
    ss << "make -s -f " << makefile_fullpath_name << std::endl ;
×
158
    ret = system(ss.str().c_str()) ;
×
159

160
    // extract the return status from the system call.
161
    ret = WEXITSTATUS(ret) ;
×
162

163
    // If the compilation was unsuccessful, exec_terminate
164
    if ( ret != 0 ) {
×
165
        std::string error_message = std::string("JITInputFile shared library creation failed: ")
×
166
                                  + std::strerror(errno);
×
167
        exec_terminate_with_return(-1 , __FILE__ , __LINE__ , error_message.c_str());
×
168
    }
169

170
    // The library compile successfully.  Add library name to map
171
    JITLibInfo li ;
×
172
    li.library_name = library_fullpath_name ;
×
173
    file_to_libinfo_map[file_name] = li ;
×
174

175
    return 0 ;
×
176

177
}
178

179
/**
180
@details
181
-# Check if we have compiled this library yet
182
    -# If we have not compiled the library then exec_terminate
183
-# If the library handle is NULL, try and open the library
184
    -# If the library open fails, exec_terminate
185
-# Look up the symbol run_function
186
    -# If the symbol is not found exec_terminate.
187
-# Call the function
188
*/
189
int Trick::JITInputFile::run(std::string file_name , std::string run_function ) {
×
190
    // Check if we have compiled this library yet.
191
    if ( file_to_libinfo_map.find(file_name) == file_to_libinfo_map.end() ) {
×
192
        // If we have not compiled the library then exec_terminate
193
        std::string error_message = "JITInputfile library not found for " + file_name ;
×
194
        exec_terminate_with_return(-1 , __FILE__ , __LINE__ , error_message.c_str() ) ;
×
195
    }
196

197
    JITLibInfo & li = file_to_libinfo_map.find(file_name)->second ;
×
198
    // if the library handle is NULL, try and open the library.
199
    if ( li.handle == NULL ) {
×
200
        li.handle = dlopen( li.library_name.c_str() , RTLD_LAZY ) ;
×
201
        // if the library open fails, exec_terminate
202
        if ( li.handle == NULL ) {
×
203
            std::string error_message = "JITInputfile dlopen failed on " + li.library_name ;
×
204
            exec_terminate_with_return(-1 , __FILE__ , __LINE__ , error_message.c_str() ) ;
×
205
        }
206
    }
207

208
    // Look up the symbol name
209
    int (*call_me)(void) = (int (*)(void))dlsym( li.handle , run_function.c_str()) ;
×
210
    if ( call_me == NULL ) {
×
211
        std::string error_message = "JITInputfile could not find function " + run_function ;
×
212
        return exec_terminate_with_return(-1 , __FILE__ , __LINE__ , error_message.c_str() ) ;
×
213
    } else {
214
        // We found the function, call it!
215
        return (*call_me)() ;
×
216
    }
217
}
218

219
/**
220
@details
221
-# If the file_name is not empty
222
    -# Compile the file_name
223
    -# If the file compiled successfully
224
        -# Execute the run_function
225
*/
226
int Trick::JITInputFile::compile_and_run(std::string file_name, std::string run_function) {
177✔
227

228
    int ret = 0 ;
177✔
229

230
    // If the file name is not empty
231
    if ( ! file_name.empty() ) {
177✔
232
        // Attempt to compile the library.
233
        ret = compile(file_name) ;
×
234
        if ( ret == 0 ) {
×
235
            // If the compilation was successful execute run_function.
236
            ret = run( file_name , run_function ) ;
×
237
        }
238
    }
239

240
    // Return 0 or the return value of compile/run.
241
    return ret ;
177✔
242
}
243

244
/**
245
@details
246
-# If the incoming file name has already been added, return 0
247
-# Add library name to map
248
*/
249
int Trick::JITInputFile::add_library(std::string lib_name) {
×
250

251
    // If the incoming file name has already been added, return 0
252
    if ( file_to_libinfo_map.find(lib_name) != file_to_libinfo_map.end() ) {
×
253
        return 0 ;
×
254
    }
255

256
    // Add library name to map
257
    JITLibInfo li ;
×
258
    li.library_name = lib_name ;
×
259
    li.handle = dlopen( li.library_name.c_str() , RTLD_LAZY ) ;
×
260
    file_to_libinfo_map[lib_name] = li ;
×
261

262
    return 0 ;
×
263
}
264

265
void * Trick::JITInputFile::find_symbol(std::string sym) {
×
266
    std::map< std::string , JITLibInfo >::iterator it ;
×
267
    for ( it = file_to_libinfo_map.begin() ; it != file_to_libinfo_map.end() ; ++it ) {
×
268
        void * ret = (*it).second.find_symbol(sym) ;
×
269
        if (ret != NULL) {
×
270
            return ret ;
×
271
        }
272
    }
273
    return NULL ;
×
274
}
275

276
/**
277
@details
278
-# Call compile_and_run with the input_file from the command line
279
*/
280
int Trick::JITInputFile::init() {
177✔
281
    // Compile and run the input file.  It's ok if input_file is empty.
282
    return compile_and_run(input_file) ;
177✔
283
}
284

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