Mercurial > emacs
comparison src/dired.c @ 33345:8ee80e8c9093
(directory_files_internal): Add missing GCPRO's.
Some cleanup.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Thu, 09 Nov 2000 14:48:19 +0000 |
parents | 233d9eb5dff0 |
children | 07dd05556e82 |
comparison
equal
deleted
inserted
replaced
33344:ae432b5b679d | 33345:8ee80e8c9093 |
---|---|
135 directory_files_internal (directory, full, match, nosort, attrs) | 135 directory_files_internal (directory, full, match, nosort, attrs) |
136 Lisp_Object directory, full, match, nosort; | 136 Lisp_Object directory, full, match, nosort; |
137 int attrs; | 137 int attrs; |
138 { | 138 { |
139 DIR *d; | 139 DIR *d; |
140 int dirnamelen; | 140 int directory_nbytes; |
141 Lisp_Object list, name, dirfilename; | 141 Lisp_Object list, dirfilename, encoded_directory; |
142 Lisp_Object encoded_directory; | |
143 Lisp_Object handler; | 142 Lisp_Object handler; |
144 struct re_pattern_buffer *bufp = NULL; | 143 struct re_pattern_buffer *bufp = NULL; |
145 int needsep = 0; | 144 int needsep = 0; |
146 int count = specpdl_ptr - specpdl; | 145 int count = specpdl_ptr - specpdl; |
147 struct gcpro gcpro1, gcpro2; | 146 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
148 | 147 |
149 /* Because of file name handlers, these functions might call | 148 /* Because of file name handlers, these functions might call |
150 Ffuncall, and cause a GC. */ | 149 Ffuncall, and cause a GC. */ |
151 GCPRO1 (match); | 150 list = encoded_directory = dirfilename = Qnil; |
151 GCPRO5 (match, directory, list, dirfilename, encoded_directory); | |
152 directory = Fexpand_file_name (directory, Qnil); | 152 directory = Fexpand_file_name (directory, Qnil); |
153 UNGCPRO; | |
154 GCPRO2 (match, directory); | |
155 dirfilename = Fdirectory_file_name (directory); | 153 dirfilename = Fdirectory_file_name (directory); |
156 UNGCPRO; | |
157 | 154 |
158 if (!NILP (match)) | 155 if (!NILP (match)) |
159 { | 156 { |
160 CHECK_STRING (match, 3); | 157 CHECK_STRING (match, 3); |
161 | 158 |
170 #else | 167 #else |
171 bufp = compile_pattern (match, 0, Qnil, 0, 1); | 168 bufp = compile_pattern (match, 0, Qnil, 0, 1); |
172 #endif | 169 #endif |
173 } | 170 } |
174 | 171 |
172 /* Note: ENOCDE_FILE and DECODE_FILE can GC because they can run | |
173 run_pre_post_conversion_on_str which calls Lisp directly and | |
174 indirectly. */ | |
175 dirfilename = ENCODE_FILE (dirfilename); | 175 dirfilename = ENCODE_FILE (dirfilename); |
176 | |
177 encoded_directory = ENCODE_FILE (directory); | 176 encoded_directory = ENCODE_FILE (directory); |
178 | 177 |
179 /* Now *bufp is the compiled form of MATCH; don't call anything | 178 /* Now *bufp is the compiled form of MATCH; don't call anything |
180 which might compile a new regexp until we're done with the loop! */ | 179 which might compile a new regexp until we're done with the loop! */ |
181 | 180 |
182 /* Do this opendir after anything which might signal an error; if | 181 /* Do this opendir after anything which might signal an error; if |
183 an error is signaled while the directory stream is open, we | 182 an error is signaled while the directory stream is open, we |
184 have to make sure it gets closed, and setting up an | 183 have to make sure it gets closed, and setting up an |
185 unwind_protect to do so would be a pain. */ | 184 unwind_protect to do so would be a pain. */ |
186 d = opendir (XSTRING (dirfilename)->data); | 185 d = opendir (XSTRING (dirfilename)->data); |
187 if (! d) | 186 if (d == NULL) |
188 report_file_error ("Opening directory", Fcons (directory, Qnil)); | 187 report_file_error ("Opening directory", Fcons (directory, Qnil)); |
189 | 188 |
190 /* Unfortunately, we can now invoke expand-file-name and | 189 /* Unfortunately, we can now invoke expand-file-name and |
191 file-attributes on filenames, both of which can throw, so we must | 190 file-attributes on filenames, both of which can throw, so we must |
192 do a proper unwind-protect. */ | 191 do a proper unwind-protect. */ |
193 record_unwind_protect (directory_files_internal_unwind, | 192 record_unwind_protect (directory_files_internal_unwind, |
194 Fcons (make_number (((unsigned long) d) >> 16), | 193 Fcons (make_number (((unsigned long) d) >> 16), |
195 make_number (((unsigned long) d) & 0xffff))); | 194 make_number (((unsigned long) d) & 0xffff))); |
196 | 195 |
197 list = Qnil; | 196 directory_nbytes = STRING_BYTES (XSTRING (directory)); |
198 dirnamelen = STRING_BYTES (XSTRING (directory)); | |
199 re_match_object = Qt; | 197 re_match_object = Qt; |
200 | 198 |
201 /* Decide whether we need to add a directory separator. */ | 199 /* Decide whether we need to add a directory separator. */ |
202 #ifndef VMS | 200 #ifndef VMS |
203 if (dirnamelen == 0 | 201 if (directory_nbytes == 0 |
204 || !IS_ANY_SEP (XSTRING (directory)->data[dirnamelen - 1])) | 202 || !IS_ANY_SEP (XSTRING (directory)->data[directory_nbytes - 1])) |
205 needsep = 1; | 203 needsep = 1; |
206 #endif /* not VMS */ | 204 #endif /* not VMS */ |
207 | |
208 GCPRO2 (encoded_directory, list); | |
209 | 205 |
210 /* Loop reading blocks */ | 206 /* Loop reading blocks */ |
211 while (1) | 207 while (1) |
212 { | 208 { |
213 DIRENTRY *dp = readdir (d); | 209 DIRENTRY *dp = readdir (d); |
214 | 210 |
215 if (!dp) break; | 211 if (dp == NULL) |
212 break; | |
213 | |
216 if (DIRENTRY_NONEMPTY (dp)) | 214 if (DIRENTRY_NONEMPTY (dp)) |
217 { | 215 { |
218 int len; | 216 int len; |
219 int wanted = 0; | 217 int wanted = 0; |
218 Lisp_Object name, finalname; | |
219 struct gcpro gcpro1, gcpro2; | |
220 | 220 |
221 len = NAMLEN (dp); | 221 len = NAMLEN (dp); |
222 name = DECODE_FILE (make_string (dp->d_name, len)); | 222 name = finalname = make_string (dp->d_name, len); |
223 GCPRO2 (finalname, name); | |
224 | |
225 /* Note: ENCODE_FILE can GC; it should protect its argument, | |
226 though. */ | |
227 name = DECODE_FILE (name); | |
223 len = STRING_BYTES (XSTRING (name)); | 228 len = STRING_BYTES (XSTRING (name)); |
224 | 229 |
225 /* Now that we have unwind_protect in place, we might as well | 230 /* Now that we have unwind_protect in place, we might as well |
226 allow matching to be interrupted. */ | 231 allow matching to be interrupted. */ |
227 immediate_quit = 1; | 232 immediate_quit = 1; |
228 QUIT; | 233 QUIT; |
229 | 234 |
230 if (NILP (match) | 235 if (NILP (match) |
231 || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0))) | 236 || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0))) |
232 { | 237 wanted = 1; |
233 wanted = 1; | |
234 } | |
235 | 238 |
236 immediate_quit = 0; | 239 immediate_quit = 0; |
237 | 240 |
238 if (wanted) | 241 if (wanted) |
239 { | 242 { |
240 Lisp_Object finalname; | |
241 | |
242 finalname = name; | |
243 if (!NILP (full)) | 243 if (!NILP (full)) |
244 { | 244 { |
245 int afterdirindex = dirnamelen; | 245 Lisp_Object fullname; |
246 int total = len + dirnamelen; | 246 int nbytes = len + directory_nbytes + needsep; |
247 int nchars; | 247 int nchars; |
248 Lisp_Object fullname; | 248 |
249 | 249 fullname = make_uninit_multibyte_string (nbytes, nbytes); |
250 fullname = make_uninit_multibyte_string (total + needsep, | |
251 total + needsep); | |
252 bcopy (XSTRING (directory)->data, XSTRING (fullname)->data, | 250 bcopy (XSTRING (directory)->data, XSTRING (fullname)->data, |
253 dirnamelen); | 251 directory_nbytes); |
252 | |
254 if (needsep) | 253 if (needsep) |
255 XSTRING (fullname)->data[afterdirindex++] = DIRECTORY_SEP; | 254 XSTRING (fullname)->data[directory_nbytes + 1] |
255 = DIRECTORY_SEP; | |
256 | |
256 bcopy (XSTRING (name)->data, | 257 bcopy (XSTRING (name)->data, |
257 XSTRING (fullname)->data + afterdirindex, len); | 258 XSTRING (fullname)->data + directory_nbytes + needsep, |
258 nchars = chars_in_text (XSTRING (fullname)->data, | 259 len); |
259 afterdirindex + len); | 260 |
261 nchars = chars_in_text (XSTRING (fullname)->data, nbytes); | |
262 | |
263 /* Some bug somewhere. */ | |
264 if (nchars > nbytes) | |
265 abort (); | |
266 | |
260 XSTRING (fullname)->size = nchars; | 267 XSTRING (fullname)->size = nchars; |
261 if (nchars == STRING_BYTES (XSTRING (fullname))) | 268 if (nchars == nbytes) |
262 SET_STRING_BYTES (XSTRING (fullname), -1); | 269 SET_STRING_BYTES (XSTRING (fullname), -1); |
270 | |
263 finalname = fullname; | 271 finalname = fullname; |
264 } | 272 } |
265 | 273 |
266 if (attrs) | 274 if (attrs) |
267 { | 275 { |
268 /* Construct an expanded filename for the directory entry. | 276 /* Construct an expanded filename for the directory entry. |
269 Use the decoded names for input to Ffile_attributes. */ | 277 Use the decoded names for input to Ffile_attributes. */ |
270 Lisp_Object decoded_fullname; | 278 Lisp_Object decoded_fullname, fileattrs; |
271 Lisp_Object fileattrs; | 279 struct gcpro gcpro1, gcpro2; |
272 | 280 |
281 decoded_fullname = fileattrs = Qnil; | |
282 GCPRO2 (decoded_fullname, fileattrs); | |
283 | |
284 /* Both Fexpand_file_name and Ffile_attributes can GC. */ | |
273 decoded_fullname = Fexpand_file_name (name, directory); | 285 decoded_fullname = Fexpand_file_name (name, directory); |
274 fileattrs = Ffile_attributes (decoded_fullname); | 286 fileattrs = Ffile_attributes (decoded_fullname); |
275 | 287 |
276 list = Fcons (Fcons (finalname, fileattrs), list); | 288 list = Fcons (Fcons (finalname, fileattrs), list); |
289 UNGCPRO; | |
277 } | 290 } |
278 else | 291 else |
279 { | 292 list = Fcons (finalname, list); |
280 list = Fcons (finalname, list); | |
281 } | |
282 } | 293 } |
294 | |
295 UNGCPRO; | |
283 } | 296 } |
284 } | 297 } |
285 | 298 |
286 closedir (d); | 299 closedir (d); |
287 | 300 |
288 /* Discard the unwind protect. */ | 301 /* Discard the unwind protect. */ |
289 specpdl_ptr = specpdl + count; | 302 specpdl_ptr = specpdl + count; |
290 | 303 |
291 UNGCPRO; | 304 if (NILP (nosort)) |
292 if (!NILP (nosort)) | 305 list = Fsort (Fnreverse (list), |
293 return list; | 306 attrs ? Qfile_attributes_lessp : Qstring_lessp); |
294 if (attrs) | 307 |
295 return Fsort (Fnreverse (list), Qfile_attributes_lessp); | 308 RETURN_UNGCPRO (list); |
296 else | |
297 return Fsort (Fnreverse (list), Qstring_lessp); | |
298 } | 309 } |
299 | 310 |
300 | 311 |
301 DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0, | 312 DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0, |
302 "Return a list of names of files in DIRECTORY.\n\ | 313 "Return a list of names of files in DIRECTORY.\n\ |