Súbor: [Platon] / games / 3do-view / dir.c (stiahnutie)
Revízia 1.11, Wed Nov 10 18:14:32 2004 UTC (19 years, 4 months ago) by nepto
Zmeny od 1.10: +5 -1
[lines]
Fixed several warnings.
|
/*
* 3do-view - 3D objects (3DO) viewer for MS-Dos/Win32/SVGAlib/X11
*
* dir.c - files and directories handler
* ____________________________________________________________
*
* Developed by Ondrej Jombik <nepto@platon.sk>
* Copyright (c) 2003-2004 Platon SDG, http://platon.sk/
* All rights reserved.
*
* See README file for more information about this software.
* See COPYING file for license information.
*
* Download the latest version from
* http://platon.sk/projects/games/
*
* Changelog:
* 2003-05-19 - created
* 2003-06-27 - added Win32 support
* 2003-07-15 - smart memory allocation for files and directories data
* 2003-08-12 - X11 adaptations
*/
/* $Platon: games/3do-view/dir.c,v 1.10 2004/04/06 09:54:15 nepto Exp $ */
#include <string.h>
#include <stdlib.h>
#include <system.h>
#define DIR_SMART_ALLOCATION (1) /* 1 or 0 */
#define DIR_REALLOC_IDX_STEP (15)
#if DIR_SMART_ALLOCATION
# define DIR_REALLOC_DATA_STEP (255)
#endif
#if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11
# include <unistd.h>
# include <dirent.h>
# include <sys/types.h>
# include <sys/stat.h>
# define DIR_DIRECTORY_CONDITION (S_ISDIR(st.st_mode))
# define DIR_FILENAME (dp->d_name)
# define DIR_INIT_CONDITION (! ((dirp = opendir(".")) == NULL \
&& !chdir("/") && (dirp = opendir(".")) == NULL))
/* If current directory cannot be opened, fallback to root directory. */
#endif
#if PLATON_SYSTEM_WIN32
# include <windows.h>
# define DIR_DIRECTORY_CONDITION (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
# define DIR_FILENAME (FindFileData.cFileName)
# define DIR_NEXT_CONDITION (FindNextFile(hFind, &FindFileData))
# define DIR_INIT_CONDITION ((hFind = FindFirstFile("*.*", &FindFileData)) != INVALID_HANDLE_VALUE)
#endif
#if PLATON_SYSTEM_MSDOS
# include <dos.h>
# include <dir.h>
# define DIR_DIRECTORY_CONDITION (ffblk.ff_attrib & FA_DIREC)
# define DIR_FILENAME (ffblk.ff_name)
# define DIR_NEXT_CONDITION (! findnext(&ffblk))
# define DIR_INIT_CONDITION (! (findfirst("*.*", &ffblk, \
FA_DIREC + FA_HIDDEN + FA_RDONLY + FA_SYSTEM)))
#endif
#if DIR_SMART_ALLOCATION
/* Sorting currently does not work in smart allocation mode. */
#else
static int compare_function(const void *ptr1, const void *ptr2) /* {{{ */
{
#if 0
fprintf(stderr, "comparing %s[%p]:%s[%p]\n",
*(char **) ptr1, ptr1, *(char **) ptr2, ptr2);
#endif
return strcmp(*(char **) ptr1, *(char **) ptr2);
} /* }}} */
#endif
void get_directories_and_files(char ***directories, char ***files) /* {{{ */
{
#if DIR_SMART_ALLOCATION
register int *alloc_bytes;
register int *free_bytes;
int directories_alloc_bytes = 0;
int directories_free_bytes = 0;
int files_alloc_bytes = 0;
int files_free_bytes = 0;
#endif
#if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11
DIR *dirp;
struct dirent *dp;
struct stat st;
#endif
#if PLATON_SYSTEM_WIN32
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
#endif
#if PLATON_SYSTEM_MSDOS
struct ffblk ffblk;
#endif
register char ***ptr;
int directories_size, files_size, *size;
if (directories != NULL) *directories = NULL;
if (files != NULL) *files = NULL;
if (! DIR_INIT_CONDITION)
return;
directories_size = 0;
files_size = 0;
#if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
if (stat(DIR_FILENAME, &st))
continue;
#endif
#if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32
do {
#endif
if (DIR_DIRECTORY_CONDITION) {
if (directories == NULL || ! strcmp(DIR_FILENAME, "."))
continue;
ptr = directories;
size = &directories_size;
#if DIR_SMART_ALLOCATION
alloc_bytes = &directories_alloc_bytes;
free_bytes = &directories_free_bytes;
#endif
} else {
if (files == NULL)
continue;
ptr = files;
size = &files_size;
#if DIR_SMART_ALLOCATION
alloc_bytes = &files_alloc_bytes;
free_bytes = &files_free_bytes;
#endif
}
if (! *size || !((*size + 1) % DIR_REALLOC_IDX_STEP)) {
register char **new_ptr;
new_ptr = (char **) realloc((void *) *ptr,
sizeof(char *) * (*size + 1 + DIR_REALLOC_IDX_STEP));
if (new_ptr == NULL)
break; /* take what we recentry have and go away
if memory allocation failed */
*ptr = new_ptr;
if (! *size)
(*ptr)[0] = NULL;
}
#if DIR_SMART_ALLOCATION
while (strlen(DIR_FILENAME) + 1 > *free_bytes) {
register char *new_ptr;
register int i, diff;
new_ptr = (char *) realloc((void *) **ptr,
sizeof(char) * (*alloc_bytes + DIR_REALLOC_DATA_STEP));
if (new_ptr == NULL)
break; /* skip this entry if memory allocation failed */
diff = new_ptr - **ptr;
for (i = 0; i <= *size; i++)
(*ptr)[i] += diff;
*free_bytes += DIR_REALLOC_DATA_STEP;
*alloc_bytes += DIR_REALLOC_DATA_STEP;
}
if (strlen(DIR_FILENAME) + 1 <= *free_bytes) {
(*ptr)[*size] = **ptr + *alloc_bytes - *free_bytes;
strcpy((*ptr)[*size], DIR_FILENAME);
*free_bytes -= (strlen(DIR_FILENAME) + 1);
}
#else
if (((*ptr)[*size] = strdup(DIR_FILENAME)) == NULL)
break;
#endif
(*size)++;
(*ptr)[*size] = NULL;
#if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11
}
closedir(dirp);
#endif
#if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32
} while (DIR_NEXT_CONDITION);
#endif
#if DIR_SMART_ALLOCATION
/* Sorting currently does not work in smart allocation mode. */
#else
if (*directories != NULL)
qsort(*directories, directories_size, sizeof(char *), compare_function);
if (*files != NULL)
qsort(*files, files_size, sizeof(char *), compare_function);
#endif
} /* }}} */
void free_directories_or_files(char **ar) /* {{{ */
{
#if DIR_SMART_ALLOCATION
if (ar[0] != NULL)
free(ar[0]);
#else
register int i;
for (i = 0; ar[i] != NULL; i++)
free(ar[i]);
#endif
free(ar);
} /* }}} */
#if defined(SELF) || defined(SELFTEST) || defined(SELF_DIR)
#include <stdio.h>
int main(int argc, char **argv) /* {{{ */
{
register int k;
char **dirs, **files;
get_directories_and_files(&dirs, &files);
printf("Directories: [%p]\n", dirs);
for (k = 0; dirs != NULL && dirs[k] != NULL; k++)
printf("%03d: %s\n", k, dirs[k]);
printf("Files: [%p]\n", files);
for (k = 0; files != NULL && files[k] != NULL; k++)
printf("%03d: %s\n", k, files[k]);
if (dirs != NULL)
free_directories_or_files(dirs);
if (files != NULL)
free_directories_or_files(files);
return 0;
} /* }}} */
#endif /* #if defined(SELF) || defined(SELFTEST) || defined(SELF_DIR) */
/* Modeline for ViM {{{
* vim: set ts=4:
* vim600: fdm=marker fdl=0 fdc=0:
* }}} */
Platon Group <platon@platon.sk> http://platon.sk/
|