Initial integration, lots of broken stuff
[supertux.git] / src / unison / physfs-1.1.1 / test / wxtest_physfs.cpp
1 /**
2  * Test program for PhysicsFS, using wxWidgets. May only work on Unix.
3  *
4  * Please see the file LICENSE.txt in the source's root directory.
5  *
6  *  This file written by Ryan C. Gordon.
7  */
8
9 #if ( (defined(__MACH__)) && (defined(__APPLE__)) )
10 #define PLATFORM_MACOSX 1
11 #include <Carbon/Carbon.h>
12 #endif
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <time.h>
18 #include <errno.h>
19
20 #include <wx/wx.h>
21 #include <wx/treectrl.h>
22
23 #include "physfs.h"
24
25 #define TEST_VER_MAJOR  1
26 #define TEST_VER_MINOR  1
27 #define TEST_VER_PATCH  1
28
29 //static PHYSFS_uint32 do_buffer_size = 0;
30
31 enum WxTestPhysfsMenuCommands
32 {
33     // start with standard menu items, since using the wxIDs will map them
34     //  to sane things in the platform's UI (gnome icons in GTK+, moves the
35     //  about and quit items to the Apple menu on Mac OS X, etc).
36     MENUCMD_About = wxID_ABOUT,
37     MENUCMD_Quit = wxID_EXIT,
38
39     // non-standard menu items go here.
40     MENUCMD_Init = wxID_HIGHEST,
41     MENUCMD_Deinit,
42     MENUCMD_AddArchive,
43     MENUCMD_Mount,
44     MENUCMD_Remove,
45     MENUCMD_GetCDs,
46     MENUCMD_SetWriteDir,
47     MENUCMD_PermitSymLinks,
48     MENUCMD_SetSaneConfig,
49     MENUCMD_MkDir,
50     MENUCMD_Delete,
51     MENUCMD_Cat,
52     MENUCMD_SetBuffer,
53     MENUCMD_StressBuffer,
54     MENUCMD_Append,
55     MENUCMD_Write,
56     MENUCMD_GetLastError,
57
58 /*
59     { "getdirsep",      cmd_getdirsep,      0, NULL                         },
60     { "getsearchpath",  cmd_getsearchpath,  0, NULL                         },
61     { "getbasedir",     cmd_getbasedir,     0, NULL                         },
62     { "getuserdir",     cmd_getuserdir,     0, NULL                         },
63     { "getwritedir",    cmd_getwritedir,    0, NULL                         },
64     { "getrealdir",     cmd_getrealdir,     1, "<fileToFind>"               },
65     { "exists",         cmd_exists,         1, "<fileToCheck>"              },
66     { "isdir",          cmd_isdir,          1, "<fileToCheck>"              },
67     { "issymlink",      cmd_issymlink,      1, "<fileToCheck>"              },
68     { "filelength",     cmd_filelength,     1, "<fileToCheck>"              },
69     { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>"            },
70 */
71 };
72
73
74 class WxTestPhysfsFrame : public wxFrame
75 {
76 public:
77     WxTestPhysfsFrame(const wxChar *argv0);
78
79     void rebuildTree();
80
81     void onMenuInit(wxCommandEvent &evt);
82     void onMenuDeinit(wxCommandEvent &evt);
83     void onMenuAddArchive(wxCommandEvent &evt);
84     void onMenuGetCDs(wxCommandEvent &evt);
85     void onMenuPermitSymLinks(wxCommandEvent &evt);
86
87 private:
88     wxTreeCtrl *fileTree;
89     wxTreeItemId stateItem;
90     wxTreeItemId fsItem;
91
92     int err(int success);
93     void fillFileSystemTree(const char *path, const wxTreeItemId &item);
94     void doInit(const char *argv0);
95     void doDeinit();
96
97     DECLARE_EVENT_TABLE()
98 };
99
100 BEGIN_EVENT_TABLE(WxTestPhysfsFrame, wxFrame)
101     EVT_MENU(MENUCMD_Init, WxTestPhysfsFrame::onMenuInit)
102     EVT_MENU(MENUCMD_Deinit, WxTestPhysfsFrame::onMenuDeinit)
103     EVT_MENU(MENUCMD_AddArchive, WxTestPhysfsFrame::onMenuAddArchive)
104     EVT_MENU(MENUCMD_GetCDs, WxTestPhysfsFrame::onMenuGetCDs)
105     EVT_MENU(MENUCMD_PermitSymLinks, WxTestPhysfsFrame::onMenuPermitSymLinks)
106 END_EVENT_TABLE()
107
108
109
110 // This is the the Application itself.
111 class WxTestPhysfsApp : public wxApp
112 {
113 public:
114     WxTestPhysfsApp() : mainWindow(NULL) { /* no-op. */ }
115     virtual bool OnInit();
116
117 private:
118     WxTestPhysfsFrame *mainWindow;
119 };
120
121 DECLARE_APP(WxTestPhysfsApp)
122
123
124 static inline char *newstr(const char *str)
125 {
126     char *retval = NULL;
127     if (str != NULL)
128     {
129         retval = new char[strlen(str) + 1];
130         strcpy(retval, str);
131     } // if
132     return retval;
133 } // newstr
134
135 static char *newutf8(const wxString &wxstr)
136 {
137     #if wxUSE_UNICODE
138     size_t len = wxstr.Len() + 1;
139     char *utf8text = new char[len * 6];
140     wxConvUTF8.WC2MB(utf8text, wxstr, len);
141     return utf8text;
142     #else
143     return newstr(wxstr);
144     #endif
145 } // newutf8
146
147
148 WxTestPhysfsFrame::WxTestPhysfsFrame(const wxChar *argv0)
149     : wxFrame(NULL, -1, wxT("WxTestPhysfs"))
150 {
151     this->CreateStatusBar();
152
153     wxMenuBar *menuBar = new wxMenuBar;
154
155     wxMenu *stuffMenu = new wxMenu;
156     stuffMenu->Append(MENUCMD_Init, wxT("&Init"));
157     stuffMenu->Append(MENUCMD_Deinit, wxT("&Deinit"));
158     stuffMenu->Append(MENUCMD_AddArchive, wxT("&Add Archive"));
159     stuffMenu->Append(MENUCMD_Mount, wxT("&Mount Archive"));
160     stuffMenu->Append(MENUCMD_Remove, wxT("&Remove Archive"));
161     stuffMenu->Append(MENUCMD_GetCDs, wxT("&Get CD-ROM drives"));
162     stuffMenu->Append(MENUCMD_SetWriteDir, wxT("&Set Write Dir"));
163     stuffMenu->Append(MENUCMD_SetSaneConfig, wxT("Set Sane &Config"));
164     stuffMenu->Append(MENUCMD_MkDir, wxT("M&kDir"));
165     stuffMenu->Append(MENUCMD_Delete, wxT("D&elete"));
166     stuffMenu->Append(MENUCMD_Cat, wxT("&Cat"));
167     stuffMenu->Append(MENUCMD_SetBuffer, wxT("Set &Buffer"));
168     stuffMenu->Append(MENUCMD_StressBuffer, wxT("Stress &Test Buffer"));
169     stuffMenu->Append(MENUCMD_Append, wxT("&Append"));
170     stuffMenu->Append(MENUCMD_Write, wxT("&Write"));
171     stuffMenu->Append(MENUCMD_Write, wxT("&Update getLastError"));
172     stuffMenu->AppendCheckItem(MENUCMD_PermitSymLinks, wxT("&Permit symlinks"));
173     menuBar->Append(stuffMenu, wxT("&Stuff"));
174
175     //wxMenu *helpMenu = new wxMenu;
176     //helpMenu->Append(MENUCMD_About, wxT("&About\tF1"));
177     //menuBar->Append(helpMenu, wxT("&Help"));
178
179     this->SetMenuBar(menuBar);
180
181     this->fileTree = new wxTreeCtrl(this, -1);
182
183     // The sizer just makes sure that fileTree owns whole client area.
184     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
185     sizer->Add(this->fileTree, 1, wxALL | wxEXPAND | wxALIGN_CENTRE);
186     sizer->SetItemMinSize(this->fileTree, 1, 1);
187     this->SetSizer(sizer);
188
189     char *utf8argv0 = newutf8(wxString(argv0));
190     this->doInit(utf8argv0);
191     delete[] utf8argv0;
192 } // WxTestPhysfsFrame::WxTestPhysfsFrame
193
194
195 int WxTestPhysfsFrame::err(int success)
196 {
197     if (success)
198         this->SetStatusText(wxT(""));
199     else
200         this->SetStatusText(wxString(PHYSFS_getLastError(), wxConvUTF8));
201     return success;
202 } // WxTestPhysfsFrame::err
203
204
205 void WxTestPhysfsFrame::fillFileSystemTree(const char *path,
206                                            const wxTreeItemId &item)
207 {
208     char **rc = PHYSFS_enumerateFiles(path);
209     char **i;
210     wxTreeItemId id;
211
212     if (rc == NULL)
213     {
214         const wxString quote(wxT("'"));
215         wxString str(wxT("Enumeration error: "));
216         str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
217         id = this->fileTree->AppendItem(item, str);
218         this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
219     } // if
220     else
221     {
222         for (i = rc; *i != NULL; i++)
223         {
224             id = this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
225             const int len = strlen(path) + strlen(*i) + 2;
226             char *fname = new char[len];
227             const char *origdir = path;
228             if (strcmp(origdir, "/") == 0)
229                 origdir = "";
230             snprintf(fname, len, "%s/%s", origdir, *i);
231
232             if (PHYSFS_isDirectory(fname))
233             {
234                 this->fileTree->SetItemTextColour(id, wxColour(0, 0, 255));
235                 this->fillFileSystemTree(fname, id);
236             } // if
237
238             else if (PHYSFS_isSymbolicLink(fname))
239             {
240                 this->fileTree->SetItemTextColour(id, wxColour(0, 255, 0));
241             } // else if
242
243             else  // ...file.
244             {
245             } // else
246
247             delete[] fname;
248         } // for
249
250         PHYSFS_freeList(rc);
251     } // else
252 } // fillFileSystemTree
253
254
255 void WxTestPhysfsFrame::rebuildTree()
256 {
257     const wxString dot(wxT("."));
258     const wxString quote(wxT("'"));
259     wxTreeItemId item;
260     wxString str;
261     const char *cstr = NULL;
262     const bool wasInit = PHYSFS_isInit() ? true : false;
263
264     this->fileTree->DeleteAllItems();
265     wxTreeItemId root = this->fileTree->AddRoot(wxT("PhysicsFS"));
266     this->stateItem = this->fileTree->AppendItem(root, wxT("Library state"));
267
268     str = wxT("Initialized: ");
269     str << ((wasInit) ? wxT("true") : wxT("false"));
270     this->fileTree->AppendItem(this->stateItem, str);
271
272     this->fileTree->Expand(this->stateItem);
273     this->fileTree->Expand(root);
274
275     // Fill in version information...
276
277     PHYSFS_Version ver;
278     item = this->stateItem;
279     str = wxT("wxtest_physfs version: ");
280     str << TEST_VER_MAJOR << dot << TEST_VER_MINOR << dot << TEST_VER_PATCH;
281     this->fileTree->AppendItem(item, str);
282     PHYSFS_VERSION(&ver);
283     str = wxT("Compiled against PhysicsFS version: ");
284     str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
285     this->fileTree->AppendItem(item, str);
286     PHYSFS_getLinkedVersion(&ver);
287     str = wxT("Linked against PhysicsFS version: ");
288     str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
289     this->fileTree->AppendItem(item, str);
290
291     if (!wasInit)
292         return;   // nothing else to do before initialization...
293
294     str = wxT("Symbolic links permitted: ");
295     str << ((PHYSFS_symbolicLinksPermitted()) ? wxT("true") : wxT("false"));
296     this->fileTree->AppendItem(this->stateItem, str);
297
298     str = wxT("Native directory separator: ");
299     str << quote << wxString(PHYSFS_getDirSeparator(), wxConvUTF8) << quote;
300     this->fileTree->AppendItem(this->stateItem, str);
301
302     // Fill in supported archives...
303
304     item = this->fileTree->AppendItem(this->stateItem, wxT("Archivers"));
305     const PHYSFS_ArchiveInfo **arcs = PHYSFS_supportedArchiveTypes();
306     if (*arcs == NULL)
307         this->fileTree->AppendItem(item, wxT("(none)"));
308     else
309     {
310         const PHYSFS_ArchiveInfo **i;
311         for (i = arcs; *i != NULL; i++)
312         {
313             const wxString ext((*i)->extension, wxConvUTF8);
314             const wxString desc((*i)->description, wxConvUTF8);
315             const wxString auth((*i)->author, wxConvUTF8);
316             const wxString url((*i)->url, wxConvUTF8);
317             wxTreeItemId arcitem = this->fileTree->AppendItem(item, ext);
318             this->fileTree->AppendItem(arcitem, desc);
319             this->fileTree->AppendItem(arcitem, auth);
320             this->fileTree->AppendItem(arcitem, url);
321         } // for
322     } // else
323
324
325     // Fill in the standard paths...
326
327     item = this->fileTree->AppendItem(this->stateItem, wxT("Paths"));
328     str = wxT("Base directory: ");
329     str << quote << wxString(PHYSFS_getBaseDir(), wxConvUTF8) << quote;
330     this->fileTree->AppendItem(item, str);
331     str = wxT("User directory: ");
332     str << quote << wxString(PHYSFS_getUserDir(), wxConvUTF8) << quote;
333     this->fileTree->AppendItem(item, str);
334     str = wxT("Write directory: ");
335     if ((cstr = PHYSFS_getWriteDir()) == NULL)
336         str << wxT("(NULL)");
337     else
338         str << quote << wxString(cstr ? cstr : "(NULL)", wxConvUTF8) << quote;
339     this->fileTree->AppendItem(item, str);
340     //str = wxT("Preference directory: ");
341     //str << wxString(PHYSFS_getUserDir(), wxConvUTF8);
342     //this->fileTree->AppendItem(item, str);
343
344     // Fill in the CD-ROMs...
345
346     item = this->fileTree->AppendItem(this->stateItem, wxT("CD-ROMs"));
347     char **cds = PHYSFS_getCdRomDirs();
348     if (cds == NULL)
349     {
350         str = wxT("Error: ");
351         str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
352         wxTreeItemId id = this->fileTree->AppendItem(item, str);
353         this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
354     } // if
355     else
356     {
357         if (*cds == NULL)
358             this->fileTree->AppendItem(item, wxT("(none)"));
359         else
360         {
361             char **i;
362             for (i = cds; *i != NULL; i++)
363                 this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
364         } // else
365         PHYSFS_freeList(cds);
366     } // else
367
368     // Fill in search path...
369
370     item = this->fileTree->AppendItem(this->stateItem, wxT("Search path"));
371     char **sp = PHYSFS_getSearchPath();
372     if (sp == NULL)
373     {
374         str = wxT("Error: ");
375         str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
376         wxTreeItemId id = this->fileTree->AppendItem(item, str);
377         this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
378     } // if
379     else
380     {
381         if (*sp == NULL)
382             this->fileTree->AppendItem(item, wxT("(none)"));
383         else
384         {
385             char **i;
386             for (i = sp; *i != NULL; i++)
387                 this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
388         } // else
389         PHYSFS_freeList(sp);
390     } // else
391
392     // Now fill in the filesystem...
393
394     this->fsItem = this->fileTree->AppendItem(root, wxT("Filesystem"));
395     this->fillFileSystemTree("/", this->fsItem);
396     this->fileTree->Expand(this->fsItem);
397 } // WxTestPhysfsFrame::rebuildTree
398
399
400 void WxTestPhysfsFrame::doInit(const char *argv0)
401 {
402     if (!this->err(PHYSFS_init(argv0)))
403         ::wxMessageBox(wxT("PHYSFS_init() failed!"), wxT("wxTestPhysfs"));
404     this->rebuildTree();
405 } // WxTestPhysfsFrame::doInit
406
407
408 void WxTestPhysfsFrame::doDeinit()
409 {
410     if (!this->err(PHYSFS_deinit()))
411         ::wxMessageBox(wxT("PHYSFS_deinit() failed!"), wxT("wxTestPhysfs"));
412     this->rebuildTree();
413 } // WxTestPhysfsFrame::doDeinit
414
415
416 void WxTestPhysfsFrame::onMenuInit(wxCommandEvent &evt)
417 {
418     wxString argv0(wxGetApp().argv[0] == NULL ? wxT("") : wxGetApp().argv[0]);
419     wxString str(wxGetTextFromUser(wxT("PHYSFS_init"),
420                  wxT("argv[0]? (cancel for NULL)"), argv0));
421     char *cstr = str.IsEmpty() ? NULL : newutf8(str);
422     this->doInit(cstr);
423     delete[] cstr;
424 } // WxTestPhysfsFrame::onMenuInit
425
426
427 void WxTestPhysfsFrame::onMenuDeinit(wxCommandEvent &evt)
428 {
429     this->doDeinit();
430 } // WxTestPhysfsFrame::onMenuDeinit
431
432
433 void WxTestPhysfsFrame::onMenuAddArchive(wxCommandEvent &evt)
434 {
435     wxString arc = wxFileSelector(wxT("Choose archive to add"));
436     if (!arc.IsEmpty())
437     {
438         char *cstr = newutf8(arc);
439         // !!! FIXME: add to start/end?
440         if (!this->err(PHYSFS_addToSearchPath(cstr, 1)))
441             ::wxMessageBox(wxT("PHYSFS_addToSearchPath() failed!"), wxT("wxTestPhysfs"));
442         delete[] cstr;
443         this->rebuildTree();
444     } // if
445 } // WxTestPhysfsFrame::onMenuAddArchive
446
447
448 void WxTestPhysfsFrame::onMenuGetCDs(wxCommandEvent &evt)
449 {
450     this->rebuildTree();  // This will call PHYSFS_getCdRomDirs()...
451 } // WxTestPhysfsFrame::onMenuGetCDs
452
453
454 void WxTestPhysfsFrame::onMenuPermitSymLinks(wxCommandEvent &evt)
455 {
456     PHYSFS_permitSymbolicLinks(evt.IsChecked() ? 1 : 0);
457     this->rebuildTree();
458 } // WxTestPhysfsFrame::onMenuPermitSymLinks
459
460
461
462 IMPLEMENT_APP(WxTestPhysfsApp)
463
464 bool WxTestPhysfsApp::OnInit()
465 {
466     #if PLATFORM_MACOSX
467     // This lets a stdio app become a GUI app. Otherwise, you won't get
468     //  GUI events from the system and other things will fail to work.
469     // Putting the app in an application bundle does the same thing.
470     //  TransformProcessType() is a 10.3+ API. SetFrontProcess() is 10.0+.
471     if (TransformProcessType != NULL)  // check it as a weak symbol.
472     {
473         ProcessSerialNumber psn = { 0, kCurrentProcess };
474         TransformProcessType(&psn, kProcessTransformToForegroundApplication);
475         SetFrontProcess(&psn);
476     } // if
477     #endif
478
479     this->mainWindow = new WxTestPhysfsFrame(this->argv[0]);
480     this->mainWindow->Show(true);
481     SetTopWindow(this->mainWindow);
482     return true;
483 } // WxTestPhysfsApp::OnInit
484
485 // end of wxtest_physfs.cpp ...
486