Skip to content

Commit 4e96383

Browse files
committed
WIP: Add parsing include statements
1 parent d17a43b commit 4e96383

File tree

3 files changed

+88
-6
lines changed

3 files changed

+88
-6
lines changed

include/ur_client_library/control/script_reader.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
// -- END LICENSE BLOCK ------------------------------------------------
3030

3131
#pragma once
32+
#include <filesystem>
3233
#include <string>
34+
#include <unordered_map>
35+
#include <variant>
3336

3437
#include <ur_client_library/ur/datatypes.h>
3538
#include <ur_client_library/ur/version_information.h>
@@ -59,7 +62,12 @@ class ScriptReader
5962
std::string readScriptFile(const std::string& filename);
6063

6164
private:
65+
std::filesystem::path script_path_;
6266
RobotInfo robot_info_;
67+
std::unordered_map<std::string, std::variant<std::string, float, int>> replacement_data_;
68+
69+
void replaceIncludes(std::string& script_code);
70+
std::string readFileContent(const std::string& filename);
6371
};
6472
} // namespace control
6573
} // namespace urcl

src/control/script_reader.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,23 @@
3232
#include <ur_client_library/control/script_reader.h>
3333

3434
#include <fstream>
35+
#include <regex>
3536

3637
namespace urcl
3738
{
3839
namespace control
3940
{
4041
std::string ScriptReader::readScriptFile(const std::string& filename)
42+
{
43+
script_path_ = filename;
44+
std::string script_code = readFileContent(filename);
45+
46+
replaceIncludes(script_code);
47+
48+
return script_code;
49+
}
50+
51+
std::string ScriptReader::readFileContent(const std::string& filename)
4152
{
4253
std::ifstream ifs;
4354
ifs.open(filename);
@@ -57,5 +68,32 @@ std::string ScriptReader::readScriptFile(const std::string& filename)
5768

5869
return content;
5970
}
71+
72+
void ScriptReader::replaceIncludes(std::string& script)
73+
{
74+
std::string line;
75+
std::regex include_pattern(R"(\{\%\s*include\s*['|"]([^'"]+)['|"]\s*\%\})");
76+
77+
std::stringstream input_stream(script);
78+
std::stringstream output_stream;
79+
80+
while (std::getline(input_stream, line))
81+
{
82+
std::smatch match;
83+
std::string processed_line = line;
84+
85+
// Replace all include patterns in the line
86+
while (std::regex_search(processed_line, match, include_pattern))
87+
{
88+
std::filesystem::path file_path(match[1]);
89+
std::string file_content = readFileContent(script_path_.parent_path() / file_path.string());
90+
processed_line.replace(match.position(0), match.length(0), file_content);
91+
}
92+
93+
output_stream << processed_line << '\n';
94+
}
95+
script = output_stream.str();
96+
}
97+
6098
} // namespace control
6199
} // namespace urcl

tests/test_script_reader.cpp

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333

3434
#include <fstream>
3535

36+
#ifdef _WIN32
37+
# define mkstemp _mktemp_s
38+
#endif
39+
3640
using namespace urcl::control;
3741

3842
class ScriptReaderTest : public ::testing::Test
@@ -51,9 +55,6 @@ class ScriptReaderTest : public ::testing::Test
5155
invalid_script_path_ = "test_resources/non_existent_script.urscript";
5256
empty_script_path_ = "resources/empty.txt";
5357
char existing_script_file[] = "urscript.XXXXXX";
54-
#ifdef _WIN32
55-
# define mkstemp _mktemp_s
56-
#endif
5758
std::ignore = mkstemp(existing_script_file);
5859
std::ofstream ofs(existing_script_file);
5960
if (ofs.bad())
@@ -65,7 +66,7 @@ class ScriptReaderTest : public ::testing::Test
6566

6667
valid_script_path_ = existing_script_file;
6768

68-
simple_script_ << "movej([0,0,0,0,0,0])";
69+
simple_script_ << "movej([0,0,0,0,0,0])\n";
6970

7071
// Create test resources
7172
std::ofstream valid_script(valid_script_path_);
@@ -89,7 +90,7 @@ TEST_F(ScriptReaderTest, ReadValidScript)
8990
{
9091
ScriptReader reader(robot_info_);
9192
std::string content = reader.readScriptFile(valid_script_path_);
92-
EXPECT_EQ(content, "movej([0,0,0,0,0,0])");
93+
EXPECT_EQ(content, simple_script_.str());
9394
}
9495

9596
TEST_F(ScriptReaderTest, ReadEmptyScript)
@@ -103,4 +104,39 @@ TEST_F(ScriptReaderTest, ReadNonExistentScript)
103104
{
104105
ScriptReader reader(robot_info_);
105106
EXPECT_THROW(reader.readScriptFile(invalid_script_path_), std::runtime_error);
106-
}
107+
}
108+
109+
TEST_F(ScriptReaderTest, ReplaceIncludes)
110+
{
111+
ScriptReader reader(robot_info_);
112+
113+
char existing_script_file[] = "main_script.XXXXXX";
114+
std::ignore = mkstemp(existing_script_file);
115+
char existing_include_file[] = "included_script.XXXXXX";
116+
std::ignore = mkstemp(existing_include_file);
117+
std::ofstream ofs(existing_script_file);
118+
if (ofs.bad())
119+
{
120+
std::cout << "Failed to create temporary files" << std::endl;
121+
GTEST_FAIL();
122+
}
123+
std::string script_with_include = "{% include '" + std::string(existing_include_file) + "' %}";
124+
ofs << script_with_include;
125+
ofs.close();
126+
127+
// Create a temporary included script
128+
std::ofstream ofs_included(existing_include_file);
129+
if (ofs_included.bad())
130+
{
131+
std::cout << "Failed to create temporary files" << std::endl;
132+
GTEST_FAIL();
133+
}
134+
ofs_included << "movej([1,2,3,4,5,6])";
135+
ofs_included.close();
136+
137+
std::string processed_script = reader.readScriptFile(existing_script_file);
138+
EXPECT_EQ(processed_script, "movej([1,2,3,4,5,6])\n");
139+
140+
std::remove(existing_script_file);
141+
std::remove(existing_include_file);
142+
}

0 commit comments

Comments
 (0)