[physfs] Getting every instance of overlapping files

Haydn Harach hharach at gmail.com
Tue Aug 26 11:51:39 EDT 2014


Now I'm having trouble rebuilding the project.  I'm trying to use a
code::blocks project which I generated with cmake, changing only the 2
files (physfs.c and physfs.h).  It compiles and builds just fine, but I'm
getting "undefined reference to PHYSFS_closeList" now.  What did I do wrong?


On Mon, Aug 25, 2014 at 6:55 PM, Haydn Harach <hharach at gmail.com> wrote:

> Alrighty, here are the additions I've made to my physfs.c:
>
> PHYSFS_File **PHYSFS_openReadMulti(const char *_fname)
> {
>     char *fname;
>     size_t len;
>
>     BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
>     len = strlen(_fname) + 1;
>     fname = (char *) __PHYSFS_smallAlloc(len);
>     BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
>
>     FileHandle** ret = NULL;
>     unsigned int retcount = 0;
>
>     if (sanitizePlatformIndependentPath(_fname, fname))
>     {
>         int fileExists = 0;
>         DirHandle *i = NULL;
>         fvoid *opaque = NULL;
>
>         __PHYSFS_platformGrabMutex(stateLock);
>
>         GOTO_IF_MACRO(!searchPath, ERR_NO_SUCH_PATH, openReadEnd);
>
>         /* !!! FIXME: Why aren't we using a for loop here? */
>         i = searchPath;
>
>         do
>         {
>             char *arcfname = fname;
>             if (verifyPath(i, &arcfname, 0))
>             {
>                 opaque = i->funcs->openRead(i->opaque, arcfname,
> &fileExists);
>                 if (opaque)
>                 {
>                    // We found a valid file, let's prepare it.
>                    FileHandle* h =
> (FileHandle*)allocator.Malloc(sizeof(FileHandle));
>                    if (h == NULL)
>                    {
>                       i->funcs->fileClose(opaque);
>                         GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
>                    }
>                    memset(h, 0, sizeof(FileHandle));
>                    h->opaque = opaque;
>                    h->forReading = 1;
>                    h->dirHandle = i;
>                    h->funcs = i->funcs;
>                    h->next = openReadList;
>                    openReadList = h;
>
>                      // Add the file to the list
>                      FileHandle** temp =
> (FileHandle**)allocator.Malloc(sizeof(FileHandle) * (retcount + 1));
>                      if (temp == NULL)
>                      {
>                         allocator.Free(h);
>                         i->funcs->fileClose(opaque);
>                         GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
>                      }
>                      if (ret != NULL)
>                      {
>                         memcpy(temp, ret, sizeof(FileHandle) * retcount);
>                         allocator.Free(ret);
>                      }
>                      temp[retcount] = h;
>                      ++retcount;
>                      ret = temp;
>                 }
>             } /* if */
>             i = i->next;
>         } while ((i != NULL) && (!fileExists));
>
>         // Add a null terminator to the list
>         if (ret != NULL)
>         {
>            FileHandle** temp =
> (FileHandle**)allocator.Malloc(sizeof(FileHandle) * (retcount + 1));
>            if (temp == NULL)
>                GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
>
>             memcpy(temp, ret, sizeof(FileHandle) * retcount);
>             allocator.Free(ret);
>
>             temp[retcount] = NULL;
>             ret = temp;
>         }
>
>         openReadEnd:
>         __PHYSFS_platformReleaseMutex(stateLock);
>     } /* if */
>
>     __PHYSFS_smallFree(fname);
>     return ret;
> } /* PHYSFS_openReadMulti */
>
> int PHYSFS_closeList(PHYSFS_file** list)
> {
>    int retval = 1;
>
>    for (PHYSFS_file** i = list; *i != NULL; ++i)
>    {
>       if (PHYSFS_close(*i) == 0)
>          retval = 0;
>    }
>
>    allocator.Free(list);
>    return retval;
> }
>
> Is there anything not immediately obvious that I'm missing?
>
>
> On Mon, Aug 25, 2014 at 6:11 PM, Edward Rudd <urkle at outoforder.cc> wrote:
>
>> On Aug 25, 2014, at 8:06 PM, Haydn Harach <hharach at gmail.com> wrote:
>>
>> > Looking at PHYSFS_openRead() in physfs.c, I've found this little
>> snippet:
>> >
>> > do
>> >         {
>> >             char *arcfname = fname;
>> >             if (verifyPath(i, &arcfname, 0))
>> >             {
>> >                 opaque = i->funcs->openRead(i->opaque, arcfname,
>> &fileExists);
>> >                 if (opaque)
>> >                     break;
>> >             } /* if */
>> >             i = i->next;
>> >         } while ((i != NULL) && (!fileExists));
>> >
>> > Now, from what I can see, this loop goes through all the paths, and the
>> first one that satisfies the function and returns some data (from the
>> openRead function) and causes 'opaque' to not be NULL, and thus breaks out
>> of the loop.
>> >
>> > So, if I replaced "if (opaque) break;" with "if (opaque)
>> someVector.emplace_back(opaque, i);", then did some cleanup to ensure that
>> I have a vector of FileHandle's instead of one, and return that, this
>> should be exactly what I'm looking for, yes?
>>
>> More or less, yes that would be exactly what you were looking for.
>> _______________________________________________
>> physfs mailing list
>> physfs at icculus.org
>> http://icculus.org/mailman/listinfo/physfs
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://icculus.org/pipermail/physfs/attachments/20140826/f389f6ba/attachment.html>


More information about the physfs mailing list