diff options
| author | Karl Heuer | 1997-02-20 06:46:14 +0000 |
|---|---|---|
| committer | Karl Heuer | 1997-02-20 06:46:14 +0000 |
| commit | 32d08644825676dc29359934d0304e1729cb5524 (patch) | |
| tree | 1cf3f1ebba467ad659a0c633a1e13a220f669754 /src | |
| parent | 40b2421cb01fc1fe1538bcc804c3e1d70b263ddd (diff) | |
| download | emacs-32d08644825676dc29359934d0304e1729cb5524.tar.gz emacs-32d08644825676dc29359934d0304e1729cb5524.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/callproc.c | 140 |
1 files changed, 131 insertions, 9 deletions
diff --git a/src/callproc.c b/src/callproc.c index 5d743d30696..c4d631618e1 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -71,6 +71,8 @@ extern char *strerror (); | |||
| 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" |
| @@ -219,6 +221,9 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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; |
| @@ -229,6 +234,50 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 229 | error ("Operating system cannot handle asynchronous subprocesses"); | 234 | error ("Operating system cannot handle asynchronous subprocesses"); |
| 230 | #endif /* subprocesses */ | 235 | #endif /* subprocesses */ |
| 231 | 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 | } | ||
| 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); |
| @@ -328,7 +377,21 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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 | } |
| @@ -440,7 +503,9 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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); |
| @@ -530,7 +595,7 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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 |
| @@ -549,13 +614,32 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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. */ |
| @@ -565,6 +649,12 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 565 | bufptr = (char *) alloca (bufsize); | 649 | bufptr = (char *) alloca (bufsize); |
| 566 | } | 650 | } |
| 567 | 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); | ||
| 657 | |||
| 568 | if (!NILP (display) && INTERACTIVE) | 658 | if (!NILP (display) && INTERACTIVE) |
| 569 | { | 659 | { |
| 570 | if (first) | 660 | if (first) |
| @@ -634,6 +724,10 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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'; |
| @@ -668,13 +762,41 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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 | ||