DRC | 2ff39b8 | 2011-07-28 08:38:59 +0000 | [diff] [blame] | 1 | // |
| 2 | // "$Id: filename_isdir.cxx 8063 2010-12-19 21:20:10Z matt $" |
| 3 | // |
| 4 | // Directory detection routines for the Fast Light Tool Kit (FLTK). |
| 5 | // |
| 6 | // Copyright 1998-2010 by Bill Spitzak and others. |
| 7 | // |
| 8 | // This library is free software; you can redistribute it and/or |
| 9 | // modify it under the terms of the GNU Library General Public |
| 10 | // License as published by the Free Software Foundation; either |
| 11 | // version 2 of the License, or (at your option) any later version. |
| 12 | // |
| 13 | // This library is distributed in the hope that it will be useful, |
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | // Library General Public License for more details. |
| 17 | // |
| 18 | // You should have received a copy of the GNU Library General Public |
| 19 | // License along with this library; if not, write to the Free Software |
| 20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
| 21 | // USA. |
| 22 | // |
| 23 | // Please report all bugs and problems on the following page: |
| 24 | // |
| 25 | // http://www.fltk.org/str.php |
| 26 | // |
| 27 | |
| 28 | // Used by fl_file_chooser |
| 29 | |
| 30 | #include "flstring.h" |
| 31 | #include <sys/types.h> |
| 32 | #include <sys/stat.h> |
| 33 | #include <ctype.h> |
| 34 | #include <FL/filename.H> |
| 35 | #include <FL/fl_utf8.h> |
| 36 | |
| 37 | |
| 38 | #if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) |
| 39 | static inline int isdirsep(char c) {return c=='/' || c=='\\';} |
| 40 | #else |
| 41 | #define isdirsep(c) ((c)=='/') |
| 42 | #endif |
| 43 | |
| 44 | int _fl_filename_isdir_quick(const char* n) { |
| 45 | // Do a quick optimization for filenames with a trailing slash... |
| 46 | if (*n && isdirsep(n[strlen(n) - 1])) return 1; |
| 47 | return fl_filename_isdir(n); |
| 48 | } |
| 49 | |
| 50 | /** |
| 51 | Determines if a file exists and is a directory from its filename. |
| 52 | \code |
| 53 | #include <FL/filename.H> |
| 54 | [..] |
| 55 | fl_filename_isdir("/etc"); // returns non-zero |
| 56 | fl_filename_isdir("/etc/hosts"); // returns 0 |
| 57 | \endcode |
| 58 | \param[in] n the filename to parse |
| 59 | \return non zero if file exists and is a directory, zero otherwise |
| 60 | */ |
| 61 | int fl_filename_isdir(const char* n) { |
| 62 | struct stat s; |
| 63 | char fn[FL_PATH_MAX]; |
| 64 | int length; |
| 65 | |
| 66 | length = strlen(n); |
| 67 | |
| 68 | #ifdef WIN32 |
| 69 | // This workaround brought to you by the fine folks at Microsoft! |
| 70 | // (read lots of sarcasm in that...) |
| 71 | if (length < (int)(sizeof(fn) - 1)) { |
| 72 | if (length < 4 && isalpha(n[0]) && n[1] == ':' && |
| 73 | (isdirsep(n[2]) || !n[2])) { |
| 74 | // Always use D:/ for drive letters |
| 75 | fn[0] = n[0]; |
| 76 | strcpy(fn + 1, ":/"); |
| 77 | n = fn; |
| 78 | } else if (length > 0 && isdirsep(n[length - 1])) { |
| 79 | // Strip trailing slash from name... |
| 80 | length --; |
| 81 | memcpy(fn, n, length); |
| 82 | fn[length] = '\0'; |
| 83 | n = fn; |
| 84 | } |
| 85 | } |
| 86 | #else |
| 87 | // Matt: Just in case, we strip the slash for other operating |
| 88 | // systems as well, avoid bugs by sloppy implementations |
| 89 | // of "stat". |
| 90 | if (length > 1 && isdirsep(n[length - 1])) { |
| 91 | length --; |
| 92 | memcpy(fn, n, length); |
| 93 | fn[length] = '\0'; |
| 94 | n = fn; |
| 95 | } |
| 96 | #endif |
| 97 | |
| 98 | return !fl_stat(n, &s) && (s.st_mode&0170000)==0040000; |
| 99 | } |
| 100 | |
| 101 | // |
| 102 | // End of "$Id: filename_isdir.cxx 8063 2010-12-19 21:20:10Z matt $". |
| 103 | // |