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. * CHANGELOG.
*/ */
04022007 - Added wxWidgets-based test program (incomplete).
04012007 - Added PHYSFS_isInit() and PHYSFS_symbolicLinksPermitted() functions. 04012007 - Added PHYSFS_isInit() and PHYSFS_symbolicLinksPermitted() functions.
03312007 - Added a quick'n'dirty unpack utility to the extras directory. Moved 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 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) SET_TARGET_PROPERTIES(physfs-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
ENDIF(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC) 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) MARK_AS_ADVANCED(PHYSFS_BUILD_TEST)
IF(PHYSFS_BUILD_TEST) IF(PHYSFS_BUILD_TEST)
CHECK_INCLUDE_FILE(readline/readline.h HAVE_READLINE_H) 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") SET(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";test_physfs")
ENDIF(PHYSFS_BUILD_TEST) 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} INSTALL(TARGETS ${PHYSFS_INSTALL_TARGETS}
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
LIBRARY DESTINATION lib 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 own zlib" PHYSFS_INTERNAL_ZLIB)
MESSAGE_BOOL_OPTION("Build static library" PHYSFS_BUILD_STATIC) MESSAGE_BOOL_OPTION("Build static library" PHYSFS_BUILD_STATIC)
MESSAGE_BOOL_OPTION("Build shared library" PHYSFS_BUILD_SHARED) 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) IF(PHYSFS_BUILD_TEST)
MESSAGE_BOOL_OPTION(" Use readline in test program" HAVE_SYSTEM_READLINE) MESSAGE_BOOL_OPTION(" Use readline in test program" HAVE_SYSTEM_READLINE)
ENDIF(PHYSFS_BUILD_TEST) 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 ...