-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerate_structs.cpp
More file actions
143 lines (123 loc) · 4.79 KB
/
generate_structs.cpp
File metadata and controls
143 lines (123 loc) · 4.79 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
/**
* @file generate_structs.cpp
* @author Eliot Abramo
* @brief Generate c++ structs to be used by avionics code.
* @date 2025-07-03
*/
#ifdef GENERATE_MSG //defined in bash script
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <filesystem>
#include <unordered_map>
// Structure to hold generated struct info.
struct GeneratedStruct {
std::string name;
std::string code;
};
// Structure to hold a field's type and name.
struct Field {
std::string type;
std::string name;
};
std::unordered_map<std::string, std::string> TYPE_MAP = {
{"uint16", "uint16_t"},
{"uint8", "uint8_t"},
{"float", "double"},
{"bool","string"},
};
// Extract the struct name from the filename (removing the extension).
std::string getStructName(const std::string& filename) {
return std::filesystem::path(filename).stem().string();
}
void generate_message_file(std::string folderPath, std::string outputFilename){
// Check if the input directory exists.
if (!std::filesystem::exists(folderPath)) {
std::cerr << "Directory " << folderPath << " does not exist." << std::endl;
return;
}
// Open the output file at the specified path.
std::ofstream outfile(outputFilename);
if (!outfile) {
std::cerr << "Error creating output file: " << outputFilename << std::endl;
return;
}
outfile << "/** \n";
outfile << " * @file packet_definition.hpp \n";
outfile << " * @author Eliot Abramo \n";
outfile << "*/ \n\n";
// Write the header guard and include <iostream>.
outfile << "#ifndef PACKET_DEFINITION_H\n";
outfile << "#define PACKET_DEFINITION_H\n\n";
outfile << "#include <iostream>\n";
outfile << "#include <packet_id.hpp>\n\n";
outfile << "#pragma pack(push, 1)\n";
// Iterate through all files in the folder.
for (const auto &entry : std::filesystem::directory_iterator(folderPath)) {
// Process only regular files with a .msg extension.
if (entry.is_regular_file() && entry.path().extension() == ".msg") {
std::ifstream infile(entry.path());
if (!infile) {
std::cerr << "Error opening file: " << entry.path() << std::endl;
continue;
}
// Derive the struct name from the file name.
std::string structName = getStructName(entry.path().string());
std::vector<Field> fields;
std::string line;
// Read each line and parse the type and variable name,
// skipping lines that are empty or start with '#'.
while (std::getline(infile, line)) {
if (line.empty() || line[0] == '#')
continue;
std::istringstream iss(line);
std::string type, name;
if (!(iss >> type >> name)) {
std::cerr << "Error parsing line in " << entry.path() << ": " << line << std::endl;
continue;
}
// Add a _t suffix to uint8 and uint16 cases.
if (type == "uint8") {
type = "uint8_t";
} else if (type == "uint16") {
type = "uint16_t";
} else if (type == "float32[4]"){
type = "float";
name = name +"[4]";
} else if (type == "float32") {
type = "float";
} else if (type == "bool[4]"){
type = "bool";
name = name + "[4]";
} else if (type == "uint32[7]") {
type = "uint32_t";
name = name + "[4]";
} else if (type == "string" || type == "String"){
type = "std::string";
} else if (type == "uint32"){
type = "uint32_t";
}
fields.push_back({type, name});
}
infile.close();
// Write the struct definition to the aggregated header file.
outfile << "struct " << structName << " {\n";
for (const auto &field : fields) {
outfile << " " << field.type << " " << field.name << ";\n";
}
outfile << "};\n\n";
std::cout << "Processed file: " << entry.path() << std::endl;
}
}
outfile << "pragma pack(pop)\n";
outfile << "#endif /* PACKET_DEFINITION_H */";
outfile.close();
std::cout << "Generated aggregated header file: " << outputFilename << std::endl;
}
int main(){
generate_message_file("ERC_SE_CustomMessages/msg/avionics", "avionics_nexus/include/packet_definition.hpp");
return 0;
}
#endif