[physfs] physfs tutorial AND BUGFIX

Robby Dermody robbyd at p9i.com
Thu Jan 15 14:23:01 EST 2004


Thanks Adam for the help. I got it working when I upgraded to 1.0.0, I'm
thinking it had to do with the version of zlib I was using with 0.1.9....

Ryan: Past that, there is a problem under cygwin that I submitted a fix to
before, but it didn't get added in. I'm not sure why, or if it even needs to
be added in. The problem is that under Cygwin, physfs is still using '\' as
the dir-seperator, not '/'. This breaks my command-line program under cygwin
(as, for example, "/home/test\bla\bla) . The fix is easy:

#ifdef __CYGWIN__
const char *__PHYSFS_platformDirSeparator = "/";
#else
const char *__PHYSFS_platformDirSeparator = "\\";
#endif

in win32.c at line 55.

However, I'm not sure if that's how you want to do this. I did notice that
what you had it before (\\) is valid under cygwin, but only under a certain
circumstance. It seems that \\ can not start the path. Thus:

cd \\etc
won't work (at least with my setup)
while cd /etc\\X11
will

You undoubtably know more about cygwin than I do, so please let me know if
you think this fix should be made.

Robby

----- Original Message ----- 
From: "Adam D. Moss" <adam at gimp.org>
To: <physfs at icculus.org>
Sent: Thursday, January 15, 2004 12:27 PM
Subject: Re: [physfs] physfs tutorial


> Robby Dermody wrote:
> > A quick question regarding physfs usage (probably something stupid I'm
> > missing). I'm using Cygwin and physfs 0.1.9 (looked at the function in
the
> > 1.0.0 source and it looks the same, I have a large project and it would
be a
> > pain switching to 1.0.0 at this time unless it fixes this)
> >
> > I initialized physfs fine, passed it argv[0] ("./gcm") which is the name
of
> > my program.
> >
> > The problem is that PHYSFS_AddToSearchPath() keeps returning a zero with
no
> > failure reason. I have my archive files residing in a different
directory
> > than my program.
> >
> > I call it with a archive path arg such as
> > "./../../respacks/built/TestTheme/theme.tff"
> >
> > Also, it doesn't work under test_physfs.exe as well:
> >
> > addarchive ../../respacks/built/TestTheme/resource/terrain.rff 0
> > Failure. reason: (null).
>
> It could be because PHYSFS_AddToSearchPath() takes a platform-
> specific path.  You could try using the attached function in your
> program as a substitute for PHYSFS_AddToSearchPath(); it instead
> adds the specified searchpath string that is:
> * relative to wherever the program binary is, and
> * in physfs-style (unix-style) platform-independant format.
>
> Regards,
> --Adam
> -- 
> Adam D. Moss   . ,,^^   adam at gimp.org   http://www.foxbox.org/   co:3
> "At this point the rocket becomes engorged with astronauts."
>


----------------------------------------------------------------------------
----


>
> int
> physfs_util_binrelative_add_to_searchpath(const char *newDir,
>   int appendToPath)
> {
> #define BATSP_STRSIZE 1000
>   const char *const basedir = PHYSFS_getBaseDir();
>   if (basedir && newDir) {
>     char c;
>     int ndpos = 0;
>     int dpos = 0;
>     const char *const sep = PHYSFS_getDirSeparator();
>     int seplen = strlen(sep);
>     char newname[BATSP_STRSIZE];
>     int dotdotcount = 0;
>
>     newname[BATSP_STRSIZE-1] = '\0'; /* a safeguard... */
>
>     if ('/' == newDir[0]) {
>       /* if newDir has been formulated like an absolute path then
> leave it relative to the pwd rather than the basedir, but
> still do the unix-directory-like munging. */
>       ++ndpos;
>     } else {
>       strncpy(&newname[dpos], basedir, BATSP_STRSIZE-1);
>       dpos += strlen(basedir);
>     }
>
>     do {
>       c = newDir[ndpos];
>
>       /* spot '../' or '..[END OF STRING]' */
>       if (0 == dotdotcount) {
> if ('.' == c) {
>   ++dotdotcount;
> } else {
>   dotdotcount = 0;
> }
>       } else if (1 == dotdotcount) {
> if ('.' == c) {
>   ++dotdotcount;
> } else {
>   dotdotcount = 0;
> }
>       } else if (2 == dotdotcount) {
> if ('\0' == c || '/' == c) {
>   ++dotdotcount;
> } else {
>   dotdotcount = 0;
> }
>       }
>
>       /* if we saw a '..' in the newDir then strip two directory
> levels off of newname (one to get rid of '..' and another to
> get rid of the preceding path segment that it nullifies). */
>       if (3 == dotdotcount) {
> int seen_seps = 0;
> /* iterate backwards past a dirseparator, until the character after
>    the dirseparator preceding that one. */
> --dpos;
> while (dpos >= (1 + seplen) &&
>        ! (1 == seen_seps &&
>   0 == strncmp(sep,&newname[dpos - seplen],seplen)) ) {
>   if (0 == strncmp(sep,&newname[dpos],seplen)) {
>     /* just passed a separator while iterating backwards */
>     ++seen_seps;
>   }
>   --dpos;
> }
> dotdotcount = 0;
>       } else {
> /* we didn't see '..' (yet); copy path chararcter as usual. */
> if ('/' != c) {
>   if (dpos < BATSP_STRSIZE-1) {
>     newname[dpos] = c;
>     ++dpos;
>   }
> } else {
>   /* it's a path separator (treat multiple successive slashes
>      as one); put the system-dependant separator into newname. */
>   if (ndpos >= 1 && '/' != newDir[ndpos-1]) {
>     int i = 0;
>     while (sep[i] != '\0') {
>       if (dpos < BATSP_STRSIZE-1) {
> newname[dpos] = sep[i];
> ++dpos;
>       }
>       ++i;
>     }
>   }
> }
>       }
>
>       ++ndpos;
>     } while ('\0' != c);
>     newname[dpos] = '\0'; /* be very confident that we've written
>      the string terminator... */
>     /*ZLOG(VERBOSE, "adding '%s'", newname);*/
>     return PHYSFS_addToSearchPath(newname, appendToPath);
>   } else {
>     return PHYSFS_addToSearchPath(newDir, appendToPath);
>   }
> #undef BATSP_STRSIZE
> }
>





More information about the physfs mailing list