extras/globbing.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 11 Jun 2003 09:05:47 +0000
changeset 575 3bf69b30fe74
parent 573 01112353ffad
child 576 5da65f8e9a50
permissions -rw-r--r--
Fixes for corner cases (thanks, Bradley!)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
573
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
/** \file globbing.c */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
#include <stdio.h>
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
#include <stdlib.h>
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
#include <string.h>
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     6
#include <ctype.h>
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
#include "physfs.h"
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
#include "globbing.h"
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    10
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    11
/**
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    12
 * Please see globbing.h for details.
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    13
 *
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    14
 * License: this code is public domain. I make no warranty that it is useful,
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    15
 *  correct, harmless, or environmentally safe.
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    16
 *
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    17
 * This particular file may be used however you like, including copying it
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    18
 *  verbatim into a closed-source project, exploiting it commercially, and
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    19
 *  removing any trace of my name from the source (although I hope you won't
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    20
 *  do that). I welcome enhancements and corrections to this file, but I do
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    21
 *  not require you to send me patches if you make changes.
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    22
 *
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    23
 * Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    24
 *  General Public License: http://www.gnu.org/licenses/lgpl.txt
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    25
 *
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    26
 *  \author Ryan C. Gordon.
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    27
 */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    28
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    29
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    30
static int matchesPattern(const char *fname, const char *wildcard,
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    31
                          int caseSensitive)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    32
{
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    33
    char x, y;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    34
    const char *fnameptr = fname;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    35
    const char *wildptr = wildcard;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    36
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
    while ((*wildptr) && (*fnameptr))
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    38
    {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    39
        y = *wildptr;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    40
        if (y == '*')
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    41
        {
575
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    42
            do
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    43
            {
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    44
                wildptr++;  /* skip multiple '*' in a row... */
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    45
            } while (*wildptr == '*');
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    46
573
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    47
            y = (caseSensitive) ? *wildptr : (char) tolower(*wildptr);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    48
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
            while (1)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
            {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    51
                x = (caseSensitive) ? *fnameptr : (char) tolower(*fnameptr);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
                if ((!x) || (x == y))
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
                    break;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    54
                else
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    55
                    fnameptr++;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    56
            } /* while */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    57
        } /* if */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    58
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    59
        else if (y == '?')
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    60
        {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    61
            wildptr++;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    62
            fnameptr++;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
        } /* else if */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    64
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    65
        else
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    66
        {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    67
            if (caseSensitive)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
                x = *fnameptr;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    69
            else
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
            {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    71
                x = tolower(*fnameptr);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    72
                y = tolower(y);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    73
            } /* if */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    75
            wildptr++;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
            fnameptr++;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
            if (x != y)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    79
                return(0);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    80
        } /* else */
575
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    81
    } /* while */
573
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    82
575
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    83
    while (*wildptr == '*')
3bf69b30fe74 Fixes for corner cases (thanks, Bradley!)
Ryan C. Gordon <icculus@icculus.org>
parents: 573
diff changeset
    84
        wildptr++;
573
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    85
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    86
    return(*fnameptr == *wildptr);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    87
} /* matchesPattern */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    89
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
char **PHYSFSEXT_enumerateFilesWildcard(const char *dir, const char *wildcard,
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    91
                                        int caseSensitive)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
{
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
    char **rc = PHYSFS_enumerateFiles(dir);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    94
    char **i = rc;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
    char **j;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    96
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    97
    while (*i != NULL)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
    {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    99
        if (matchesPattern(*i, wildcard, caseSensitive))
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   100
            i++;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   101
        else
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   102
        {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   103
            /* FIXME: This counts on physfs's allocation method not changing! */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
            free(*i);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   105
            for (j = i; *j != NULL; j++)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   106
                j[0] = j[1];
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   107
        } /* else */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   108
    } /* for */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   109
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   110
    return(rc);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   111
} /* PHYSFSEXT_enumerateFilesWildcard */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   112
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   113
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   114
#ifdef TEST_PHYSFSEXT_ENUMERATEFILESWILDCARD
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   115
int main(int argc, char **argv)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   116
{
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   117
    int rc;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   118
    char **flist;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   119
    char **i;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   120
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   121
    if (argc != 3)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   122
    {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   123
        printf("USAGE: %s <pattern> <caseSen>\n"
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   124
               "   where <caseSen> is 1 or 0.\n", argv[0]);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   125
        return(1);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   126
    } /* if */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   127
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   128
    if (!PHYSFS_init(argv[0]))
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   129
    {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   130
        fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   131
        return(1);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   132
    } /* if */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   133
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   134
    if (!PHYSFS_addToSearchPath(".", 1))
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   135
    {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   136
        fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   137
        PHYSFS_deinit();
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   138
        return(1);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   139
    } /* if */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   140
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   141
    flist = PHYSFSEXT_enumerateFilesWildcard("/", argv[1], atoi(argv[2]));
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   142
    rc = 0;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   143
    for (i = flist; *i; i++)
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   144
    {
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   145
        printf("%s\n", *i);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   146
        rc++;
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
    } /* for */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   148
    printf("\n  total %d files.\n\n", rc);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   149
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   150
    PHYSFS_freeList(flist);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   151
    PHYSFS_deinit();
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   152
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   153
    return(0);
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   154
} /* main */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   155
#endif
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   156
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   157
/* end of globbing.c ... */
01112353ffad First stab at globbing extension.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   158