Cleanup in lib/listdir.c - xforms.git - xforms

index : xforms.git
xforms
summary refs log tree commit diff
diff options
context:
space:
mode:
authorJens Thoms Toerring <jt@toerring.de>2015年03月14日 22:29:07 +0100
committerJens Thoms Toerring <jt@toerring.de>2015年03月14日 22:29:07 +0100
commit21aa9a88ab461a71f40b2ed2202d77d7c289c3b6 (patch)
treec942a75419cc51560dd6094f70549ebee53a98ff
parentcca9dbdbaed4e37f37a763bea2d1e3b714f5c971 (diff)
downloadxforms-21aa9a88ab461a71f40b2ed2202d77d7c289c3b6.tar.gz
Cleanup in lib/listdir.c
Diffstat
-rw-r--r--demos/dirlist.c 11
-rwxr-xr-xdemos/positioner_overlay 228
-rw-r--r--doc/part1_goodies.texi 29
-rw-r--r--lib/fselect.c 24
-rw-r--r--lib/listdir.c 229
5 files changed, 150 insertions, 371 deletions
diff --git a/demos/dirlist.c b/demos/dirlist.c
index 931e56e..c03a265 100644
--- a/demos/dirlist.c
+++ b/demos/dirlist.c
@@ -53,16 +53,15 @@ fill_browser( FL_OBJECT * ob )
fl_set_object_label( fdui->total, buf );
fl_clear_browser( fdui->browser );
- for ( ds = dl; dl < dlend; dl++ )
+ for ( ds = dl; ds < dlend; ds++ )
{
- sprintf( buf, "%-10s\t\t%5ldK\t%s", dl->name, dl->dl_size >> 10,
- ctime( &dl->dl_mtime ) + 3 );
+ sprintf( buf, "%-20s\t\t%5ldK\t%s", ds->name, ds->dl_size >> 10,
+ ctime( &ds->dl_mtime ) + 3 );
fl_addto_browser_chars( fdui->browser, buf );
}
+ fl_free_dirlist( dl );
fl_unfreeze_form( ob->form );
-
- fl_free_dirlist( ( FL_Dirlist * ) ds );
}
@@ -101,7 +100,7 @@ main( int argc,
{
FD_fbform *fd_fbform;
- fl_initialize( &argc, argv, 0, 0, 0 );
+ fl_initialize( &argc, argv, "FormDemo", NULL, 0 );
fd_fbform = create_form_fbform( );
fl_set_browser_fontstyle( fd_fbform->browser, FL_FIXED_STYLE );
diff --git a/demos/positioner_overlay b/demos/positioner_overlay
deleted file mode 100755
index 0852d87..0000000
--- a/demos/positioner_overlay
+++ /dev/null
@@ -1,228 +0,0 @@
-#! /bin/bash
-
-# positioner_overlay - temporary wrapper script for .libs/positioner_overlay
-# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1
-#
-# The positioner_overlay program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\([`"$\\]\)/\\1円/g'
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-relink_command="(cd /home/jens/Programming/XForms/xforms/demos; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; LD_LIBRARY_PATH=:/home/jens/Programming/P/Yaba/yaba/; export LD_LIBRARY_PATH; PATH=/home/jens/Tools/Android/adt/sdk/tools:/home/jens/Tools/Android/adt/sdk/platform-tools:/home/jens/bin:/usr/local/bin:/usr/bin:/bin:/usr/games:/home/jens/bin:/sbin; export PATH; gcc -g -O0 -W -Wall -o \$progdir/\$file positioner_overlay.o ../lib/.libs/libforms.so -lSM -lICE -lc -lm -Wl,-rpath -Wl,/home/jens/Programming/XForms/xforms/lib/.libs)"
-
-# This environment variable determines our operation mode.
-if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
- # install mode needs the following variables:
- generated_by_libtool_version='2.4.2'
- notinst_deplibs=' ../lib/libforms.la'
-else
- # When we are sourced in execute mode, $file and $ECHO are already set.
- if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
- file="0ドル"
-
-# A function that is used when there is no print builtin or printf.
-func_fallback_echo ()
-{
- eval 'cat <<_LTECHO_EOF
-1ドル
-_LTECHO_EOF'
-}
- ECHO="printf %s\\n"
- fi
-
-# Very basic option parsing. These options are (a) specific to
-# the libtool wrapper, (b) are identical between the wrapper
-# /script/ and the wrapper /executable/ which is used only on
-# windows platforms, and (c) all begin with the string --lt-
-# (application programs are unlikely to have options which match
-# this pattern).
-#
-# There are only two supported options: --lt-debug and
-# --lt-dump-script. There is, deliberately, no --lt-help.
-#
-# The first argument to this parsing function should be the
-# script's ../libtool value, followed by no.
-lt_option_debug=
-func_parse_lt_options ()
-{
- lt_script_arg0=0ドル
- shift
- for lt_opt
- do
- case "$lt_opt" in
- --lt-debug) lt_option_debug=1 ;;
- --lt-dump-script)
- lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
- test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
- lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
- cat "$lt_dump_D/$lt_dump_F"
- exit 0
- ;;
- --lt-*)
- $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
- exit 1
- ;;
- esac
- done
-
- # Print the debug banner immediately:
- if test -n "$lt_option_debug"; then
- echo "positioner_overlay:positioner_overlay:${LINENO}: libtool wrapper (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1" 1>&2
- fi
-}
-
-# Used when --lt-debug. Prints its arguments to stdout
-# (redirection is the responsibility of the caller)
-func_lt_dump_args ()
-{
- lt_dump_args_N=1;
- for lt_arg
- do
- $ECHO "positioner_overlay:positioner_overlay:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
- lt_dump_args_N=`expr $lt_dump_args_N + 1`
- done
-}
-
-# Core function for launching the target application
-func_exec_program_core ()
-{
-
- if test -n "$lt_option_debug"; then
- $ECHO "positioner_overlay:positioner_overlay:${LINENO}: newargv[0]: $progdir/$program" 1>&2
- func_lt_dump_args ${1+"$@"} 1>&2
- fi
- exec "$progdir/$program" ${1+"$@"}
-
- $ECHO "0ドル: cannot exec $program $*" 1>&2
- exit 1
-}
-
-# A function to encapsulate launching the target application
-# Strips options in the --lt-* namespace from $@ and
-# launches target application with the remaining arguments.
-func_exec_program ()
-{
- case " $* " in
- *\ --lt-*)
- for lt_wr_arg
- do
- case $lt_wr_arg in
- --lt-*) ;;
- *) set x "$@" "$lt_wr_arg"; shift;;
- esac
- shift
- done ;;
- esac
- func_exec_program_core ${1+"$@"}
-}
-
- # Parse options
- func_parse_lt_options "0ドル" ${1+"$@"}
-
- # Find the directory that this script lives in.
- thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
- test "x$thisdir" = "x$file" && thisdir=.
-
- # Follow symbolic links until we get to the real thisdir.
- file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
- while test -n "$file"; do
- destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
-
- # If there was a directory component, then change thisdir.
- if test "x$destdir" != "x$file"; then
- case "$destdir" in
- [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
- *) thisdir="$thisdir/$destdir" ;;
- esac
- fi
-
- file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
- file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
- done
-
- # Usually 'no', except on cygwin/mingw when embedded into
- # the cwrapper.
- WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
- if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
- # special case for '.'
- if test "$thisdir" = "."; then
- thisdir=`pwd`
- fi
- # remove .libs from thisdir
- case "$thisdir" in
- *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
- .libs ) thisdir=. ;;
- esac
- fi
-
- # Try to get the absolute directory name.
- absdir=`cd "$thisdir" && pwd`
- test -n "$absdir" && thisdir="$absdir"
-
- program=lt-'positioner_overlay'
- progdir="$thisdir/.libs"
-
- if test ! -f "$progdir/$program" ||
- { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
- test "X$file" != "X$progdir/$program"; }; then
-
- file="$$-$program"
-
- if test ! -d "$progdir"; then
- mkdir "$progdir"
- else
- rm -f "$progdir/$file"
- fi
-
- # relink executable if necessary
- if test -n "$relink_command"; then
- if relink_command_output=`eval $relink_command 2>&1`; then :
- else
- printf %s\n "$relink_command_output" >&2
- rm -f "$progdir/$file"
- exit 1
- fi
- fi
-
- mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
- { rm -f "$progdir/$program";
- mv -f "$progdir/$file" "$progdir/$program"; }
- rm -f "$progdir/$file"
- fi
-
- if test -f "$progdir/$program"; then
- if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
- # Run the actual program with our arguments.
- func_exec_program ${1+"$@"}
- fi
- else
- # The program doesn't exist.
- $ECHO "0ドル: error: \`$progdir/$program' does not exist" 1>&2
- $ECHO "This script is just a wrapper for $program." 1>&2
- $ECHO "See the libtool documentation for more information." 1>&2
- exit 1
- fi
-fi
diff --git a/doc/part1_goodies.texi b/doc/part1_goodies.texi
index a12b395..bbce1ef 100644
--- a/doc/part1_goodies.texi
+++ b/doc/part1_goodies.texi
@@ -79,7 +79,7 @@ can only be removed programmatically
@findex fl_hide_oneliner()
@anchor{fl_hide_oneliner()}
@example
-void fl_show_oneliner(const char *str, FL_Coord x, FL_Coord y);
+void fl_show_oneliner(const char *str, FL_COORD x, FL_COORD y);
void fl_hide_oneliner(void);
@end example
@noindent
@@ -885,9 +885,12 @@ on return is the total number of entries in directory @code{dirname}
that match the pattern specified by @code{pattern} (not exactly true,
see below). The function returns the address of an array of type
@code{FL_Dirlist} with @code{nfiles} if successful and @code{NULL}
-otherwise. By default, directory entries are cached. Passing the
-function a true (non-zero) value for the @code{rescan} argument requests
-a re-read.
+otherwise. By default, directory entries are cached, i.e. when called
+with the same arguments for @code{dirname} and @code{pattern} again
+the exact same list is usually returned (and no checks are done if
+any files have been added or removed in the mean time). By passing
+the function a true (non-zero) value for the @code{rescan} argument
+requests a re-read, whch then returns
@code{FL_Dirlist} is a structure defined as follows
@example
@@ -901,9 +904,11 @@ typedef struct @{
@noindent
where @code{type} is one of the following file types
@table @code
+@tindex FT_REG
+@item FT_REG
+a regular file (note: in older versions instead
@tindex FT_FILE
-@item FT_FILE
-a regular file
+@code{FT_FILE} was used!)
@tindex FT_DIR
@item FT_DIR
a directory
@@ -926,18 +931,18 @@ a character device
?
@end table
-To free the list cache returned by @code{@ref{fl_get_dirlist()}}, use
-the following call
+Once you're done with the directory list obtained from
+@code{@ref{fl_get_dirlist()}} you must free it, using the following
+call:
@findex fl_free_dirlist()
@anchor{fl_free_dirlist()}
@example
void fl_free_dirlist(const FL_Dirlist *dl);
@end example
@noindent
-Note that a cast may be required to get rid of compiler warnings due
-to the @code{const} qualifier of the return value of
-@code{@ref{fl_get_dirlist()}}. See demo program @file{dirlist.c} for
-an example use of @code{@ref{fl_get_dirlist()}}.
+Of course, the argument passed to @code{@ref{fl_free_dirlist()}} must
+be a pointer you obtained from a call of @code{@ref{fl_get_dirlist()}}.
+See demo program @file{dirlist.c} for an example use of these functions.
Per default not all types of files are returned by
@code{@ref{fl_get_dirlist()}}. The specific rules for which
diff --git a/lib/fselect.c b/lib/fselect.c
index 3ab51b6..e522080 100644
--- a/lib/fselect.c
+++ b/lib/fselect.c
@@ -102,7 +102,7 @@ typedef struct
static FD_fselect * create_form_fselect( void );
-static FD_fselect *fd_fselector[ FL_MAX_FSELECTOR ] = { 0 },
+static FD_fselect *fd_fselector[ FL_MAX_FSELECTOR ] = { NULL },
*fs;
@@ -298,7 +298,11 @@ fli_del_tail_slash( char * d )
{
int i = strlen( d ) - 1;
+#ifndef FL_WIN32
if ( d[ i ] == '/' )
+#else
+ if ( d[ i ] == '/' || d[ i ] == '\\' )
+#endif
d[ i ] = '0円';
return d;
}
@@ -317,17 +321,19 @@ select_cb( FL_OBJECT * obj,
char seltext[ FL_PATH_MAX ];
int thisline;
FD_fselect *lfs = obj->form->fdui;
+ int is_dir;
if ( ( thisline = fl_get_browser( obj ) ) <= 0 )
return;
fli_sstrcpy( seltext, fl_get_browser_line( obj, thisline ),
sizeof seltext );
+ is_dir = seltext[ 0 ] == dirmarker && seltext[ 1 ] == ' ';
lfs->last_len = strlen( seltext + 2 );
lfs->last_line = thisline;
memmove( seltext, seltext + 2, lfs->last_len + 1 );
- if ( seltext[ 0 ] == dirmarker && seltext[ 1 ] == ' ' ) /* directory */
+ if ( is_dir ) /* directory */
{
if ( isdblclick )
{
@@ -469,7 +475,7 @@ fill_entries( FL_OBJECT * br,
{
const FL_Dirlist *dirlist,
*dl;
- char tt[ FL_FLEN ];
+ char * tt = NULL;
int n, i;
FD_fselect *lfs = br->form->fdui;
int dcount = 1;
@@ -485,12 +491,12 @@ fill_entries( FL_OBJECT * br,
if ( ! ( dirlist = fl_get_dirlist( lfs->dname, lfs->pattern, &n,
lfs->rescan || lfs->disabled_cache ) ) )
{
- char tmpbuf[ 256 ],
+ char * tmpbuf,
*p;
- fli_snprintf( tmpbuf, sizeof tmpbuf, "Can't read %s", lfs->dname );
- tmpbuf[ sizeof tmpbuf - 1 ] = '0円';
+ asprintf( tmpbuf, "Can't read %s", lfs->dname );
fl_show_alert( "ReadDir", tmpbuf, fli_get_syserror_msg( ), 0 );
+ fl_free( tmpbuf );
M_err( "fill_entries", "Can't read %s", lfs->dname );
/* Backup */
@@ -506,7 +512,7 @@ fill_entries( FL_OBJECT * br,
fl_set_object_label( lfs->dirbutt, contract_dirname( lfs->dname, 38 ) );
fl_clear_browser( br );
- for ( i = 0, dl = dirlist; dl->name; i++, dl++ )
+ for ( i = 0, dl = dirlist; i < n; i++, dl++ )
{
int cur_line;
char marker;
@@ -534,7 +540,7 @@ fill_entries( FL_OBJECT * br,
marker = filemarker;
}
- fli_snprintf( tt, sizeof tt, "%c %s", marker, dl->name );
+ asprintf( &tt, "%c %s", marker, dl->name );
if ( dl->type == FT_DIR && listdirfirst )
{
@@ -549,6 +555,8 @@ fill_entries( FL_OBJECT * br,
fl_add_browser_line( br, tt );
}
+ fli_safe_free( tt );
+
lcount++;
if ( sel_line <= 0
diff --git a/lib/listdir.c b/lib/listdir.c
index dea7125..f739640 100644
--- a/lib/listdir.c
+++ b/lib/listdir.c
@@ -42,7 +42,7 @@
#include <ctype.h>
#include <sys/types.h>
-#ifndef _WIN32
+#ifndef FL_WIN32
#include <unistd.h>
#else
#include <io.h>
@@ -112,8 +112,12 @@
# endif /* !S_IFSOCK && S_ISNAM */
#endif /* !S_ISSOCK */
-#define MAXCACHE 10 /* upto MAXCACHE dir will be cached */
-#define MAXFL ( FL_PATH_MAX + FL_FLEN )/* maximum file length */
+#if defined NEED_DIRECT
+#define DIRENT direct
+#else
+#define DIRENT dirent
+#endif
+
#ifndef StrReDup
#define StrReDup( a, b ) do \
@@ -124,11 +128,6 @@
} while( 0 )
#endif
-#if defined NEED_DIRECT
-#define DIRENT direct
-#else
-#define DIRENT dirent
-#endif
#if defined NEED_GETCWD
#if defined Lynx
@@ -172,8 +171,6 @@ fl_b2f_slash( char *dir )
/************* local variables ****************/
-static char fname[ MAXFL + 2 ];
-
#define FL_NONE 0
/******* local function forward dec **********/
@@ -194,14 +191,11 @@ int fli_sort_method = FL_ALPHASORT;
static FL_DIRLIST_FILTER ffilter = default_filter;
static int filter_directory = 0; /* true to filter directory entries */
-/*
- * convert native file types to FL
- */
-
#ifndef FL_WIN32 /* [ */
/***************************************
+ * Convert native file types to FL
***************************************/
static void
@@ -230,7 +224,7 @@ mode2type( unsigned int mode,
/******************************************************************
- * Filter the filename before handing it over to the "file is here"
+ * Filter filename before handing it over to the "file is here"
* list. Per default only files (including links) are shown.
******************************************************************/
@@ -241,10 +235,12 @@ fselect( const char * d_name,
const char * dir,
const char * pat )
{
+ char * fname;
int ret = 0;
unsigned int mode;
- strcat( strcpy( fname, dir), d_name );
+
+ asprintf( &fname, "%s%s", dir, d_name );
stat( fname, ffstat );
mode = ffstat->st_mode;
mode2type( mode, type );
@@ -255,7 +251,7 @@ fselect( const char * d_name,
{
/* Always keep directory and links */
- ret = S_ISDIR(mode)
+ ret = S_ISDIR( mode )
|| ( ( S_ISREG( mode ) || S_ISLNK( mode ) )
&& fli_wildmat( d_name, pat ) );
}
@@ -271,6 +267,8 @@ fselect( const char * d_name,
&& ffilter( fname, *type );
}
+ fl_free( fname );
+
return ret;
}
@@ -294,21 +292,24 @@ fselect( struct _finddata_t * c_file,
type = FT_FILE;
if ( ! ffilter )
- ret = 1;
+ ret 1;
else if ( ffilter == default_filter ) /* always keep directory and links */
ret = type == FT_DIR || fli_wildmat( c_file->name, pat );
else
{
- strcat( strcpy( fname, dir ), c_file->name );
+ char * fname;
+
+ asprintf( &fname, "%s%s" dir, c_file->name );
ret = type == FT_DIR
|| ( flo_wildmat( c_file->name, pat )
&& ffilter( fname, type ) );
+ fl_free( fname );
}
if ( ret )
{
- dl->name = fl_strdup( c_file->name );
- dl->type = type;
+ dl->name = fl_strdup( c_file->name );
+ dl->type = type;
dl->dl_mtime = c_file->time_write;
dl->dl_size = c_file->size;
}
@@ -362,8 +363,8 @@ tc_sort( const void * a,
/*******************************************************************
- * On entry, dir must be no zero and be terminated properly, i.e.,
- * ends with /
+ * On entry, dir must be non-zero and terminated properly, i.e.,
+ * ends with a '/'
*******************************************************************/
#ifndef FL_WIN32
@@ -373,31 +374,17 @@ scandir_get_entries( const char * dir,
const char * pat,
FL_Dirlist ** dirlist )
{
- static struct DIRENT **dlist;
- FL_Dirlist *dl;
- static int lastn;
- static struct stat ffstat;
+ struct DIRENT **dlist;
+ int max_n;
+ struct stat ffstat;
int n = 0;
- /* Free all memory used last time we were here */
-
- if ( dlist )
- {
- while ( --lastn >= 0 )
- if ( dlist[ lastn ] )
- fl_free( dlist[ lastn ]);
- fl_free( dlist );
- dlist = NULL;
- }
-
- if ( ( lastn = tc_scandir( dir, &dlist ) ) > 0 )
+ if ( ( max_n = tc_scandir( dir, &dlist ) ) > 0 )
{
+ FL_Dirlist *dl = *dirlist = fl_malloc( max_n * sizeof **dirlist );
int i;
- dl = *dirlist = fl_malloc( ( lastn + 1 ) * sizeof **dirlist );
-
- for ( i = n = 0; i < lastn; i++ )
- {
+ for ( i = 0; i < max_n; i++ )
if ( fselect( dlist[ i ]->d_name, &ffstat, &dl->type, dir, pat ) )
{
dl->name = fl_strdup( dlist[ i ]->d_name );
@@ -406,9 +393,10 @@ scandir_get_entries( const char * dir,
dl++;
n++;
}
- }
- dl->name = NULL; /* sentinel */
+ fl_free( dlist );
+
+ *dirlist = fl_realloc( *dirlist, n * sizeof **dirlist );
if ( fli_sort_method != FL_NONE )
qsort( *dirlist, n, sizeof **dirlist, tc_sort );
@@ -501,46 +489,38 @@ scandir_get_entries( const char * dir,
*
********************************************************************/
-static char *lastdir[ MAXCACHE ],
- *lastpat[ MAXCACHE ];
-static int lastn[ MAXCACHE ],
- last_sort[ MAXCACHE ];
-static FL_Dirlist *dirlist[ MAXCACHE ];
+typedef struct
+{
+ char * dirname;
+ char * pattern;
+ FL_Dirlist * list;
+ int list_len;
+} Dirlist_Cache;
+
+static Dirlist_Cache * cache = NULL;
+static int cache_size = 0;
+
/********************************************************************
* Check if a particular directory is cached
********************************************************************/
-static int
+static
+int
is_cached( const char * dir,
- const char * pat,
- int * c )
+ const char * pat )
{
- int cached = 0,
- i = 0;
- static int lastcache;
+ int i;
- do
+ for ( i = 0; i < cache_size; i++ )
{
- cached = lastpat[ i ]
- && lastdir[ i ]
- && strcmp( lastdir[ i ], dir ) == 0
- && strcmp( lastpat[ i ], pat ) == 0
- && dirlist[ i ]
- && dirlist[ i ]->name;
- *c = i++;
+ if ( ! strcmp( cache[ i ].dirname, dir )
+ && ! strcmp( cache[ i ].pattern, pat ) )
+ return i;
}
- while ( ! cached && i < MAXCACHE );
-
- /* search for the least used slot if not cached */
- if ( ! cached )
- *c = ++lastcache % MAXCACHE;
-
- lastcache = *c;
- M_info( "is_cached", "%s is %s cached", dir, cached ? "" : "not" );
- return cached;
+ return -1;
}
@@ -550,29 +530,34 @@ is_cached( const char * dir,
void
fl_free_dirlist( const FL_Dirlist * dl )
{
- size_t i;
+ int i, j;
- for ( i = 0; i < MAXCACHE; i++ )
- if ( dl == dirlist[ i ] )
+ for ( i = 0; i < cache_size; ++i )
+ if ( dl == cache[ i ].list )
break;
- if ( i >= MAXCACHE )
+ if ( i == cache_size )
{
M_err( "fl_free_dirlist", "Bad list" );
return;
}
+
+ fl_free( cache[ i ].dirname );
+ fl_free( cache[ i ].pattern );
+ for ( j = 0; j < cache[ i ].list_len; ++j )
+ fl_free( cache[ i ].list[ j ].name );
+ fl_free( cache[ i ].list );
- while ( dl && dl->name )
- {
- fli_safe_free( ( ( FL_Dirlist * ) dl )->name );
- dl++;
- }
+ cache_size--;
- if ( dirlist[ i ] )
+ if ( i < cache_size )
{
- fl_free( dirlist[ i ] );
- dirlist[ i ] = NULL;
+ cache[ i ].dirname = cache[ cache_size ].dirname;
+ cache[ i ].pattern = cache[ cache_size ].pattern;
+ cache[ i ].list = cache[ cache_size ].list;
}
+
+ cache = fl_realloc( cache, cache_size * sizeof *cache );
}
@@ -581,50 +566,61 @@ fl_free_dirlist( const FL_Dirlist * dl )
*********************************************************************/
const FL_Dirlist *
-fl_get_dirlist( const char * dir,
+fl_get_dirlist( const char * directory,
const char * pattern,
int * n,
int rescan )
{
- int i,
- c;
- const char *pat = pattern;
- char okdir[ FL_PATH_MAX + 1 ];
+ char * dir;
+ char * pat;
+ FL_Dirlist * dl;
+ int i;
- if ( ! dir || ! *dir )
+ if ( ! directory || ! *directory )
return NULL;
- if ( ! pat || ! *pat )
- pat = "*";
+ if ( ! pattern || ! *pattern )
+ pat = fl_strdup( "*" );
+ else
+ pat = fl_strdup( pattern );
- /* Fix the directory on the fly */
+ /* Make sure the directory has a slash at the end (or, oprionally, a
+ backslash under Windows) */
- i = strlen( strcpy( okdir, dir ) );
- if ( okdir[ i - 1 ] != '/' )
- {
- okdir[ i ] = '/';
- okdir[ ++i ] = '0円';
- }
+#ifndef FL_WIN32
+ if ( directory[ strlen( directory ) - 1 ] == '/' )
+#else
+ if ( directory[ strlen( directory ) - 1 ] == '/'
+ || directory[ strlen( directory ) - 1 ] == '\\')
+#endif
+ dir = fl_strdup( directory );
+ else
+ asprintf( &dir, "%s/", directory );
- /* is_cached must go first to get correct cache location */
+ /* First check if it's not already cached (unless we're asked to rescan
+ anyway) */
- if ( ! is_cached( okdir, pat, &c ) || rescan )
+ if ( ( i = is_cached( dir, pat ) ) >= 0 && ! rescan )
{
- fl_free_dirlist( dirlist[ c ] );
- lastn[ c ] = scandir_get_entries( okdir, pat, dirlist + c );
- last_sort[ c ] = fli_sort_method;
- StrReDup( lastpat[ c ], pat );
- StrReDup( lastdir[ c ], okdir );
+ fl_free( dir );
+ fl_free( pat );
+ *n = cache[ i ].list_len;
+ return cache[ i ].list;
}
- *n = lastn[ c ];
- if ( last_sort[ c ] != fli_sort_method )
+ *n = scandir_get_entries( dir, pat, &dl );
+ if ( ! dl )
{
- qsort( dirlist[ c ], *n, sizeof **dirlist, tc_sort );
- last_sort[ c ] = fli_sort_method;
+ fl_free( dir );
+ fl_free( pat );
+ return NULL;
}
- return dirlist[ c ];
+ cache = fl_realloc( cache, ++cache_size * sizeof *cache );
+ cache[ cache_size - 1 ].dirname = dir;
+ cache[ cache_size - 1 ].pattern = pat;
+ cache[ cache_size - 1 ].list_len = *n;
+ return cache[ cache_size - 1 ].list = dl;
}
@@ -633,11 +629,11 @@ fl_get_dirlist( const char * dir,
**********************************************************************/
int
-fli_is_valid_dir( const char *name )
+fli_is_valid_dir( const char * name )
{
struct stat stbuf;
-#ifdef __EMX__
+#ifdef __EMX__ || defined FL_WIN32
if ( name
&& isalpha( ( unsigned char ) name[ 0 ] )
&& name[ 1 ] == ':'
@@ -968,7 +964,8 @@ tc_scandir( const char * dirname,
#else
total = dname_is_1 ? dentry->d_reclen : sizeof *dentry;
#endif
- memcpy( head[ n ] = fl_malloc( total ), dentry, total );
+ head[ n ] = fl_malloc( total );
+ memcpy( head[ n ], dentry, total );
}
closedir( dir );
@@ -1047,8 +1044,6 @@ fli_getcwd( char * buf,
#else
return getcwd( buf, len );
#endif
-
-
}
generated by cgit v1.2.3 (git 2.39.1) at 2025年11月25日 07:59:40 +0000

AltStyle によって変換されたページ (->オリジナル) /