/src/ogre/OgreMain/src/OgreSearchOps.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | |
29 | | // Emulate _findfirst, _findnext on non-Windows platforms |
30 | | #include "OgreSearchOps.h" |
31 | | #include <stdio.h> |
32 | | #include <dirent.h> |
33 | | #include <fnmatch.h> |
34 | | #include <sys/stat.h> |
35 | | #include <string.h> |
36 | | #include <stdlib.h> |
37 | | |
38 | | /* Win32 directory operations emulation */ |
39 | | #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32 && OGRE_PLATFORM != OGRE_PLATFORM_WINRT |
40 | | |
41 | | struct _find_search_t |
42 | | { |
43 | | char *pattern; |
44 | | char *curfn; |
45 | | char *directory; |
46 | | int dirlen; |
47 | | DIR *dirfd; |
48 | | }; |
49 | | |
50 | | intptr_t _findfirst(const char *pattern, struct _finddata_t *data) |
51 | 0 | { |
52 | 0 | _find_search_t *fs = new _find_search_t; |
53 | 0 | fs->curfn = NULL; |
54 | 0 | fs->pattern = NULL; |
55 | | |
56 | | // Separate the mask from directory name |
57 | 0 | const char *mask = strrchr (pattern, '/'); |
58 | 0 | if (mask) |
59 | 0 | { |
60 | 0 | fs->dirlen = static_cast<int>(mask - pattern); |
61 | 0 | mask++; |
62 | 0 | fs->directory = (char *)malloc (fs->dirlen + 1); |
63 | 0 | memcpy (fs->directory, pattern, fs->dirlen); |
64 | 0 | fs->directory [fs->dirlen] = 0; |
65 | 0 | } |
66 | 0 | else |
67 | 0 | { |
68 | 0 | mask = pattern; |
69 | 0 | fs->directory = strdup ("."); |
70 | 0 | fs->dirlen = 1; |
71 | 0 | } |
72 | |
|
73 | 0 | fs->dirfd = opendir (fs->directory); |
74 | 0 | if (!fs->dirfd) |
75 | 0 | { |
76 | 0 | _findclose ((intptr_t)fs); |
77 | 0 | return -1; |
78 | 0 | } |
79 | | |
80 | | /* Hack for "*.*" -> "*' from DOS/Windows */ |
81 | 0 | if (strcmp (mask, "*.*") == 0) |
82 | 0 | mask += 2; |
83 | 0 | fs->pattern = strdup (mask); |
84 | | |
85 | | /* Get the first entry */ |
86 | 0 | if (_findnext ((intptr_t)fs, data) < 0) |
87 | 0 | { |
88 | 0 | _findclose ((intptr_t)fs); |
89 | 0 | return -1; |
90 | 0 | } |
91 | | |
92 | 0 | return (intptr_t)fs; |
93 | 0 | } |
94 | | |
95 | | int _findnext(intptr_t id, struct _finddata_t *data) |
96 | 0 | { |
97 | 0 | _find_search_t *fs = reinterpret_cast<_find_search_t *>(id); |
98 | | |
99 | | /* Loop until we run out of entries or find the next one */ |
100 | 0 | dirent *entry; |
101 | 0 | for (;;) |
102 | 0 | { |
103 | 0 | if (!(entry = readdir (fs->dirfd))) |
104 | 0 | return -1; |
105 | | |
106 | | /* See if the filename matches our pattern */ |
107 | 0 | if (fnmatch (fs->pattern, entry->d_name, 0) == 0) |
108 | 0 | break; |
109 | 0 | } |
110 | | |
111 | 0 | if (fs->curfn) |
112 | 0 | free (fs->curfn); |
113 | 0 | data->name = fs->curfn = strdup (entry->d_name); |
114 | |
|
115 | 0 | size_t namelen = strlen (entry->d_name); |
116 | 0 | char *xfn = new char [fs->dirlen + 1 + namelen + 1]; |
117 | 0 | sprintf (xfn, "%s/%s", fs->directory, entry->d_name); |
118 | | |
119 | | /* stat the file to get if it's a subdir and to find its length */ |
120 | 0 | struct stat stat_buf; |
121 | 0 | if (stat (xfn, &stat_buf)) |
122 | 0 | { |
123 | | // Hmm strange, imitate a zero-length file then |
124 | 0 | data->attrib = _A_NORMAL; |
125 | 0 | data->size = 0; |
126 | 0 | } |
127 | 0 | else |
128 | 0 | { |
129 | 0 | if (S_ISDIR(stat_buf.st_mode)) |
130 | 0 | data->attrib = _A_SUBDIR; |
131 | 0 | else |
132 | | /* Default type to a normal file */ |
133 | 0 | data->attrib = _A_NORMAL; |
134 | |
|
135 | 0 | data->size = (unsigned long)stat_buf.st_size; |
136 | 0 | } |
137 | |
|
138 | 0 | delete [] xfn; |
139 | | |
140 | | /* Files starting with a dot are hidden files in Unix */ |
141 | 0 | if (data->name [0] == '.') |
142 | 0 | data->attrib |= _A_HIDDEN; |
143 | |
|
144 | 0 | return 0; |
145 | 0 | } |
146 | | |
147 | | int _findclose(intptr_t id) |
148 | 0 | { |
149 | 0 | int ret; |
150 | 0 | _find_search_t *fs = reinterpret_cast<_find_search_t *>(id); |
151 | | |
152 | 0 | ret = fs->dirfd ? closedir (fs->dirfd) : 0; |
153 | 0 | free (fs->pattern); |
154 | 0 | free (fs->directory); |
155 | 0 | if (fs->curfn) |
156 | 0 | free (fs->curfn); |
157 | 0 | delete fs; |
158 | |
|
159 | 0 | return ret; |
160 | 0 | } |
161 | | |
162 | | #endif |