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\