Added initial work on a wxWidgets-based test app.

This commit is contained in:
Ryan C. Gordon 2007-04-02 20:57:39 +00:00
parent 0d45ce01c4
commit 40ab6d277f
3 changed files with 508 additions and 2 deletions

View File

@ -2,6 +2,7 @@
* CHANGELOG.
*/
04022007 - Added wxWidgets-based test program (incomplete).
04012007 - Added PHYSFS_isInit() and PHYSFS_symbolicLinksPermitted() functions.
03312007 - Added a quick'n'dirty unpack utility to the extras directory. Moved
DIR archiver to start of the list, so we don't have to have every

View File

@ -297,7 +297,7 @@ IF(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC)
SET_TARGET_PROPERTIES(physfs-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
ENDIF(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC)
OPTION(PHYSFS_BUILD_TEST "Build test program." TRUE)
OPTION(PHYSFS_BUILD_TEST "Build stdio test program." TRUE)
MARK_AS_ADVANCED(PHYSFS_BUILD_TEST)
IF(PHYSFS_BUILD_TEST)
CHECK_INCLUDE_FILE(readline/readline.h HAVE_READLINE_H)
@ -317,6 +317,24 @@ IF(PHYSFS_BUILD_TEST)
SET(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";test_physfs")
ENDIF(PHYSFS_BUILD_TEST)
OPTION(PHYSFS_BUILD_WX_TEST "Build wxWidgets test program." TRUE)
MARK_AS_ADVANCED(PHYSFS_BUILD_WX_TEST)
IF(PHYSFS_BUILD_WX_TEST)
SET(wxWidgets_USE_LIBS base core adv)
SET(wxWidgets_INCLUDE_DIRS_NO_SYSTEM 1)
FIND_PACKAGE(wxWidgets)
IF(wxWidgets_FOUND)
INCLUDE(${wxWidgets_USE_FILE})
ADD_EXECUTABLE(wxtest_physfs test/wxtest_physfs.cpp)
SET_SOURCE_FILES_PROPERTIES(test/wxtest_physfs.cpp COMPILE_FLAGS ${wxWidgets_CXX_FLAGS})
TARGET_LINK_LIBRARIES(wxtest_physfs ${PHYSFS_LIB_TARGET} ${wxWidgets_LIBRARIES} ${OTHER_LDFLAGS})
SET(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";wxtest_physfs")
ELSE(wxWidgets_FOUND)
MESSAGE(STATUS "wxWidgets not found. Disabling wx test app.")
SET(PHYSFS_BUILD_WX_TEST FALSE)
ENDIF(wxWidgets_FOUND)
ENDIF(PHYSFS_BUILD_WX_TEST)
INSTALL(TARGETS ${PHYSFS_INSTALL_TARGETS}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
@ -352,7 +370,8 @@ MESSAGE_BOOL_OPTION("Thread safety" PHYSFS_HAVE_THREAD_SUPPORT)
MESSAGE_BOOL_OPTION("Build own zlib" PHYSFS_INTERNAL_ZLIB)
MESSAGE_BOOL_OPTION("Build static library" PHYSFS_BUILD_STATIC)
MESSAGE_BOOL_OPTION("Build shared library" PHYSFS_BUILD_SHARED)
MESSAGE_BOOL_OPTION("Build test program" PHYSFS_BUILD_TEST)
MESSAGE_BOOL_OPTION("Build wxWidgets test program" PHYSFS_BUILD_WX_TEST)
MESSAGE_BOOL_OPTION("Build stdio test program" PHYSFS_BUILD_TEST)
IF(PHYSFS_BUILD_TEST)
MESSAGE_BOOL_OPTION(" Use readline in test program" HAVE_SYSTEM_READLINE)
ENDIF(PHYSFS_BUILD_TEST)

486
test/wxtest_physfs.cpp Normal file
View File

@ -0,0 +1,486 @@
/**
* Test program for PhysicsFS, using wxWidgets. May only work on Unix.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#if ( (defined(__MACH__)) && (defined(__APPLE__)) )
#define PLATFORM_MACOSX 1
#include <Carbon/Carbon.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <wx/wx.h>
#include <wx/treectrl.h>
#include "physfs.h"
#define TEST_VER_MAJOR 1
#define TEST_VER_MINOR 1
#define TEST_VER_PATCH 1
//static PHYSFS_uint32 do_buffer_size = 0;
enum WxTestPhysfsMenuCommands
{
// start with standard menu items, since using the wxIDs will map them
// to sane things in the platform's UI (gnome icons in GTK+, moves the
// about and quit items to the Apple menu on Mac OS X, etc).
MENUCMD_About = wxID_ABOUT,
MENUCMD_Quit = wxID_EXIT,
// non-standard menu items go here.
MENUCMD_Init = wxID_HIGHEST,
MENUCMD_Deinit,
MENUCMD_AddArchive,
MENUCMD_Mount,
MENUCMD_Remove,
MENUCMD_GetCDs,
MENUCMD_SetWriteDir,
MENUCMD_PermitSymLinks,
MENUCMD_SetSaneConfig,
MENUCMD_MkDir,
MENUCMD_Delete,
MENUCMD_Cat,
MENUCMD_SetBuffer,
MENUCMD_StressBuffer,
MENUCMD_Append,
MENUCMD_Write,
MENUCMD_GetLastError,
/*
{ "getdirsep", cmd_getdirsep, 0, NULL },
{ "getsearchpath", cmd_getsearchpath, 0, NULL },
{ "getbasedir", cmd_getbasedir, 0, NULL },
{ "getuserdir", cmd_getuserdir, 0, NULL },
{ "getwritedir", cmd_getwritedir, 0, NULL },
{ "getrealdir", cmd_getrealdir, 1, "<fileToFind>" },
{ "exists", cmd_exists, 1, "<fileToCheck>" },
{ "isdir", cmd_isdir, 1, "<fileToCheck>" },
{ "issymlink", cmd_issymlink, 1, "<fileToCheck>" },
{ "filelength", cmd_filelength, 1, "<fileToCheck>" },
{ "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>" },
*/
};
class WxTestPhysfsFrame : public wxFrame
{
public:
WxTestPhysfsFrame(const wxChar *argv0);
void rebuildTree();
void onMenuInit(wxCommandEvent &evt);
void onMenuDeinit(wxCommandEvent &evt);
void onMenuAddArchive(wxCommandEvent &evt);
void onMenuGetCDs(wxCommandEvent &evt);
void onMenuPermitSymLinks(wxCommandEvent &evt);
private:
wxTreeCtrl *fileTree;
wxTreeItemId stateItem;
wxTreeItemId fsItem;
int err(int success);
void fillFileSystemTree(const char *path, const wxTreeItemId &item);
void doInit(const char *argv0);
void doDeinit();
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(WxTestPhysfsFrame, wxFrame)
EVT_MENU(MENUCMD_Init, WxTestPhysfsFrame::onMenuInit)
EVT_MENU(MENUCMD_Deinit, WxTestPhysfsFrame::onMenuDeinit)
EVT_MENU(MENUCMD_AddArchive, WxTestPhysfsFrame::onMenuAddArchive)
EVT_MENU(MENUCMD_GetCDs, WxTestPhysfsFrame::onMenuGetCDs)
EVT_MENU(MENUCMD_PermitSymLinks, WxTestPhysfsFrame::onMenuPermitSymLinks)
END_EVENT_TABLE()
// This is the the Application itself.
class WxTestPhysfsApp : public wxApp
{
public:
WxTestPhysfsApp() : mainWindow(NULL) { /* no-op. */ }
virtual bool OnInit();
private:
WxTestPhysfsFrame *mainWindow;
};
DECLARE_APP(WxTestPhysfsApp)
static inline char *newstr(const char *str)
{
char *retval = NULL;
if (str != NULL)
{
retval = new char[strlen(str) + 1];
strcpy(retval, str);
} // if
return retval;
} // newstr
static char *newutf8(const wxString &wxstr)
{
#if wxUSE_UNICODE
size_t len = wxstr.Len() + 1;
char *utf8text = new char[len * 6];
wxConvUTF8.WC2MB(utf8text, wxstr, len);
return utf8text;
#else
return newstr(wxstr);
#endif
} // newutf8
WxTestPhysfsFrame::WxTestPhysfsFrame(const wxChar *argv0)
: wxFrame(NULL, -1, wxT("WxTestPhysfs"))
{
this->CreateStatusBar();
wxMenuBar *menuBar = new wxMenuBar;
wxMenu *stuffMenu = new wxMenu;
stuffMenu->Append(MENUCMD_Init, wxT("&Init"));
stuffMenu->Append(MENUCMD_Deinit, wxT("&Deinit"));
stuffMenu->Append(MENUCMD_AddArchive, wxT("&Add Archive"));
stuffMenu->Append(MENUCMD_Mount, wxT("&Mount Archive"));
stuffMenu->Append(MENUCMD_Remove, wxT("&Remove Archive"));
stuffMenu->Append(MENUCMD_GetCDs, wxT("&Get CD-ROM drives"));
stuffMenu->Append(MENUCMD_SetWriteDir, wxT("&Set Write Dir"));
stuffMenu->Append(MENUCMD_SetSaneConfig, wxT("Set Sane &Config"));
stuffMenu->Append(MENUCMD_MkDir, wxT("M&kDir"));
stuffMenu->Append(MENUCMD_Delete, wxT("D&elete"));
stuffMenu->Append(MENUCMD_Cat, wxT("&Cat"));
stuffMenu->Append(MENUCMD_SetBuffer, wxT("Set &Buffer"));
stuffMenu->Append(MENUCMD_StressBuffer, wxT("Stress &Test Buffer"));
stuffMenu->Append(MENUCMD_Append, wxT("&Append"));
stuffMenu->Append(MENUCMD_Write, wxT("&Write"));
stuffMenu->Append(MENUCMD_Write, wxT("&Update getLastError"));
stuffMenu->AppendCheckItem(MENUCMD_PermitSymLinks, wxT("&Permit symlinks"));
menuBar->Append(stuffMenu, wxT("&Stuff"));
//wxMenu *helpMenu = new wxMenu;
//helpMenu->Append(MENUCMD_About, wxT("&About\tF1"));
//menuBar->Append(helpMenu, wxT("&Help"));
this->SetMenuBar(menuBar);
this->fileTree = new wxTreeCtrl(this, -1);
// The sizer just makes sure that fileTree owns whole client area.
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(this->fileTree, 1, wxALL | wxEXPAND | wxALIGN_CENTRE);
sizer->SetItemMinSize(this->fileTree, 1, 1);
this->SetSizer(sizer);
char *utf8argv0 = newutf8(wxString(argv0));
this->doInit(utf8argv0);
delete[] utf8argv0;
} // WxTestPhysfsFrame::WxTestPhysfsFrame
int WxTestPhysfsFrame::err(int success)
{
if (success)
this->SetStatusText(wxT(""));
else
this->SetStatusText(wxString(PHYSFS_getLastError(), wxConvUTF8));
return success;
} // WxTestPhysfsFrame::err
void WxTestPhysfsFrame::fillFileSystemTree(const char *path,
const wxTreeItemId &item)
{
char **rc = PHYSFS_enumerateFiles(path);
char **i;
wxTreeItemId id;
if (rc == NULL)
{
const wxString quote(wxT("'"));
wxString str(wxT("Enumeration error: "));
str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
id = this->fileTree->AppendItem(item, str);
this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
} // if
else
{
for (i = rc; *i != NULL; i++)
{
id = this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
const int len = strlen(path) + strlen(*i) + 2;
char *fname = new char[len];
const char *origdir = path;
if (strcmp(origdir, "/") == 0)
origdir = "";
snprintf(fname, len, "%s/%s", origdir, *i);
if (PHYSFS_isDirectory(fname))
{
this->fileTree->SetItemTextColour(id, wxColour(0, 0, 255));
this->fillFileSystemTree(fname, id);
} // if
else if (PHYSFS_isSymbolicLink(fname))
{
this->fileTree->SetItemTextColour(id, wxColour(0, 255, 0));
} // else if
else // ...file.
{
} // else
delete[] fname;
} // for
PHYSFS_freeList(rc);
} // else
} // fillFileSystemTree
void WxTestPhysfsFrame::rebuildTree()
{
const wxString dot(wxT("."));
const wxString quote(wxT("'"));
wxTreeItemId item;
wxString str;
const char *cstr = NULL;
const bool wasInit = PHYSFS_isInit() ? true : false;
this->fileTree->DeleteAllItems();
wxTreeItemId root = this->fileTree->AddRoot(wxT("PhysicsFS"));
this->stateItem = this->fileTree->AppendItem(root, wxT("Library state"));
str = wxT("Initialized: ");
str << ((wasInit) ? wxT("true") : wxT("false"));
this->fileTree->AppendItem(this->stateItem, str);
this->fileTree->Expand(this->stateItem);
this->fileTree->Expand(root);
// Fill in version information...
PHYSFS_Version ver;
item = this->stateItem;
str = wxT("wxtest_physfs version: ");
str << TEST_VER_MAJOR << dot << TEST_VER_MINOR << dot << TEST_VER_PATCH;
this->fileTree->AppendItem(item, str);
PHYSFS_VERSION(&ver);
str = wxT("Compiled against PhysicsFS version: ");
str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
this->fileTree->AppendItem(item, str);
PHYSFS_getLinkedVersion(&ver);
str = wxT("Linked against PhysicsFS version: ");
str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
this->fileTree->AppendItem(item, str);
if (!wasInit)
return; // nothing else to do before initialization...
str = wxT("Symbolic links permitted: ");
str << ((PHYSFS_symbolicLinksPermitted()) ? wxT("true") : wxT("false"));
this->fileTree->AppendItem(this->stateItem, str);
str = wxT("Native directory separator: ");
str << quote << wxString(PHYSFS_getDirSeparator(), wxConvUTF8) << quote;
this->fileTree->AppendItem(this->stateItem, str);
// Fill in supported archives...
item = this->fileTree->AppendItem(this->stateItem, wxT("Archivers"));
const PHYSFS_ArchiveInfo **arcs = PHYSFS_supportedArchiveTypes();
if (*arcs == NULL)
this->fileTree->AppendItem(item, wxT("(none)"));
else
{
const PHYSFS_ArchiveInfo **i;
for (i = arcs; *i != NULL; i++)
{
const wxString ext((*i)->extension, wxConvUTF8);
const wxString desc((*i)->description, wxConvUTF8);
const wxString auth((*i)->author, wxConvUTF8);
const wxString url((*i)->url, wxConvUTF8);
wxTreeItemId arcitem = this->fileTree->AppendItem(item, ext);
this->fileTree->AppendItem(arcitem, desc);
this->fileTree->AppendItem(arcitem, auth);
this->fileTree->AppendItem(arcitem, url);
} // for
} // else
// Fill in the standard paths...
item = this->fileTree->AppendItem(this->stateItem, wxT("Paths"));
str = wxT("Base directory: ");
str << quote << wxString(PHYSFS_getBaseDir(), wxConvUTF8) << quote;
this->fileTree->AppendItem(item, str);
str = wxT("User directory: ");
str << quote << wxString(PHYSFS_getUserDir(), wxConvUTF8) << quote;
this->fileTree->AppendItem(item, str);
str = wxT("Write directory: ");
if ((cstr = PHYSFS_getWriteDir()) == NULL)
str << wxT("(NULL)");
else
str << quote << wxString(cstr ? cstr : "(NULL)", wxConvUTF8) << quote;
this->fileTree->AppendItem(item, str);
//str = wxT("Preference directory: ");
//str << wxString(PHYSFS_getUserDir(), wxConvUTF8);
//this->fileTree->AppendItem(item, str);
// Fill in the CD-ROMs...
item = this->fileTree->AppendItem(this->stateItem, wxT("CD-ROMs"));
char **cds = PHYSFS_getCdRomDirs();
if (cds == NULL)
{
str = wxT("Error: ");
str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
wxTreeItemId id = this->fileTree->AppendItem(item, str);
this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
} // if
else
{
if (*cds == NULL)
this->fileTree->AppendItem(item, wxT("(none)"));
else
{
char **i;
for (i = cds; *i != NULL; i++)
this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
} // else
PHYSFS_freeList(cds);
} // else
// Fill in search path...
item = this->fileTree->AppendItem(this->stateItem, wxT("Search path"));
char **sp = PHYSFS_getSearchPath();
if (sp == NULL)
{
str = wxT("Error: ");
str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
wxTreeItemId id = this->fileTree->AppendItem(item, str);
this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
} // if
else
{
if (*sp == NULL)
this->fileTree->AppendItem(item, wxT("(none)"));
else
{
char **i;
for (i = sp; *i != NULL; i++)
this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
} // else
PHYSFS_freeList(sp);
} // else
// Now fill in the filesystem...
this->fsItem = this->fileTree->AppendItem(root, wxT("Filesystem"));
this->fillFileSystemTree("/", this->fsItem);
this->fileTree->Expand(this->fsItem);
} // WxTestPhysfsFrame::rebuildTree
void WxTestPhysfsFrame::doInit(const char *argv0)
{
if (!this->err(PHYSFS_init(argv0)))
::wxMessageBox(wxT("PHYSFS_init() failed!"), wxT("wxTestPhysfs"));
this->rebuildTree();
} // WxTestPhysfsFrame::doInit
void WxTestPhysfsFrame::doDeinit()
{
if (!this->err(PHYSFS_deinit()))
::wxMessageBox(wxT("PHYSFS_deinit() failed!"), wxT("wxTestPhysfs"));
this->rebuildTree();
} // WxTestPhysfsFrame::doDeinit
void WxTestPhysfsFrame::onMenuInit(wxCommandEvent &evt)
{
wxString argv0(wxGetApp().argv[0] == NULL ? wxT("") : wxGetApp().argv[0]);
wxString str(wxGetTextFromUser(wxT("PHYSFS_init"),
wxT("argv[0]? (cancel for NULL)"), argv0));
char *cstr = str.IsEmpty() ? NULL : newutf8(str);
this->doInit(cstr);
delete[] cstr;
} // WxTestPhysfsFrame::onMenuInit
void WxTestPhysfsFrame::onMenuDeinit(wxCommandEvent &evt)
{
this->doDeinit();
} // WxTestPhysfsFrame::onMenuDeinit
void WxTestPhysfsFrame::onMenuAddArchive(wxCommandEvent &evt)
{
wxString arc = wxFileSelector(wxT("Choose archive to add"));
if (!arc.IsEmpty())
{
char *cstr = newutf8(arc);
// !!! FIXME: add to start/end?
if (!this->err(PHYSFS_addToSearchPath(cstr, 1)))
::wxMessageBox(wxT("PHYSFS_addToSearchPath() failed!"), wxT("wxTestPhysfs"));
delete[] cstr;
this->rebuildTree();
} // if
} // WxTestPhysfsFrame::onMenuAddArchive
void WxTestPhysfsFrame::onMenuGetCDs(wxCommandEvent &evt)
{
this->rebuildTree(); // This will call PHYSFS_getCdRomDirs()...
} // WxTestPhysfsFrame::onMenuGetCDs
void WxTestPhysfsFrame::onMenuPermitSymLinks(wxCommandEvent &evt)
{
PHYSFS_permitSymbolicLinks(evt.IsChecked() ? 1 : 0);
this->rebuildTree();
} // WxTestPhysfsFrame::onMenuPermitSymLinks
IMPLEMENT_APP(WxTestPhysfsApp)
bool WxTestPhysfsApp::OnInit()
{
#if PLATFORM_MACOSX
// This lets a stdio app become a GUI app. Otherwise, you won't get
// GUI events from the system and other things will fail to work.
// Putting the app in an application bundle does the same thing.
// TransformProcessType() is a 10.3+ API. SetFrontProcess() is 10.0+.
if (TransformProcessType != NULL) // check it as a weak symbol.
{
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
} // if
#endif
this->mainWindow = new WxTestPhysfsFrame(this->argv[0]);
this->mainWindow->Show(true);
SetTopWindow(this->mainWindow);
return true;
} // WxTestPhysfsApp::OnInit
// end of wxtest_physfs.cpp ...