WIN32 compilation of wxrc, wxrcedit
[wxWidgets.git] / utils / wxrc / wxrc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wxrc.cpp
3 // Purpose: XML resource compiler
4 // Author: Vaclav Slavik
5 // Created: 2000/03/05
6 // RCS-ID: $Id$
7 // Copyright: (c) 2000 Vaclav Slavik
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation
13 #pragma interface
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 // for all others, include the necessary headers (this file is usually all you
24 // need because it includes almost all "standard" wxWindows headers
25 #ifndef WX_PRECOMP
26 #include "wx/wx.h"
27 #endif
28
29 #include "wx/cmdline.h"
30 #include "wx/xml/xml.h"
31 #include "wx/ffile.h"
32
33 /*
34 #if wxUSE_GUI
35 #error "You must compile the resource compiler with wxBase!"
36 #endif
37 */
38
39 class XmlResApp : public wxApp
40 {
41 public:
42
43 #if wxUSE_GUI
44 bool OnInit();
45 #else
46 virtual int OnRun();
47 #endif
48
49 private:
50
51 void ParseParams(const wxCmdLineParser& cmdline);
52 void CompileRes();
53 wxArrayString PrepareTempFiles();
54 void DeleteTempFiles(const wxArrayString& flist);
55 void MakePackageZIP(const wxArrayString& flist);
56 void MakePackageCPP(const wxArrayString& flist);
57
58 bool flagVerbose, flagCPP, flagCompress;
59 wxString parOutput, parFuncname, parOutputPath;
60 wxArrayString parFiles;
61 int retCode;
62 };
63
64 IMPLEMENT_APP(XmlResApp)
65
66 #if wxUSE_GUI
67 bool XmlResApp::OnInit()
68 #else
69 int XmlResApp::OnRun()
70 #endif
71 {
72 static const wxCmdLineEntryDesc cmdLineDesc[] =
73 {
74 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
75 { wxCMD_LINE_SWITCH, "c", "cpp-code", "output C++ source rather than .rsc file" },
76 { wxCMD_LINE_SWITCH, "u", "uncompressed", "do not compress .xml files (C++ only)" },
77 { wxCMD_LINE_OPTION, "n", "function", "C++ function name (with -c) [InitXmlResource]" },
78 { wxCMD_LINE_OPTION, "o", "output", "output file [resource.rsc/cpp]" },
79 { wxCMD_LINE_OPTION, "h", "handlers", "output list of neccessary handlers to this file" },
80
81 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
82 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
83
84 { wxCMD_LINE_NONE }
85 };
86
87 wxCmdLineParser parser(cmdLineDesc, argc, argv);
88
89 switch (parser.Parse())
90 {
91 case -1:
92 return 0;
93 break;
94
95 case 0:
96 retCode = 0;
97 ParseParams(parser);
98 CompileRes();
99 #if wxUSE_GUI
100 return FALSE;
101 #else
102 return retCode;
103 #endif
104 break;
105
106 default:
107 #if wxUSE_GUI
108 return FALSE;
109 #else
110 return 1;
111 #endif
112 break;
113 }
114 }
115
116
117
118
119 void XmlResApp::ParseParams(const wxCmdLineParser& cmdline)
120 {
121 flagVerbose = cmdline.Found("v");
122 flagCPP = cmdline.Found("c");
123 flagCompress = flagCPP && !cmdline.Found("u");
124
125 if (!cmdline.Found("o", &parOutput))
126 parOutput = flagCPP ? "resource.cpp" : "resource.rsc";
127 parOutputPath = wxPathOnly(parOutput);
128 if (!parOutputPath) parOutputPath = ".";
129
130 if (!cmdline.Found("n", &parFuncname))
131 parFuncname = "InitXmlResource";
132
133 for (size_t i = 0; i < cmdline.GetParamCount(); i++)
134 parFiles.Add(cmdline.GetParam(i));
135 }
136
137
138
139
140 void XmlResApp::CompileRes()
141 {
142 wxArrayString files = PrepareTempFiles();
143
144 wxRemoveFile(parOutput);
145
146 printf("TODO: include bitmaps, list of handlers\n");
147
148 if (!retCode)
149 {
150 if (flagCPP)
151 MakePackageCPP(files);
152 else
153 MakePackageZIP(files);
154 }
155
156 DeleteTempFiles(files);
157 }
158
159
160
161 wxArrayString XmlResApp::PrepareTempFiles()
162 {
163 wxArrayString flist;
164
165 for (size_t i = 0; i < parFiles.Count(); i++)
166 {
167 if (flagVerbose)
168 wxPrintf("processing " + parFiles[i] + "...\n");
169
170 wxXmlDocument doc;
171
172 if (!doc.Load(parFiles[i]))
173 {
174 wxLogError("Error parsing file " + parFiles[i]);
175 retCode = 1;
176 continue;
177 }
178
179 wxString name, ext;
180 wxSplitPath(parFiles[i], NULL, &name, &ext);
181
182 doc.Save(parOutputPath + "/" + name + ".xmb", flagCompress ? wxXML_IO_BINZ : wxXML_IO_BIN);
183 flist.Add(name + ".xmb");
184 }
185
186 return flist;
187 }
188
189
190
191 void XmlResApp::DeleteTempFiles(const wxArrayString& flist)
192 {
193 for (size_t i = 0; i < flist.Count(); i++)
194 wxRemoveFile(parOutputPath + "/" + flist[i]);
195 }
196
197
198
199 void XmlResApp::MakePackageZIP(const wxArrayString& flist)
200 {
201 wxString files;
202
203 for (size_t i = 0; i < flist.Count(); i++)
204 files += flist[i] + " ";
205 files.RemoveLast();
206
207 if (flagVerbose)
208 wxPrintf("compressing " + parOutput + "...\n");
209
210 if (wxExecute("zip -9 -j " + wxString(flagVerbose ? "" : "-q ") +
211 parOutput + " " + files, TRUE) == -1)
212 {
213 wxLogError("Unable to execute zip program. Make sure it is in the path.");
214 wxLogError("You can download it at http://www.cdrom.com/pub/infozip/");
215 retCode = 1;
216 return;
217 }
218 }
219
220
221
222
223 static wxString FileToCppArray(wxString filename, int num)
224 {
225 wxString output;
226 wxString snum;
227 wxString tmp;
228 wxFFile file(filename, "rb");
229 size_t lng = file.Length();
230
231 snum.Printf("%i", num);
232 output.Printf("static size_t xml_res_size_" + snum + " = %i;\n", lng);
233 output += "static unsigned char xml_res_file_" + snum + "[] = {";
234
235 unsigned char *buffer = new unsigned char[lng];
236 file.Read(buffer, lng);
237
238 for (size_t i = 0; i < lng; i++)
239 {
240 if (i % 16 == 0) output += "\n";
241 tmp.Printf("0x%02X", buffer[i]);
242 output += tmp;
243 if (i != lng-1) output += ",";
244 }
245
246 delete[] buffer;
247
248 output += "\n};\n\n";
249
250 return output;
251 }
252
253
254 void XmlResApp::MakePackageCPP(const wxArrayString& flist)
255 {
256 wxFFile file(parOutput, "wt");
257 size_t i;
258
259 if (flagVerbose)
260 wxPrintf("creating C++ source file " + parOutput + "...\n");
261
262 file.Write("\
263 #include \"wx/wxprec.h\"\n\
264 \n\
265 #ifdef __BORLANDC__\n\
266 #pragma hdrstop\n\
267 #endif\n\
268 \n\
269 #ifndef WX_PRECOMP\n\
270 #include \"wx/wx.h\"\n\
271 #endif\n\
272 \
273 #include \"wx/filesys.h\"\n\
274 #include \"wx/fs_mem.h\"\n\
275 #include \"wx/xml/xmlres.h\"\n\
276 #include \"wx/xml/xh_all.h\"\n\
277 \n");
278
279 for (i = 0; i < flist.Count(); i++)
280 file.Write(FileToCppArray(flist[i], i));
281
282 file.Write("\
283 void " + parFuncname + "()\n\
284 {\n\
285 \n\
286 // Check for memory FS. If not present, load the handler:\n\
287 {\n\
288 wxMemoryFSHandler::AddFile(\"xml_resource/dummy_file\", \"dummy one\");\n\
289 wxFileSystem fsys;\n\
290 wxFSFile *f = fsys.OpenFile(\"xml_resource/dummy_file\");\n\
291 wxMemoryFSHandler::RemoveFile(\"xml_resource/dummy_file\");\n\
292 if (f) delete f;\n\
293 else wxFileSystem::AddHandler(new wxMemoryFSHandler);\n\
294 }\n\
295 \n");
296
297 for (i = 0; i < flist.Count(); i++)
298 {
299 wxString s;
300 s.Printf(" wxMemoryFSHandler::AddFile(\"xml_resource/" + flist[i] +
301 "\", xml_res_file_%i, xml_res_size_%i);\n"
302 " wxTheXmlResource->Read(\"xml_resource/" + flist[i] +
303 "\", wxXML_BINARY);\n", i, i);
304 file.Write(s);
305 }
306
307 file.Write("\n}\n");
308
309 }