Mercurial > emacs
comparison src/callproc.c @ 17025:3c222a7edda1
Include charset.h and coding.h.
(Fcall_process): Perform character code conversion of a process
arguments and the process output.
(Fcall_process_region): Encode coding of a text given to a
process.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Thu, 20 Feb 1997 06:46:14 +0000 |
parents | e7bf457086fb |
children | 19b17b4f765d |
comparison
equal
deleted
inserted
replaced
17024:6cfba7f41dca | 17025:3c222a7edda1 |
---|---|
69 #endif | 69 #endif |
70 | 70 |
71 #include "lisp.h" | 71 #include "lisp.h" |
72 #include "commands.h" | 72 #include "commands.h" |
73 #include "buffer.h" | 73 #include "buffer.h" |
74 #include "charset.h" | |
75 #include "coding.h" | |
74 #include <paths.h> | 76 #include <paths.h> |
75 #include "process.h" | 77 #include "process.h" |
76 #include "syssignal.h" | 78 #include "syssignal.h" |
77 #include "systty.h" | 79 #include "systty.h" |
78 | 80 |
217 int outfilefd; | 219 int outfilefd; |
218 #endif | 220 #endif |
219 #if 0 | 221 #if 0 |
220 int mask; | 222 int mask; |
221 #endif | 223 #endif |
224 struct coding_system process_coding; /* coding-system of process output */ | |
225 struct coding_system argument_coding; /* coding-system of arguments */ | |
226 | |
222 CHECK_STRING (args[0], 0); | 227 CHECK_STRING (args[0], 0); |
223 | 228 |
224 error_file = Qt; | 229 error_file = Qt; |
225 | 230 |
226 #ifndef subprocesses | 231 #ifndef subprocesses |
227 /* Without asynchronous processes we cannot have BUFFER == 0. */ | 232 /* Without asynchronous processes we cannot have BUFFER == 0. */ |
228 if (nargs >= 3 && INTEGERP (args[2])) | 233 if (nargs >= 3 && INTEGERP (args[2])) |
229 error ("Operating system cannot handle asynchronous subprocesses"); | 234 error ("Operating system cannot handle asynchronous subprocesses"); |
230 #endif /* subprocesses */ | 235 #endif /* subprocesses */ |
236 | |
237 /* Decide the coding-system for giving arguments and reading process | |
238 output. */ | |
239 { | |
240 Lisp_Object val, *args2; | |
241 /* Qt denotes that we have not yet called Ffind_coding_system. */ | |
242 Lisp_Object coding_systems = Qt; | |
243 int i; | |
244 | |
245 /* If arguments are supplied, we may have to encode them. */ | |
246 if (nargs >= 5) | |
247 { | |
248 if (NILP (val = Vcoding_system_for_write)) | |
249 { | |
250 args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); | |
251 args2[0] = Qcall_process; | |
252 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; | |
253 coding_systems = Ffind_coding_system (nargs + 1, args2); | |
254 val = CONSP (coding_systems) ? XCONS (coding_systems)->cdr : Qnil; | |
255 } | |
256 setup_coding_system (Fcheck_coding_system (val), &argument_coding); | |
257 } | |
258 | |
259 /* If BUFFER is nil, we must read process output once and then | |
260 discard it, so setup coding system but with nil. If BUFFER is | |
261 an integer, we can discard it without reading. */ | |
262 if (nargs < 3 || NILP (args[2])) | |
263 setup_coding_system (Qnil, &process_coding); | |
264 else if (!INTEGERP (args[2])) | |
265 { | |
266 if (NILP (val = Vcoding_system_for_read)) | |
267 { | |
268 if (!EQ (coding_systems, Qt)) | |
269 { | |
270 args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); | |
271 args2[0] = Qcall_process; | |
272 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; | |
273 coding_systems = Ffind_coding_system (nargs + 1, args2); | |
274 } | |
275 val = CONSP (coding_systems) ? XCONS (coding_systems)->car : Qnil; | |
276 } | |
277 setup_coding_system (Fcheck_coding_system (val), &process_coding); | |
278 } | |
279 } | |
231 | 280 |
232 if (nargs >= 2 && ! NILP (args[1])) | 281 if (nargs >= 2 && ! NILP (args[1])) |
233 { | 282 { |
234 infile = Fexpand_file_name (args[1], current_buffer->directory); | 283 infile = Fexpand_file_name (args[1], current_buffer->directory); |
235 CHECK_STRING (infile, 1); | 284 CHECK_STRING (infile, 1); |
326 { | 375 { |
327 register int i; | 376 register int i; |
328 for (i = 4; i < nargs; i++) | 377 for (i = 4; i < nargs; i++) |
329 { | 378 { |
330 CHECK_STRING (args[i], i); | 379 CHECK_STRING (args[i], i); |
331 new_argv[i - 3] = XSTRING (args[i])->data; | 380 if (argument_coding.type == coding_type_no_conversion) |
381 new_argv[i - 3] = XSTRING (args[i])->data; | |
382 else | |
383 { | |
384 /* We must encode the arguments. */ | |
385 int size = encoding_buffer_size (&argument_coding, | |
386 XSTRING (args[i])->size); | |
387 int produced, dummy; | |
388 | |
389 new_argv[i - 3] = (unsigned char *) alloca (size); | |
390 produced = encode_coding (&argument_coding, | |
391 XSTRING (args[i])->data, new_argv[i - 3], | |
392 XSTRING (args[i])->size, size, &dummy); | |
393 new_argv[i - 3][produced] = 0; | |
394 } | |
332 } | 395 } |
333 new_argv[i - 3] = 0; | 396 new_argv[i - 3] = 0; |
334 } | 397 } |
335 | 398 |
336 #ifdef MSDOS /* MW, July 1993 */ | 399 #ifdef MSDOS /* MW, July 1993 */ |
438 | 501 |
439 close (outfilefd); | 502 close (outfilefd); |
440 if (fd_error != outfilefd) | 503 if (fd_error != outfilefd) |
441 close (fd_error); | 504 close (fd_error); |
442 fd1 = -1; /* No harm in closing that one! */ | 505 fd1 = -1; /* No harm in closing that one! */ |
443 fd[0] = open (tempfile, NILP (Vbinary_process_output) ? O_TEXT : O_BINARY); | 506 /* Since CRLF is converted to LF within `decode_coding', we can |
507 always open a file with binary mode. */ | |
508 fd[0] = open (tempfile, O_BINARY); | |
444 if (fd[0] < 0) | 509 if (fd[0] < 0) |
445 { | 510 { |
446 unlink (tempfile); | 511 unlink (tempfile); |
447 close (filefd); | 512 close (filefd); |
448 report_file_error ("Cannot re-open temporary file", Qnil); | 513 report_file_error ("Cannot re-open temporary file", Qnil); |
528 { | 593 { |
529 /* Repeatedly read until we've filled as much as possible | 594 /* Repeatedly read until we've filled as much as possible |
530 of the buffer size we have. But don't read | 595 of the buffer size we have. But don't read |
531 less than 1024--save that for the next bufferful. */ | 596 less than 1024--save that for the next bufferful. */ |
532 | 597 |
533 nread = 0; | 598 nread = process_coding.carryover_size; /* This value is initially 0. */ |
534 while (nread < bufsize - 1024) | 599 while (nread < bufsize - 1024) |
535 { | 600 { |
536 int this_read | 601 int this_read |
537 = read (fd[0], bufptr + nread, bufsize - nread); | 602 = read (fd[0], bufptr + nread, bufsize - nread); |
538 | 603 |
547 | 612 |
548 give_up_1: | 613 give_up_1: |
549 | 614 |
550 /* Now NREAD is the total amount of data in the buffer. */ | 615 /* Now NREAD is the total amount of data in the buffer. */ |
551 if (nread == 0) | 616 if (nread == 0) |
552 break; | 617 /* Here, just tell decode_coding that we are processing the |
618 last block. We break the loop after decoding. */ | |
619 process_coding.last_block = 1; | |
553 | 620 |
554 immediate_quit = 0; | 621 immediate_quit = 0; |
555 total_read += nread; | 622 total_read += nread; |
556 | 623 |
557 if (!NILP (buffer)) | 624 if (!NILP (buffer)) |
558 insert (bufptr, nread); | 625 { |
626 if (process_coding.type == coding_type_no_conversion) | |
627 insert (bufptr, nread); | |
628 else | |
629 { /* We have to decode the input. */ | |
630 int size = decoding_buffer_size (&process_coding, bufsize); | |
631 char *decoding_buf = get_conversion_buffer (size); | |
632 int dummy; | |
633 | |
634 nread = decode_coding (&process_coding, bufptr, decoding_buf, | |
635 nread, size, &dummy); | |
636 if (nread > 0) | |
637 insert (decoding_buf, nread); | |
638 } | |
639 } | |
640 | |
641 if (process_coding.last_block) | |
642 break; | |
559 | 643 |
560 /* Make the buffer bigger as we continue to read more data, | 644 /* Make the buffer bigger as we continue to read more data, |
561 but not past 64k. */ | 645 but not past 64k. */ |
562 if (bufsize < 64 * 1024 && total_read > 32 * bufsize) | 646 if (bufsize < 64 * 1024 && total_read > 32 * bufsize) |
563 { | 647 { |
564 bufsize *= 2; | 648 bufsize *= 2; |
565 bufptr = (char *) alloca (bufsize); | 649 bufptr = (char *) alloca (bufsize); |
566 } | 650 } |
651 | |
652 if (!NILP (buffer) && process_coding.carryover_size > 0) | |
653 /* We have carryover in the last decoding. It should be | |
654 processed again after reading more data. */ | |
655 bcopy (process_coding.carryover, bufptr, | |
656 process_coding.carryover_size); | |
567 | 657 |
568 if (!NILP (display) && INTERACTIVE) | 658 if (!NILP (display) && INTERACTIVE) |
569 { | 659 { |
570 if (first) | 660 if (first) |
571 prepare_menu_bars (); | 661 prepare_menu_bars (); |
632 { | 722 { |
633 struct gcpro gcpro1; | 723 struct gcpro gcpro1; |
634 Lisp_Object filename_string; | 724 Lisp_Object filename_string; |
635 register Lisp_Object start, end; | 725 register Lisp_Object start, end; |
636 int count = specpdl_ptr - specpdl; | 726 int count = specpdl_ptr - specpdl; |
727 /* Qt denotes that we have not yet called Ffind_coding_system. */ | |
728 Lisp_Object coding_systems = Qt; | |
729 Lisp_Object val, *args2; | |
730 int i; | |
637 #ifdef DOS_NT | 731 #ifdef DOS_NT |
638 char *tempfile; | 732 char *tempfile; |
639 char *outf = '\0'; | 733 char *outf = '\0'; |
640 | 734 |
641 if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP"))) | 735 if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP"))) |
666 | 760 |
667 filename_string = build_string (tempfile); | 761 filename_string = build_string (tempfile); |
668 GCPRO1 (filename_string); | 762 GCPRO1 (filename_string); |
669 start = args[0]; | 763 start = args[0]; |
670 end = args[1]; | 764 end = args[1]; |
765 /* Decide coding-system of the contents of the temporary file. */ | |
671 #ifdef DOS_NT | 766 #ifdef DOS_NT |
672 specbind (Qbuffer_file_type, Vbinary_process_input); | 767 specbind (Qbuffer_file_type, Vbinary_process_input); |
768 if (NILP (Vbinary_process_input)) | |
769 val = Qnil; | |
770 else | |
771 #endif | |
772 if (NILP (val = Vcoding_system_for_write)) | |
773 { | |
774 args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); | |
775 args2[0] = Qcall_process_region; | |
776 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; | |
777 coding_systems = Ffind_coding_system (nargs + 1, args2); | |
778 val = CONSP (coding_systems) ? XCONS (coding_systems)->cdr : Qnil; | |
779 } | |
780 specbind (intern ("coding-system-for-write"), val); | |
673 Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil); | 781 Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil); |
674 unbind_to (count, Qnil); | 782 |
675 #else /* not DOS_NT */ | 783 #ifdef DOS_NT |
676 Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil); | 784 if (NILP (Vbinary_process_input)) |
677 #endif /* not DOS_NT */ | 785 val = Qnil; |
786 else | |
787 #endif | |
788 if (NILP (val = Vcoding_system_for_read)) | |
789 { | |
790 if (EQ (coding_systems, Qt)) | |
791 { | |
792 args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); | |
793 args2[0] = Qcall_process_region; | |
794 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; | |
795 coding_systems = Ffind_coding_system (nargs + 1, args2); | |
796 } | |
797 val = CONSP (coding_systems) ? XCONS (coding_systems)->car : Qnil; | |
798 } | |
799 specbind (intern ("coding-system-for-read"), val); | |
678 | 800 |
679 record_unwind_protect (delete_temp_file, filename_string); | 801 record_unwind_protect (delete_temp_file, filename_string); |
680 | 802 |
681 if (!NILP (args[3])) | 803 if (!NILP (args[3])) |
682 Fdelete_region (start, end); | 804 Fdelete_region (start, end); |