diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/src/fileio.c b/src/fileio.c index e3a2cc9f2bb..d21007a7ce8 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -2339,15 +2339,18 @@ otherwise, if FILE2 does not exist, the answer is t.") | |||
| 2339 | } | 2339 | } |
| 2340 | 2340 | ||
| 2341 | DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, | 2341 | DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, |
| 2342 | 1, 2, 0, | 2342 | 1, 4, 0, |
| 2343 | "Insert contents of file FILENAME after point.\n\ | 2343 | "Insert contents of file FILENAME after point.\n\ |
| 2344 | Returns list of absolute pathname and length of data inserted.\n\ | 2344 | Returns list of absolute file name and length of data inserted.\n\ |
| 2345 | If second argument VISIT is non-nil, the buffer's visited filename\n\ | 2345 | If second argument VISIT is non-nil, the buffer's visited filename\n\ |
| 2346 | and last save file modtime are set, and it is marked unmodified.\n\ | 2346 | and last save file modtime are set, and it is marked unmodified.\n\ |
| 2347 | If visiting and the file does not exist, visiting is completed\n\ | 2347 | If visiting and the file does not exist, visiting is completed\n\ |
| 2348 | before the error is signaled.") | 2348 | before the error is signaled.\n\n\ |
| 2349 | (filename, visit) | 2349 | The optional third and fourth arguments BEG and END\n\ |
| 2350 | Lisp_Object filename, visit; | 2350 | specify what portion of the file to insert.\n\ |
| 2351 | If VISIT is non-nil, BEG and END must be nil.") | ||
| 2352 | (filename, visit, beg, end) | ||
| 2353 | Lisp_Object filename, visit, beg, end; | ||
| 2351 | { | 2354 | { |
| 2352 | struct stat st; | 2355 | struct stat st; |
| 2353 | register int fd; | 2356 | register int fd; |
| @@ -2356,6 +2359,7 @@ before the error is signaled.") | |||
| 2356 | int count = specpdl_ptr - specpdl; | 2359 | int count = specpdl_ptr - specpdl; |
| 2357 | struct gcpro gcpro1; | 2360 | struct gcpro gcpro1; |
| 2358 | Lisp_Object handler, val; | 2361 | Lisp_Object handler, val; |
| 2362 | int total; | ||
| 2359 | 2363 | ||
| 2360 | val = Qnil; | 2364 | val = Qnil; |
| 2361 | 2365 | ||
| @@ -2371,7 +2375,7 @@ before the error is signaled.") | |||
| 2371 | handler = Ffind_file_name_handler (filename); | 2375 | handler = Ffind_file_name_handler (filename); |
| 2372 | if (!NILP (handler)) | 2376 | if (!NILP (handler)) |
| 2373 | { | 2377 | { |
| 2374 | val = call3 (handler, Qinsert_file_contents, filename, visit); | 2378 | val = call5 (handler, Qinsert_file_contents, filename, visit, beg, end); |
| 2375 | st.st_mtime = 0; | 2379 | st.st_mtime = 0; |
| 2376 | goto handled; | 2380 | goto handled; |
| 2377 | } | 2381 | } |
| @@ -2410,12 +2414,32 @@ before the error is signaled.") | |||
| 2410 | if (st.st_size < 0) | 2414 | if (st.st_size < 0) |
| 2411 | error ("File size is negative"); | 2415 | error ("File size is negative"); |
| 2412 | 2416 | ||
| 2417 | if (!NILP (beg) || !NILP (end)) | ||
| 2418 | if (!NILP (visit)) | ||
| 2419 | error ("Attempt to visit less than an entire file"); | ||
| 2420 | |||
| 2421 | if (!NILP (beg)) | ||
| 2422 | CHECK_NUMBER (beg, 0); | ||
| 2423 | else | ||
| 2424 | XFASTINT (beg) = 0; | ||
| 2425 | |||
| 2426 | if (!NILP (end)) | ||
| 2427 | CHECK_NUMBER (end, 0); | ||
| 2428 | else | ||
| 2429 | { | ||
| 2430 | XSETINT (end, st.st_size); | ||
| 2431 | if (XINT (end) != st.st_size) | ||
| 2432 | error ("maximum buffer size exceeded"); | ||
| 2433 | } | ||
| 2434 | |||
| 2435 | total = XINT (end) - XINT (beg); | ||
| 2436 | |||
| 2413 | { | 2437 | { |
| 2414 | register Lisp_Object temp; | 2438 | register Lisp_Object temp; |
| 2415 | 2439 | ||
| 2416 | /* Make sure point-max won't overflow after this insertion. */ | 2440 | /* Make sure point-max won't overflow after this insertion. */ |
| 2417 | XSET (temp, Lisp_Int, st.st_size + Z); | 2441 | XSET (temp, Lisp_Int, total); |
| 2418 | if (st.st_size + Z != XINT (temp)) | 2442 | if (total != XINT (temp)) |
| 2419 | error ("maximum buffer size exceeded"); | 2443 | error ("maximum buffer size exceeded"); |
| 2420 | } | 2444 | } |
| 2421 | 2445 | ||
| @@ -2423,12 +2447,18 @@ before the error is signaled.") | |||
| 2423 | prepare_to_modify_buffer (point, point); | 2447 | prepare_to_modify_buffer (point, point); |
| 2424 | 2448 | ||
| 2425 | move_gap (point); | 2449 | move_gap (point); |
| 2426 | if (GAP_SIZE < st.st_size) | 2450 | if (GAP_SIZE < total) |
| 2427 | make_gap (st.st_size - GAP_SIZE); | 2451 | make_gap (total - GAP_SIZE); |
| 2428 | 2452 | ||
| 2453 | if (XINT (beg) != 0) | ||
| 2454 | { | ||
| 2455 | if (lseek (fd, XINT (beg), 0) < 0) | ||
| 2456 | report_file_error ("Setting file position", Fcons (filename, Qnil)); | ||
| 2457 | } | ||
| 2458 | |||
| 2429 | while (1) | 2459 | while (1) |
| 2430 | { | 2460 | { |
| 2431 | int try = min (st.st_size - inserted, 64 << 10); | 2461 | int try = min (total - inserted, 64 << 10); |
| 2432 | int this; | 2462 | int this; |
| 2433 | 2463 | ||
| 2434 | /* Allow quitting out of the actual I/O. */ | 2464 | /* Allow quitting out of the actual I/O. */ |
| @@ -2503,7 +2533,7 @@ before the error is signaled.") | |||
| 2503 | Fcons (make_number (inserted), | 2533 | Fcons (make_number (inserted), |
| 2504 | Qnil))); | 2534 | Qnil))); |
| 2505 | } | 2535 | } |
| 2506 | 2536 | ||
| 2507 | DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 5, | 2537 | DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 5, |
| 2508 | "r\nFWrite region to file: ", | 2538 | "r\nFWrite region to file: ", |
| 2509 | "Write current region into specified file.\n\ | 2539 | "Write current region into specified file.\n\ |