parent
7f03c58cbf
commit
419776fc72
4 changed files with 186 additions and 1 deletions
|
|
@ -77,7 +77,7 @@ CFLAGS="$CFLAGS $SDL_CFLAGS ${SAMPLERATE_CFLAGS:-} ${PNG_CFLAGS:-}"
|
|||
LDFLAGS="$LDFLAGS $SDL_LIBS ${SAMPLERATE_LIBS:-} ${PNG_LIBS:-}"
|
||||
AC_CHECK_LIB(m, log)
|
||||
|
||||
AC_CHECK_HEADERS([linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
|
||||
AC_CHECK_HEADERS([dirent.h linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
|
||||
AC_CHECK_FUNCS(mmap ioperm)
|
||||
AC_CHECK_DECLS([strcasecmp, strncasecmp], [], [], [[#include <strings.h>]])
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ deh_str.c deh_str.h \
|
|||
gusconf.c gusconf.h \
|
||||
i_cdmus.c i_cdmus.h \
|
||||
i_endoom.c i_endoom.h \
|
||||
i_glob.c i_glob.h \
|
||||
i_input.c i_input.h \
|
||||
i_joystick.c i_joystick.h \
|
||||
i_swap.h \
|
||||
|
|
|
|||
148
src/i_glob.c
Normal file
148
src/i_glob.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
//
|
||||
// Copyright(C) 2018 Simon Howard
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//
|
||||
// File globbing API. This allows the contents of the filesystem
|
||||
// to be interrogated.
|
||||
//
|
||||
|
||||
// TODO: Merge win_opendir.[ch] into this file for MSVC implementation.
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "i_glob.h"
|
||||
#include "m_misc.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include "dirent.h"
|
||||
|
||||
struct glob_s
|
||||
{
|
||||
char *glob;
|
||||
DIR *dir;
|
||||
char *directory;
|
||||
char *last_filename;
|
||||
};
|
||||
|
||||
glob_t *I_StartGlob(const char *directory, const char *glob)
|
||||
{
|
||||
glob_t *result;
|
||||
|
||||
result = malloc(sizeof(glob_t));
|
||||
if (result == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result->dir = opendir(directory);
|
||||
if (result->dir == NULL)
|
||||
{
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result->directory = M_StringDuplicate(directory);
|
||||
result->glob = M_StringDuplicate(glob);
|
||||
result->last_filename = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
void I_EndGlob(glob_t *glob)
|
||||
{
|
||||
if (glob == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
free(glob->directory);
|
||||
free(glob->last_filename);
|
||||
free(glob->glob);
|
||||
(void) closedir(glob->dir);
|
||||
free(glob);
|
||||
}
|
||||
|
||||
static boolean MatchesGlob(const char *name, const char *glob)
|
||||
{
|
||||
while (*glob != '\0')
|
||||
{
|
||||
if (*glob == '*')
|
||||
{
|
||||
// To handle *-matching we skip past the * and recurse
|
||||
// to check each subsequent character in turn. If none
|
||||
// match then the whole match is a failure.
|
||||
while (*name != '\0')
|
||||
{
|
||||
if (MatchesGlob(name, glob + 1))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
++name;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (*glob != '?' && *name != *glob)
|
||||
{
|
||||
// For normal characters the name must match the glob,
|
||||
// but for ? we don't care what the character is.
|
||||
return false;
|
||||
}
|
||||
|
||||
++name;
|
||||
++glob;
|
||||
}
|
||||
|
||||
// Match successful when glob and name end at the same time.
|
||||
return *name == '\0';
|
||||
}
|
||||
|
||||
const char *I_NextGlob(glob_t *glob)
|
||||
{
|
||||
struct dirent *de;
|
||||
|
||||
do
|
||||
{
|
||||
de = readdir(glob->dir);
|
||||
if (de == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
} while (de->d_type != DT_REG || !MatchesGlob(de->d_name, glob->glob));
|
||||
|
||||
// Return the fully-qualified path, not just the bare filename.
|
||||
free(glob->last_filename);
|
||||
glob->last_filename = M_StringJoin(glob->directory, DIR_SEPARATOR_S,
|
||||
de->d_name, NULL);
|
||||
return glob->last_filename;
|
||||
}
|
||||
|
||||
#else /* #ifndef HAVE_DIRENT_H */
|
||||
|
||||
#warning No native implementation of file globbing.
|
||||
|
||||
glob_t *I_StartGlob(const char *directory, const char *glob)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void I_EndGlob(glob_t *glob)
|
||||
{
|
||||
}
|
||||
|
||||
const char *I_NextGlob(glob_t *glob)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif /* #ifndef HAVE_DIRENT_H */
|
||||
|
||||
36
src/i_glob.h
Normal file
36
src/i_glob.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Copyright(C) 2018 Simon Howard
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// System specific file globbing interface.
|
||||
//
|
||||
|
||||
|
||||
#ifndef __I_GLOB__
|
||||
#define __I_GLOB__
|
||||
|
||||
typedef struct glob_s glob_t;
|
||||
|
||||
// Start reading a list of file paths from the given directory which match
|
||||
// the given glob pattern. I_EndGlob() must be called on completion.
|
||||
glob_t *I_StartGlob(const char *directory, const char *glob);
|
||||
|
||||
// Finish reading file list.
|
||||
void I_EndGlob(glob_t *glob);
|
||||
|
||||
// Read the name of the next globbed filename. NULL is returned if there
|
||||
// are no more found.
|
||||
const char *I_NextGlob(glob_t *glob);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in a new issue