summaryrefslogtreecommitdiff
path: root/utils/zenutils/source/firmware_make/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/zenutils/source/firmware_make/main.cpp')
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/firmware_make/main.cpp522
1 files changed, 261 insertions, 261 deletions
diff --git a/utils/zenutils/source/firmware_make/main.cpp b/utils/zenutils/source/firmware_make/main.cpp
index b0602b6ffe..35d036e601 100755..100644
--- a/utils/zenutils/source/firmware_make/main.cpp
+++ b/utils/zenutils/source/firmware_make/main.cpp
@@ -1,261 +1,261 @@
1/* zenutils - Utilities for working with creative firmwares. 1/* zenutils - Utilities for working with creative firmwares.
2 * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com> 2 * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com>
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. 7 * (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19#include <iostream> 19#include <iostream>
20#include <sstream> 20#include <sstream>
21#include <getpot/getpot.hpp> 21#include <getpot/getpot.hpp>
22#include <file.h> 22#include <file.h>
23#include <firmware.h> 23#include <firmware.h>
24#include <utils.h> 24#include <utils.h>
25 25
26 26
27static const char VERSION[] = "0.1"; 27static const char VERSION[] = "0.1";
28 28
29void print_version() 29void print_version()
30{ 30{
31 std::cout 31 std::cout
32 << "firmware_make - Creates a Creative firmware archive." << std::endl 32 << "firmware_make - Creates a Creative firmware archive." << std::endl
33 << "Version " << VERSION << std::endl 33 << "Version " << VERSION << std::endl
34 << "Copyright (c) 2007 Rasmus Ry" << std::endl; 34 << "Copyright (c) 2007 Rasmus Ry" << std::endl;
35} 35}
36 36
37void print_help() 37void print_help()
38{ 38{
39 print_version(); 39 print_version();
40 std::cout << std::endl 40 std::cout << std::endl
41 << "Usage: firmware_make [command] [options]" << std::endl 41 << "Usage: firmware_make [command] [options]" << std::endl
42 << std::endl 42 << std::endl
43 << " Commands:" << std::endl 43 << " Commands:" << std::endl
44 << " -h,--help" << std::endl 44 << " -h,--help" << std::endl
45 << " prints this message." << std::endl 45 << " prints this message." << std::endl
46 << " -m,--makefile [file]" << std::endl 46 << " -m,--makefile [file]" << std::endl
47 << " specifies the .mk file to build the firmware archive from." 47 << " specifies the .mk file to build the firmware archive from."
48 << std::endl << std::endl 48 << std::endl << std::endl
49 << " Options:" << std::endl 49 << " Options:" << std::endl
50 << " -V,--verbose" << std::endl 50 << " -V,--verbose" << std::endl
51 << " prints verbose messages." << std::endl 51 << " prints verbose messages." << std::endl
52 << " -f,--firmware [file]" << std::endl 52 << " -f,--firmware [file]" << std::endl
53 << " specifies the output firmware file name" << std::endl 53 << " specifies the output firmware file name" << std::endl
54 << std::endl 54 << std::endl
55 ; 55 ;
56} 56}
57 57
58dword get_tag_value(std::string tag) 58dword get_tag_value(std::string tag)
59{ 59{
60 if (tag[0] == '0' && tag[1] == 'x') 60 if (tag[0] == '0' && tag[1] == 'x')
61 { 61 {
62 dword val = 0; 62 dword val = 0;
63 if (sscanf(tag.c_str(), "0x%08X", &val) == 1) 63 if (sscanf(tag.c_str(), "0x%08X", &val) == 1)
64 return val; 64 return val;
65 if (sscanf(tag.c_str(), "0x%08x", &val) == 1) 65 if (sscanf(tag.c_str(), "0x%08x", &val) == 1)
66 return val; 66 return val;
67 } 67 }
68 else 68 else
69 { 69 {
70 return shared::swap(*(dword*)&tag[0]); 70 return shared::swap(*(dword*)&tag[0]);
71 } 71 }
72 return 0; 72 return 0;
73} 73}
74 74
75bool process_child(const GetPot& mkfile, const std::string& root, int index, 75bool process_child(const GetPot& mkfile, const std::string& root, int index,
76 zen::firmware_entry& entry) 76 zen::firmware_entry& entry)
77{ 77{
78 std::stringstream sstm; 78 std::stringstream sstm;
79 sstm << root << "/" << index; 79 sstm << root << "/" << index;
80 std::string var = sstm.str() + "/tag"; 80 std::string var = sstm.str() + "/tag";
81 std::string tag = mkfile(var.c_str(), ""); 81 std::string tag = mkfile(var.c_str(), "");
82 var = sstm.str() + "/name"; 82 var = sstm.str() + "/name";
83 std::string name = mkfile(var.c_str(), ""); 83 std::string name = mkfile(var.c_str(), "");
84 var = sstm.str() + "/file"; 84 var = sstm.str() + "/file";
85 std::string file = mkfile(var.c_str(), ""); 85 std::string file = mkfile(var.c_str(), "");
86 86
87 if (file.empty() || tag.empty()) 87 if (file.empty() || tag.empty())
88 { 88 {
89 std::cerr << "Invalid file or tag for var: " << sstm.str() 89 std::cerr << "Invalid file or tag for var: " << sstm.str()
90 << std::endl; 90 << std::endl;
91 return false; 91 return false;
92 } 92 }
93 93
94 shared::bytes buffer; 94 shared::bytes buffer;
95 if (!shared::read_file(file, buffer)) 95 if (!shared::read_file(file, buffer))
96 { 96 {
97 std::cerr << "Failed to read the file: " << file << std::endl; 97 std::cerr << "Failed to read the file: " << file << std::endl;
98 return false; 98 return false;
99 } 99 }
100 100
101 entry.get_bytes().clear(); 101 entry.get_bytes().clear();
102 entry.get_header().tag = get_tag_value(tag); 102 entry.get_header().tag = get_tag_value(tag);
103 size_t contoff = entry.get_content_offset(); 103 size_t contoff = entry.get_content_offset();
104 if (contoff) 104 if (contoff)
105 { 105 {
106 entry.get_bytes().resize(contoff, 0); 106 entry.get_bytes().resize(contoff, 0);
107 if (!name.empty()) 107 if (!name.empty())
108 { 108 {
109 size_t endoff = entry.is_big_endian() ? 1 : 0; 109 size_t endoff = entry.is_big_endian() ? 1 : 0;
110 for (int i = 0; i < name.size(); ++i) 110 for (int i = 0; i < name.size(); ++i)
111 entry.get_bytes()[i * 2 + endoff] = name[i]; 111 entry.get_bytes()[i * 2 + endoff] = name[i];
112 } 112 }
113 } 113 }
114 entry.get_bytes().insert(entry.get_bytes().end(), buffer.begin(), 114 entry.get_bytes().insert(entry.get_bytes().end(), buffer.begin(),
115 buffer.end()); 115 buffer.end());
116 116
117 entry.get_header().size = entry.get_bytes().size(); 117 entry.get_header().size = entry.get_bytes().size();
118 118
119 return true; 119 return true;
120} 120}
121 121
122int process_arguments(int argc, char* argv[]) 122int process_arguments(int argc, char* argv[])
123{ 123{
124 //-------------------------------------------------------------------- 124 //--------------------------------------------------------------------
125 // Parse input variables. 125 // Parse input variables.
126 //-------------------------------------------------------------------- 126 //--------------------------------------------------------------------
127 127
128 GetPot cl(argc, argv); 128 GetPot cl(argc, argv);
129 if (cl.size() == 1 || cl.search(2, "-h", "--help")) 129 if (cl.size() == 1 || cl.search(2, "-h", "--help"))
130 { 130 {
131 print_help(); 131 print_help();
132 return 1; 132 return 1;
133 } 133 }
134 134
135 std::string makefile; 135 std::string makefile;
136 if (cl.search("-m") || cl.search("--makefile")) 136 if (cl.search("-m") || cl.search("--makefile"))
137 makefile = cl.next(""); 137 makefile = cl.next("");
138 if (makefile.empty()) 138 if (makefile.empty())
139 { 139 {
140 std::cerr << "Makefile must be specified." << std::endl; 140 std::cerr << "Makefile must be specified." << std::endl;
141 return 2; 141 return 2;
142 } 142 }
143 143
144 std::string firmware; 144 std::string firmware;
145 if (cl.search("-f") || cl.search("--firmware")) 145 if (cl.search("-f") || cl.search("--firmware"))
146 firmware = cl.next(""); 146 firmware = cl.next("");
147 if (firmware.empty()) 147 if (firmware.empty())
148 { 148 {
149 std::cerr << "Firmware must be specified." << std::endl; 149 std::cerr << "Firmware must be specified." << std::endl;
150 return 3; 150 return 3;
151 } 151 }
152 152
153 bool verbose = false; 153 bool verbose = false;
154 if (cl.search("-V") || cl.search("--verbose")) 154 if (cl.search("-V") || cl.search("--verbose"))
155 verbose = true; 155 verbose = true;
156 156
157 GetPot mkfile(makefile.c_str()); 157 GetPot mkfile(makefile.c_str());
158 if (verbose) 158 if (verbose)
159 mkfile.print(); 159 mkfile.print();
160 160
161 bool big_endian; 161 bool big_endian;
162 std::string endian = mkfile("endian", "little"); 162 std::string endian = mkfile("endian", "little");
163 if (endian == "little") 163 if (endian == "little")
164 { 164 {
165 big_endian = false; 165 big_endian = false;
166 } 166 }
167 else if (endian == "big") 167 else if (endian == "big")
168 { 168 {
169 big_endian = true; 169 big_endian = true;
170 } 170 }
171 else 171 else
172 { 172 {
173 std::cerr << "Invalid value of 'endian'" << std::endl; 173 std::cerr << "Invalid value of 'endian'" << std::endl;
174 return 4; 174 return 4;
175 } 175 }
176 176
177 zen::firmware_archive archive(big_endian); 177 zen::firmware_archive archive(big_endian);
178 int childcount = mkfile("children/count", 0); 178 int childcount = mkfile("children/count", 0);
179 if (!childcount) 179 if (!childcount)
180 { 180 {
181 std::cerr << "A firmware archive must have at least one child entry." 181 std::cerr << "A firmware archive must have at least one child entry."
182 << std::endl; 182 << std::endl;
183 return 5; 183 return 5;
184 } 184 }
185 185
186 for (int i = 0; i < childcount; i++) 186 for (int i = 0; i < childcount; i++)
187 { 187 {
188 zen::firmware_entry entry(big_endian); 188 zen::firmware_entry entry(big_endian);
189 if (!process_child(mkfile, "children", i, entry)) 189 if (!process_child(mkfile, "children", i, entry))
190 { 190 {
191 return 6; 191 return 6;
192 } 192 }
193 archive.get_children().push_back(entry); 193 archive.get_children().push_back(entry);
194 } 194 }
195 195
196 int neighbourcount = mkfile("neighbours/count", 0); 196 int neighbourcount = mkfile("neighbours/count", 0);
197 for (int i = 0; i < neighbourcount; i++) 197 for (int i = 0; i < neighbourcount; i++)
198 { 198 {
199 zen::firmware_entry entry(big_endian); 199 zen::firmware_entry entry(big_endian);
200 if (!process_child(mkfile, "neighbours", i, entry)) 200 if (!process_child(mkfile, "neighbours", i, entry))
201 { 201 {
202 return 7; 202 return 7;
203 } 203 }
204 archive.get_neighbours().push_back(entry); 204 archive.get_neighbours().push_back(entry);
205 } 205 }
206 206
207 std::ofstream ofs; 207 std::ofstream ofs;
208 ofs.open(firmware.c_str(), std::ios::out|std::ios::binary|std::ios::trunc); 208 ofs.open(firmware.c_str(), std::ios::out|std::ios::binary|std::ios::trunc);
209 if (!ofs) 209 if (!ofs)
210 { 210 {
211 std::cerr << "Failed to create the firmware file." << std::endl; 211 std::cerr << "Failed to create the firmware file." << std::endl;
212 return 8; 212 return 8;
213 } 213 }
214 214
215 if (!archive.write(ofs)) 215 if (!archive.write(ofs))
216 { 216 {
217 std::cerr << "Failed to save the firmware archive." << std::endl; 217 std::cerr << "Failed to save the firmware archive." << std::endl;
218 return 9; 218 return 9;
219 } 219 }
220 ofs.close(); 220 ofs.close();
221 221
222 size_t length = archive.calc_size(); 222 size_t length = archive.calc_size();
223 if (!length) 223 if (!length)
224 { 224 {
225 std::cerr << "Failed to determine the size of the firmware archive." 225 std::cerr << "Failed to determine the size of the firmware archive."
226 << std::endl; 226 << std::endl;
227 return 10; 227 return 10;
228 } 228 }
229 229
230 int align = length % 4; 230 int align = length % 4;
231 if (align) 231 if (align)
232 { 232 {
233 shared::bytes padding(4 - align, 0); 233 shared::bytes padding(4 - align, 0);
234 if (!shared::write_file(firmware, padding, false, length)) 234 if (!shared::write_file(firmware, padding, false, length))
235 { 235 {
236 std::cerr << "Failed to write padding data." << std::endl; 236 std::cerr << "Failed to write padding data." << std::endl;
237 return 11; 237 return 11;
238 } 238 }
239 } 239 }
240 240
241 return 0; 241 return 0;
242} 242}
243 243
244int main(int argc, char* argv[]) 244int main(int argc, char* argv[])
245{ 245{
246 try 246 try
247 { 247 {
248 return process_arguments(argc, argv); 248 return process_arguments(argc, argv);
249 } 249 }
250 catch (const std::exception& xcpt) 250 catch (const std::exception& xcpt)
251 { 251 {
252 std::cerr << "Exception caught: " << xcpt.what() << std::endl; 252 std::cerr << "Exception caught: " << xcpt.what() << std::endl;
253 return -1; 253 return -1;
254 } 254 }
255 catch (...) 255 catch (...)
256 { 256 {
257 std::cerr << "Unknown exception caught." << std::endl; 257 std::cerr << "Unknown exception caught." << std::endl;
258 return -2; 258 return -2;
259 } 259 }
260 return -3; 260 return -3;
261} 261}