-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdashrep_compile_run.cpp
More file actions
169 lines (147 loc) · 5.81 KB
/
dashrep_compile_run.cpp
File metadata and controls
169 lines (147 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// dashrep_compile_run.cpp
// -----------------------
//
// Runs shell commands that compile and run a Dashrep program.
//
// Usage:
// g++ -std=c++17 -o dashrep_compile_run dashrep_compile_run.cpp
// ./dashrep_compile_run <parameter> [<compiler_dir>]
//
// <parameter> must contain only letters, digits, and underscores.
//
// <compiler_dir> is an optional path to the directory
// that contains the file: dashrep_compiler_executable.pl
// If omitted, the default path is local.
//
// Assume Dashrep code is in file named
// input_file = "dashrep_" + param + ".txt";
//
// For output files, see code.
//
//---------------------------------------------------
#include <iostream>
#include <string>
#include <cstdlib>
#include <cctype>
#include <filesystem>
#include <fstream>
// Validates that the parameter contains only letters, digits, and underscores.
bool isValidParam(const std::string& param) {
if (param.empty()) {
return false;
}
for (char c : param) {
if (!std::isalpha(static_cast<unsigned char>(c)) &&
!std::isdigit(static_cast<unsigned char>(c)) &&
c != '_') {
return false;
}
}
return true;
}
// Runs a shell command and returns its exit code.
int run(const std::string& cmd) {
int ret = std::system(cmd.c_str());
if (ret != 0) {
std::cout << "Attempted to run: " << cmd << std::endl;
std::cerr << "Warning: command exited with code " << ret
<< ": " << cmd << std::endl;
}
return ret;
}
// Deletes a file.
void delete_file(const std::string& path) {
std::error_code ec;
std::filesystem::remove(path, ec);
// Ignore error
}
// Copies a file.
void copy_file(const std::string& src, const std::string& dst) {
std::error_code ec;
std::filesystem::copy_file(
src, dst,
std::filesystem::copy_options::overwrite_existing,
ec);
if (ec) {
std::cerr << "Error copying " << src << " to " << dst
<< ": " << ec.message() << std::endl;
}
}
// Main code.
int main(int argc, char* argv[]) {
if (argc < 2 || argc > 3) {
std::cerr << "Usage: " << argv[0] << " <parameter> [<compiler_dir>]" << std::endl;
std::cerr << " <parameter> must contain only letters, digits, and underscores." << std::endl;
std::cerr << " <compiler_dir> optional path to directory containing dashrep_compiler_executable.pl" << std::endl;
std::cerr << " (default: ./dashrep_compiler_executable.pl)" << std::endl;
return 1;
}
std::string param(argv[1]);
if (!isValidParam(param)) {
std::cerr << "Error: parameter \"" << param
<< "\" contains invalid characters. "
<< "Only letters, digits, and underscores are allowed." << std::endl;
return 1;
}
std::string compiler_dir = (argc == 3) ? std::string(argv[2]) : ".";
// Ensure no trailing slash before appending filename
if (!compiler_dir.empty() && compiler_dir.back() == '/') {
compiler_dir.pop_back();
}
std::string name_of_temporary_file;
// Build filenames.
std::string input_file = "dashrep_" + param + ".txt";
std::string output_trace_from_compiler = "output_trace_from_dashrep_compiler_" + param + ".txt";
std::string compiled_runtime_program = "output_compiled_dashrep_program_" + param + ".pl";
std::string output_trace = "output_trace_" + param + ".txt";
std::string compiler_log = "output_log_from_dashrep_compiler_" + param + ".txt";
std::string output_from_dashrep_compiler = "output_from_dashrep_compiler" + param + ".txt";
std::string run_output = "output_from_running_" + param + ".txt";
std::string output_trace_from_running = "output_trace_from_running_" + param + ".txt";
// Build path to compiler.
std::string compiler_path = compiler_dir + "/dashrep_compiler_executable.pl";
// Remove files from previous run.
delete_file(output_trace_from_compiler);
delete_file(compiled_runtime_program);
delete_file(output_trace);
delete_file(compiler_log);
delete_file(output_from_dashrep_compiler);
delete_file(run_output);
delete_file(output_trace_from_running);
// Run the Dashrep compiler.
std::string compile_cmd =
"perl -w " + compiler_path + " < " + input_file +
" > " + compiler_log;
int compile_ret = run(compile_cmd);
if (compile_ret != 0) {
std::cerr << "Error: Dashrep compiler error." << std::endl;
return compile_ret;
}
// Copy the compiler's trace output.
copy_file("output_trace.txt", output_trace_from_compiler);
name_of_temporary_file = "output_trace.txt";
delete_file(name_of_temporary_file);
// Copy the compiled runtime code.
copy_file("output_from_dashrep_compiler.pl", compiled_runtime_program);
// Delete duplicate files and files only needed for debugging compiler.
name_of_temporary_file = "output_from_dashrep_compiler.pl";
delete_file(name_of_temporary_file);
name_of_temporary_file = "output_compiler_functions_replacement_only.txt";
delete_file(name_of_temporary_file);
name_of_temporary_file = "output_compiler_all_function_branches.txt";
delete_file(name_of_temporary_file);
name_of_temporary_file = "output_compiler_all_definition_items.txt";
delete_file(name_of_temporary_file);
name_of_temporary_file = "output_compiler_all_compiled_functions.txt";
delete_file(name_of_temporary_file);
// Run the compiled Perl script.
std::string run_cmd =
"perl -w " + compiled_runtime_program + " > " + run_output;
int run_ret = run(run_cmd);
if (run_ret != 0) {
std::cerr << "Error: Running compiled script failed." << std::endl;
return run_ret;
}
std::cout << "Compiled, run, output written to " << run_output << std::endl;
return 0;
}