diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/web2c/alephdir/alephbis.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/alephdir/alephbis.c')
-rw-r--r-- | Build/source/texk/web2c/alephdir/alephbis.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/alephdir/alephbis.c b/Build/source/texk/web2c/alephdir/alephbis.c new file mode 100644 index 00000000000..45594d422f5 --- /dev/null +++ b/Build/source/texk/web2c/alephdir/alephbis.c @@ -0,0 +1,331 @@ +/* alephbis.c: C routines to support external OCPs + * based on omegabis.c from the Omega project + +This file is part of the Aleph project + +Copyleft (c) 2004 the Aleph team + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define EXTERN extern +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include "alephd.h" +#undef read + +#if 1 + +void +runexternalocp P1C(string, external_ocp_name) +{ + char *in_file_name; + char *out_file_name; + FILE *in_file; + FILE *out_file; + int in_file_fd; + int out_file_fd; + char command_line[400]; + int i; + unsigned c; + int c_in; +#ifdef WIN32 + char *tempenv; + +#define null_string(s) ((s == NULL) || (*s == '\0')) + + tempenv = getenv("TMPDIR"); + if (null_string(tempenv)) + tempenv = getenv("TEMP"); + if (null_string(tempenv)) + tempenv = getenv("TMP"); + if (null_string(tempenv)) + tempenv = "c:/tmp"; /* "/tmp" is not good if we are on a CD-ROM */ + in_file_name = concat(tempenv, "/__aleph__in__XXXXXX"); + mktemp(in_file_name); + in_file = fopen(in_file_name, FOPEN_WBIN_MODE); +#else + +#if HAVE_MKSTEMP + in_file_name = xstrdup("/tmp/__aleph__in__XXXXXX"); + in_file_fd = mkstemp(in_file_name); + in_file = fdopen(in_file_fd, FOPEN_WBIN_MODE); +#else +#if HAVE_MKTEMP + in_file_name = xstrdup("/tmp/__aleph__in__XXXXXX"); + mktemp(in_file_name); +#else + in_file_name = xstrdup(tmpnam(NULL)); +#endif /* HAVE_MKTEMP */ + in_file = fopen(in_file_name, FOPEN_WBIN_MODE); +#endif /* HAVE_MKSTEMP */ + +#endif /* WIN32 */ + + if (in_file == NULL) + fprintf(stderr, "aleph: error opening file: %s\n", strerror(errno)); + + for (i=1; i<=otpinputend; i++) { + c = otpinputbuf[i]; + if (c>0xffff) { + fprintf(stderr, "Aleph does not currently support 31-bit chars\n"); + exit(1); + } + if (c>0x4000000) { + fputc(0xfc | ((c>>30) & 0x1), in_file); + fputc(0x80 | ((c>>24) & 0x3f), in_file); + fputc(0x80 | ((c>>18) & 0x3f), in_file); + fputc(0x80 | ((c>>12) & 0x3f), in_file); + fputc(0x80 | ((c>>6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c>0x200000) { + fputc(0xf8 | ((c>>24) & 0x3), in_file); + fputc(0x80 | ((c>>18) & 0x3f), in_file); + fputc(0x80 | ((c>>12) & 0x3f), in_file); + fputc(0x80 | ((c>>6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c>0x10000) { + fputc(0xf0 | ((c>>18) & 0x7), in_file); + fputc(0x80 | ((c>>12) & 0x3f), in_file); + fputc(0x80 | ((c>>6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c>0x800) { + fputc(0xe0 | ((c>>12) & 0xf), in_file); + fputc(0x80 | ((c>>6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c>0x80) { + fputc(0xc0 | ((c>>6) & 0x1f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else { + fputc(c & 0x7f, in_file); + } + } + fclose(in_file); + +#define advance_cin if ((c_in = fgetc(out_file)) == -1) { \ + fprintf(stderr, "File contains bad char\n"); \ + goto end_of_while; \ + } + +#ifdef WIN32 + out_file_name = concat(tempenv, "/__aleph__out__XXXXXX"); + mktemp(out_file_name); + out_file = fopen(out_file_name, FOPEN_RBIN_MODE); +#else + +#if HAVE_MKSTEMP + out_file_name = xstrdup("/tmp/__aleph__out__XXXXXX"); + out_file_fd = mkstemp(out_file_name); + out_file = fdopen(out_file_fd, FOPEN_RBIN_MODE); +#else +#if HAVE_MKTEMP + out_file_name = xstrdup("/tmp/__aleph__out__XXXXXX"); + mktemp(out_file_name); +#else + out_file_name = xstrdup(tmpnam(NULL)); +#endif /* HAVE_MKTEMP */ + out_file = fopen(out_file_name, FOPEN_RBIN_MODE); +#endif /* HAVE_MKSTEMP */ + +#endif /* WIN32 */ + + if (out_file == NULL) + fprintf(stderr, "aleph: error opening file: %s\n", strerror(errno)); + + sprintf(command_line, "%s <%s >%s\n", + external_ocp_name+1, in_file_name, out_file_name); + system(command_line); + otpoutputend = 0; + otpoutputbuf[otpoutputend] = 0; + while ((c_in = fgetc(out_file)) != -1) { + if (c_in>=0xfc) { + c = (c_in & 0x1) << 30; + {advance_cin} + c |= (c_in & 0x3f) << 24; + {advance_cin} + c |= (c_in & 0x3f) << 18; + {advance_cin} + c |= (c_in & 0x3f) << 12; + {advance_cin} + c |= (c_in & 0x3f) << 6; + {advance_cin} + c |= c_in & 0x3f; + } else if (c_in>=0xf8) { + c = (c_in & 0x3) << 24; + {advance_cin} + c |= (c_in & 0x3f) << 18; + {advance_cin} + c |= (c_in & 0x3f) << 12; + {advance_cin} + c |= (c_in & 0x3f) << 6; + {advance_cin} + c |= c_in & 0x3f; + } else if (c_in>=0xf0) { + c = (c_in & 0x7) << 18; + {advance_cin} + c |= (c_in & 0x3f) << 12; + {advance_cin} + c |= (c_in & 0x3f) << 6; + {advance_cin} + c |= c_in & 0x3f; + } else if (c_in>=0xe0) { + c = (c_in & 0xf) << 12; + {advance_cin} + c |= (c_in & 0x3f) << 6; + {advance_cin} + c |= c_in & 0x3f; + } else if (c_in>=0x80) { + c = (c_in & 0x1f) << 6; + {advance_cin} + c |= c_in & 0x3f; + } else { + c = c_in & 0x7f; + } + otpoutputbuf[++otpoutputend] = c; + } + +end_of_while: + remove(in_file_name); + remove(out_file_name); +} + +#else + +void +runexternalocp P1C(string, external_ocp_name) +{ + int outpipes[2], inpipes[2]; + char *outbuf; + char *inbuf; + int n; + int chars_read_in, chars_to_go_out; + int myerrno; + +#ifdef WIN32 + STARTUPINFO si; + PROCESS_INFORMATION pi; + HANDLE hIn, hOut, hPipeIn, hPipeOut; + SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + DWORD ret = 0; + + /* Make pipes to send data from the parent to the child. The parent + writes to outpipes[0], and the child reads from outpipes[1]. */ + _pipe (outpipes, 0, _O_BINARY); + /* Make pipes to send data from the child to the parent. The child + writes to inpipes[0], and the parent reads from inpipes[1]. */ + _pipe (inpipes, 0, _O_BINARY); + + ZeroMemory( &si, sizeof(STARTUPINFO) ); + si.cb = sizeof(STARTUPINFO); + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOW; + si.hStdInput = _get_osfhandle(outpipes[0]); + si.hStdOutput = _get_osfhandle(inpipes[1]); + si.hStdError = _get_osfhandle(_fileno(stderr)); + + /* Close unnecessary pipes. */ + close (outpipes[1]); + close (inpipes[0]); + + if (CreateProcess(external_ocp_name+1, + NULL, /* Use lpApplicationName */ + NULL, + NULL, + TRUE, /* bInheritHandles */ + 0, + NULL, + NULL, + &si, + &pi) == 0) { + fprintf(stderr, "Failed to create process for %s (Error %d).\n", external_ocp_name+1, GetLastError()); + return; + } + +#else /* ! WIN32 */ + + /* Make pipes to send data from the parent to the child. The parent + writes to outpipes[0], and the child reads from outpipes[1]. */ + pipe (outpipes); + /* Make pipes to send data from the child to the parent. The child + writes to inpipes[0], and the parent reads from inpipes[1]. */ + pipe (inpipes); + + /* For a child process. */ + if (fork () == 0) + { + /* This part is executed by the child process. It translates + lower case letters to upper case. */ + + char *prog = external_ocp_name+1; + char *args[] = {external_ocp_name+1, NULL}; + + /* Close unnecessary pipes. They are for the parent. */ + close (outpipes[1]); + close (inpipes[0]); + + /* Connect pipes to stdin and stdout. */ + dup2 (outpipes[0], 0); + dup2 (inpipes[1], 1); + + /* Overlays a new process image on an old process. */ + execv (prog, args); + + /* We should never reach here. */ + } + else + { + /* Close unnecessary pipes. They are for the child. */ + close (outpipes[0]); + close (inpipes[1]); + +#endif /* WIN32 */ + +/* Here is the interesting part */ + outbuf = ((char *) otpinputbuf)+2; + inbuf = ((char *) otpoutputbuf)+2; + chars_to_go_out = 2*otpinputend; + chars_read_in = 0; + while ((n = write (outpipes[1], outbuf, chars_to_go_out))>0) { +fprintf(stderr, "Wrote (1) %d characters\n", n); + outbuf+=n; + chars_to_go_out-=n; + if (chars_to_go_out==0) goto done_writing; +/* + n = read (inpipes[0], inbuf, 1024); +fprintf(stderr, "Read (1) %d characters\n", n); + inbuf+=n; + chars_read_in+=n; +*/ + } +fprintf(stderr, "Wrote (2) %d characters\n", n); + +done_writing: + close (outpipes[1]); + while ((n = read (inpipes[0], inbuf, 1024)) > 0) { +fprintf(stderr, "Read (2) %d characters\n", n); + inbuf+=n; + chars_read_in+=n; + } +fprintf(stderr, "Read (3) %d characters\n", n); + otpoutputend = chars_read_in / 2; + + close (inpipes[0]); +#ifndef WIN32 + } +#endif +} + +#endif |