Back to index

tetex-bin  3.0
alephbis.c
Go to the documentation of this file.
00001 /* alephbis.c: C routines to support external OCPs
00002  * based on omegabis.c from the Omega project
00003 
00004 This file is part of the Aleph project
00005 
00006 Copyleft (c) 2004 the Aleph team
00007 
00008 This library is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU Library General Public
00010 License as published by the Free Software Foundation; either
00011 version 2 of the License, or (at your option) any later version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 Library General Public License for more details.
00017 
00018 You should have received a copy of the GNU Library General Public
00019 License along with this library; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
00021 
00022 #define EXTERN extern
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <errno.h>
00026 #include <string.h>
00027 #include "alephd.h"
00028 #undef read
00029 
00030 #if 1
00031 
00032 void
00033 runexternalocp P1C(string, external_ocp_name)
00034 {
00035   char *in_file_name;
00036   char *out_file_name;
00037   FILE *in_file;
00038   FILE *out_file;
00039   int in_file_fd;
00040   int out_file_fd;
00041   char command_line[400];
00042   int i;
00043   unsigned c;
00044   int c_in;
00045 #ifdef WIN32
00046   char *tempenv;
00047 
00048 #define null_string(s) ((s == NULL) || (*s == '\0'))
00049 
00050   tempenv = getenv("TMPDIR");
00051   if (null_string(tempenv))
00052     tempenv = getenv("TEMP");
00053   if (null_string(tempenv))
00054     tempenv = getenv("TMP");
00055   if (null_string(tempenv))
00056     tempenv = "c:/tmp";     /* "/tmp" is not good if we are on a CD-ROM */
00057   in_file_name = concat(tempenv, "/__aleph__in__XXXXXX");
00058   mktemp(in_file_name);
00059   in_file = fopen(in_file_name, FOPEN_WBIN_MODE);
00060 #else
00061 
00062 #if HAVE_MKSTEMP
00063   in_file_name = xstrdup("/tmp/__aleph__in__XXXXXX");
00064   in_file_fd = mkstemp(in_file_name);
00065   in_file = fdopen(in_file_fd, FOPEN_WBIN_MODE);
00066 #else
00067 #if HAVE_MKTEMP
00068   in_file_name = xstrdup("/tmp/__aleph__in__XXXXXX");
00069   mktemp(in_file_name);
00070 #else
00071   in_file_name = xstrdup(tmpnam(NULL));
00072 #endif /* HAVE_MKTEMP */
00073   in_file = fopen(in_file_name, FOPEN_WBIN_MODE);
00074 #endif /* HAVE_MKSTEMP */
00075 
00076 #endif /* WIN32 */
00077 
00078   if (in_file == NULL)
00079     fprintf(stderr, "aleph: error opening file: %s\n", strerror(errno));
00080   
00081   for (i=1; i<=otpinputend; i++) {
00082       c = otpinputbuf[i];
00083       if (c>0xffff) {
00084           fprintf(stderr, "Aleph does not currently support 31-bit chars\n");
00085           exit(1);
00086       }
00087       if (c>0x4000000) {
00088           fputc(0xfc | ((c>>30) & 0x1), in_file);
00089           fputc(0x80 | ((c>>24) & 0x3f), in_file);
00090           fputc(0x80 | ((c>>18) & 0x3f), in_file);
00091           fputc(0x80 | ((c>>12) & 0x3f), in_file);
00092           fputc(0x80 | ((c>>6) & 0x3f), in_file);
00093           fputc(0x80 | (c & 0x3f), in_file);
00094       } else if (c>0x200000) {
00095           fputc(0xf8 | ((c>>24) & 0x3), in_file);
00096           fputc(0x80 | ((c>>18) & 0x3f), in_file);
00097           fputc(0x80 | ((c>>12) & 0x3f), in_file);
00098           fputc(0x80 | ((c>>6) & 0x3f), in_file);
00099           fputc(0x80 | (c & 0x3f), in_file);
00100       } else if (c>0x10000) {
00101           fputc(0xf0 | ((c>>18) & 0x7), in_file);
00102           fputc(0x80 | ((c>>12) & 0x3f), in_file);
00103           fputc(0x80 | ((c>>6) & 0x3f), in_file);
00104           fputc(0x80 | (c & 0x3f), in_file);
00105       } else if (c>0x800) {
00106           fputc(0xe0 | ((c>>12) & 0xf), in_file);
00107           fputc(0x80 | ((c>>6) & 0x3f), in_file);
00108           fputc(0x80 | (c & 0x3f), in_file);
00109       } else if (c>0x80) {
00110           fputc(0xc0 | ((c>>6) & 0x1f), in_file);
00111           fputc(0x80 | (c & 0x3f), in_file);
00112       } else {
00113           fputc(c & 0x7f, in_file);
00114       }
00115   }
00116   fclose(in_file);
00117   
00118 #define advance_cin if ((c_in = fgetc(out_file)) == -1) { \
00119                          fprintf(stderr, "File contains bad char\n"); \
00120                          goto end_of_while; \
00121                     }
00122                      
00123 #ifdef WIN32
00124   out_file_name = concat(tempenv, "/__aleph__out__XXXXXX");
00125   mktemp(out_file_name);
00126   out_file = fopen(out_file_name, FOPEN_RBIN_MODE);
00127 #else
00128 
00129 #if HAVE_MKSTEMP
00130   out_file_name = xstrdup("/tmp/__aleph__out__XXXXXX");
00131   out_file_fd = mkstemp(out_file_name);
00132   out_file = fdopen(out_file_fd, FOPEN_RBIN_MODE);
00133 #else
00134 #if HAVE_MKTEMP
00135   out_file_name = xstrdup("/tmp/__aleph__out__XXXXXX");
00136   mktemp(out_file_name);
00137 #else
00138   out_file_name = xstrdup(tmpnam(NULL));
00139 #endif /* HAVE_MKTEMP */
00140   out_file = fopen(out_file_name, FOPEN_RBIN_MODE);
00141 #endif /* HAVE_MKSTEMP */
00142 
00143 #endif /* WIN32 */
00144  
00145   if (out_file == NULL)
00146     fprintf(stderr, "aleph: error opening file: %s\n", strerror(errno));
00147   
00148   sprintf(command_line, "%s <%s >%s\n",
00149           external_ocp_name+1, in_file_name, out_file_name);
00150   system(command_line);
00151   otpoutputend = 0;
00152   otpoutputbuf[otpoutputend] = 0;
00153   while ((c_in = fgetc(out_file)) != -1) {
00154      if (c_in>=0xfc) {
00155          c = (c_in & 0x1)   << 30;
00156          {advance_cin}
00157          c |= (c_in & 0x3f) << 24;
00158          {advance_cin}
00159          c |= (c_in & 0x3f) << 18;
00160          {advance_cin}
00161          c |= (c_in & 0x3f) << 12;
00162          {advance_cin}
00163          c |= (c_in & 0x3f) << 6;
00164          {advance_cin}
00165          c |= c_in & 0x3f;
00166      } else if (c_in>=0xf8) {
00167          c = (c_in & 0x3) << 24;
00168          {advance_cin}
00169          c |= (c_in & 0x3f) << 18;
00170          {advance_cin}
00171          c |= (c_in & 0x3f) << 12;
00172          {advance_cin}
00173          c |= (c_in & 0x3f) << 6;
00174          {advance_cin}
00175          c |= c_in & 0x3f;
00176      } else if (c_in>=0xf0) {
00177          c = (c_in & 0x7) << 18;
00178          {advance_cin}
00179          c |= (c_in & 0x3f) << 12;
00180          {advance_cin}
00181          c |= (c_in & 0x3f) << 6;
00182          {advance_cin}
00183          c |= c_in & 0x3f;
00184      } else if (c_in>=0xe0) {
00185          c = (c_in & 0xf) << 12;
00186          {advance_cin}
00187          c |= (c_in & 0x3f) << 6;
00188          {advance_cin}
00189          c |= c_in & 0x3f;
00190      } else if (c_in>=0x80) {
00191          c = (c_in & 0x1f) << 6;
00192          {advance_cin}
00193          c |= c_in & 0x3f;
00194      } else {
00195          c = c_in & 0x7f;
00196      }
00197      otpoutputbuf[++otpoutputend] = c;
00198   }
00199 
00200 end_of_while:
00201   remove(in_file_name);
00202   remove(out_file_name);
00203 }
00204 
00205 #else
00206 
00207 void
00208 runexternalocp P1C(string, external_ocp_name)
00209 {
00210   int outpipes[2], inpipes[2];
00211   char *outbuf;
00212   char *inbuf;
00213   int n;
00214   int chars_read_in, chars_to_go_out;
00215   int myerrno;
00216 
00217 #ifdef WIN32
00218   STARTUPINFO si;
00219   PROCESS_INFORMATION pi;
00220   HANDLE hIn, hOut, hPipeIn, hPipeOut;
00221   SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
00222   DWORD ret = 0;
00223 
00224   /* Make pipes to send data from the parent to the child.  The parent
00225      writes to outpipes[0], and the child reads from outpipes[1].  */
00226   _pipe (outpipes, 0, _O_BINARY);
00227   /* Make pipes to send data from the child to the parent.  The child
00228      writes to inpipes[0], and the parent reads from inpipes[1].  */
00229   _pipe (inpipes, 0, _O_BINARY);
00230 
00231   ZeroMemory( &si, sizeof(STARTUPINFO) );
00232   si.cb = sizeof(STARTUPINFO);
00233   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
00234   si.wShowWindow = SW_SHOW;
00235   si.hStdInput = _get_osfhandle(outpipes[0]);
00236   si.hStdOutput = _get_osfhandle(inpipes[1]);
00237   si.hStdError = _get_osfhandle(_fileno(stderr));
00238 
00239   /* Close unnecessary pipes.  */
00240   close (outpipes[1]);
00241   close (inpipes[0]);
00242 
00243   if (CreateProcess(external_ocp_name+1,
00244                   NULL, /* Use lpApplicationName */
00245                   NULL,
00246                   NULL,
00247                   TRUE, /* bInheritHandles */
00248                   0,
00249                   NULL,
00250                   NULL,
00251                   &si,
00252                   &pi) == 0) {
00253     fprintf(stderr, "Failed to create process for %s (Error %d).\n", external_ocp_name+1, GetLastError());
00254     return;
00255   }
00256   
00257 #else /* ! WIN32 */
00258 
00259   /* Make pipes to send data from the parent to the child.  The parent
00260      writes to outpipes[0], and the child reads from outpipes[1].  */
00261   pipe (outpipes);
00262   /* Make pipes to send data from the child to the parent.  The child
00263      writes to inpipes[0], and the parent reads from inpipes[1].  */
00264   pipe (inpipes);
00265 
00266   /* For a child process.  */
00267   if (fork () == 0)
00268     {
00269       /* This part is executed by the child process.  It translates
00270          lower case letters to upper case.  */
00271 
00272       char *prog = external_ocp_name+1;
00273       char *args[] = {external_ocp_name+1, NULL};
00274 
00275       /* Close unnecessary pipes.  They are for the parent.  */
00276       close (outpipes[1]);
00277       close (inpipes[0]);
00278 
00279       /* Connect pipes to stdin and stdout.  */
00280       dup2 (outpipes[0], 0);
00281       dup2 (inpipes[1], 1);
00282 
00283       /* Overlays a new process image on an old process. */
00284       execv (prog, args);
00285 
00286       /* We should never reach here. */
00287     }
00288   else
00289     {
00290       /* Close unnecessary pipes.  They are for the child.  */
00291       close (outpipes[0]);
00292       close (inpipes[1]);
00293 
00294 #endif /* WIN32 */
00295 
00296 /* Here is the interesting part */
00297       outbuf = ((char *) otpinputbuf)+2;
00298       inbuf = ((char *) otpoutputbuf)+2;
00299       chars_to_go_out = 2*otpinputend;
00300       chars_read_in = 0;
00301       while ((n = write (outpipes[1], outbuf, chars_to_go_out))>0) {
00302 fprintf(stderr, "Wrote (1) %d characters\n", n);
00303         outbuf+=n;
00304         chars_to_go_out-=n;
00305         if (chars_to_go_out==0) goto done_writing;
00306 /*
00307         n = read (inpipes[0], inbuf, 1024);
00308 fprintf(stderr, "Read (1) %d characters\n", n);
00309         inbuf+=n;
00310         chars_read_in+=n;
00311 */
00312       }
00313 fprintf(stderr, "Wrote (2) %d characters\n", n);
00314 
00315 done_writing:
00316       close (outpipes[1]);
00317       while ((n = read (inpipes[0], inbuf, 1024)) > 0) {
00318 fprintf(stderr, "Read (2) %d characters\n", n);
00319         inbuf+=n;
00320         chars_read_in+=n;
00321       }
00322 fprintf(stderr, "Read (3) %d characters\n", n);
00323       otpoutputend = chars_read_in / 2;
00324 
00325       close (inpipes[0]);
00326 #ifndef WIN32
00327     }
00328 #endif
00329 }
00330 
00331 #endif