/* * dir.c * * Developed by Ondrej Jombik * Copyright (c) 2003 Platon SDG, http://www.platon.sk/ * Licensed under terms of GNU General Public License. * All rights reserved. * * Changelog: * 19/05/2003 - created * 27/06/2003 - added Win32 support */ /* $Platon: games/3do-view/dir.c,v 1.5 2003/06/22 18:40:33 nepto Exp $ */ #include #include #include #if PLATON_SYSTEM_SVGALIB # include # include # include # include # 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 # 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 # include # 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 #define DIR_REALLOC_STEP (10) 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); } /* }}} */ void get_directories_and_files(char ***directories, char ***files) /* {{{ */ { #if PLATON_SYSTEM_SVGALIB 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 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; } else { if (files == NULL) continue; ptr = files; size = &files_size; } if (! *size || !((*size + 1) % DIR_REALLOC_STEP)) { register char **new_ptr; new_ptr = (char **) realloc((void *) *ptr, sizeof(char *) * (*size + 1 + DIR_REALLOC_STEP)); if (new_ptr == NULL) break; *ptr = new_ptr; } if (((*ptr)[*size] = strdup(DIR_FILENAME)) == NULL) break; (*size)++; (*ptr)[*size] = NULL; #if PLATON_SYSTEM_SVGALIB } closedir(dirp); #endif #if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32 } while (DIR_NEXT_CONDITION); #endif if (*directories != NULL) qsort(*directories, directories_size, sizeof(char *), compare_function); if (*files != NULL) qsort(*files, files_size, sizeof(char *), compare_function); } /* }}} */ void free_directories_or_files(char **ar) /* {{{ */ { register int i; for (i = 0; ar[i] != NULL; i++) free(ar[i]); free(ar); } /* }}} */ #if defined(SELF) || defined(SELFTEST) || defined(SELF_DIR) #include int main(int argc, char **argv) /* {{{ */ { register int k; char **dirs, **files; get_directories_and_files(&dirs, &files); puts("Directories:"); for (k = 0; dirs != NULL && dirs[k] != NULL; k++) printf("%03d: %s\n", k, dirs[k]); puts("Files:"); for (k = 0; files != NULL && files[k] != NULL; k++) printf("%03d: %s\n", k, files[k]); 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: * }}} */