Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/* tm_openaxiom.c
2
* COPYRIGHT : (C) 2004 Bill Page <[email protected]>
3
* (Portions) COPYRIGHT : (C) 1999 Andrey Grozin
4
***********************************************************************
5
* This software falls under the GNU general public license and comes
6
* WITHOUT ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE
7
* for more details. If you don't have this file, write to the Free
8
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
9
* MA 02111-1307, USA.
10
***********************************************************************
11
*
12
* The program runs OPENAXIOMsys as a separate process under Windows
13
* using CreateProcess() and asynchronous reader threads. It provides
14
* an interface between OpenAxiom and TeXmacs for windows.
15
*
16
* Before launching, stdin/out/err are each redirected into pipes
17
* so that OPENAXIOM can be fed commands and its output read from
18
* those pipes. A separate thread is created to manage reading the
19
* output of OpenAxiom and sending it (appropriatedly modified) to
20
* TeXmacs. The main thread reads from TeXmacs and sends it's
21
* output to OpenAxiom. In this way the input and output is completely
22
* asynchronous. There may be some advantage to the use of such
23
* "light weight" threads in Windows.
24
*
25
* Build with the command:
26
* gcc tm_openaxiom.c texbreaker.c -o tm_openaxiom.exe
27
* It is known to compile with gcc version 3.4.2 (mingw-special)
28
* under MinGW/MSYS. Other compilers may also work.
29
*
30
* Install the tm_openaxiom.exe file in the directory
31
* C:\Program Files\WinTeXmacs\TeXmacs\bin
32
*
33
* Written by Bill Page 20041203
34
* - based on Maxima test version by Mike Thomas 20030624
35
* (Thankyou Mike!)
36
* and on the TeXmacs tm_openaxiom.c program (linux)
37
* Modified by Bill Page 20041215
38
* - add call to Robert Sutor line-break routine
39
* Modified by Bill Page 20041217
40
* - initialize OPENAXIOM_exe from OPENAXIOM environment variable
41
* Modified by Bill Page 20041220
42
* - use args, TM_OPENAXIOM environment variable and/or
43
* )set output texmacs option,option, ...
44
* to specify options
45
* break no -- disables line-break algorithm
46
* over no -- converts 2-d \over to 1-d /
47
* cdot no -- converts \cdot to \ (space)
48
* space no -- convert \ (space) to \,
49
* big( no -- convert \left( \right to ( )
50
* width 4.5 -- 4.5 inches * 1000
51
* - process OpenAxiom output with no LaTeX content, e.g.
52
* )set output tex off
53
* )set output algebra on
54
* */
55
56
#include <windows.h>
57
#include <process.h>
58
#include <memory.h>
59
#include <string.h>
60
#include <stdio.h>
61
#include <fcntl.h>
62
#include <io.h>
63
64
/* Allow some debugging output from the IO threads */
65
/*#define DEBUG_OUT*/
66
67
int option_texbreak = 1, /* default options */
68
option_use_over = 1,
69
option_use_cdot = 1,
70
option_big_space = 0,
71
option_big_paren = 1;
72
73
#define INP_BUFF_SIZE 3072
74
#define OUT_BUFF_SIZE 8192
75
char szBuffer[OUT_BUFF_SIZE];
76
#define MATHBUFLEN 8*8192
77
extern int maxLineWidth;
78
extern char bufout[2*MATHBUFLEN];
79
80
int nBuffer=0;
81
int nRead;
82
int IgnorePrompts=0;
83
84
#define READ_HANDLE 0
85
#define WRITE_HANDLE 1
86
87
char OPENAXIOM_cmd[256];
88
char ENV_OPENAXIOM[256];
89
90
int fdStdOutPipe[2], fdStdInPipe[2], fdStdErrPipe[2];
91
92
HANDLE hProcess;
93
STARTUPINFO si; /* Only need to set si.cb */
94
PROCESS_INFORMATION pi; /* Post launch child process information. */
95
96
/* consult the environment */
97
98
void parse_options(int nargs, char *args[]) {
99
char *pOPENAXIOM, *pTM_OPENAXIOM, *pOption;
100
int i;
101
float w;
102
103
if (pOPENAXIOM=getenv("OPENAXIOM")) {
104
strcpy(OPENAXIOM_cmd,pOPENAXIOM); strcat(OPENAXIOM_cmd, "/../../../../bin/open-axiom.exe");
105
strcat(OPENAXIOM_cmd," --system=\""); strcat(OPENAXIOM_cmd,pOPENAXIOM);
106
strcat(OPENAXIOM_cmd,"\"");
107
strcpy(ENV_OPENAXIOM,"OPENAXIOM="); strcat(ENV_OPENAXIOM, pOPENAXIOM);
108
}
109
else {
110
printf("You must set the OPENAXIOM environment variable, e.g.\n");
111
exit(1);
112
}
113
114
/* e.g. TM_OPENAXIOM='break off, over yes, ...
115
* if not found or different options, ignore silently */
116
for (i=0;i<nargs;i++) {
117
pTM_OPENAXIOM=args[i]; /* args override environment */
118
if (i>0 || (pTM_OPENAXIOM=getenv("TM_OPENAXIOM"))) {
119
if (strstr(pTM_OPENAXIOM,"break off")
120
|| strstr(pTM_OPENAXIOM,"break n")
121
|| strstr(pTM_OPENAXIOM,"break 0"))
122
option_texbreak=0;
123
if (strstr(pTM_OPENAXIOM,"break on")
124
|| strstr(pTM_OPENAXIOM,"break y")
125
|| strstr(pTM_OPENAXIOM,"break 1"))
126
option_texbreak=1;
127
if (strstr(pTM_OPENAXIOM,"over off")
128
|| strstr(pTM_OPENAXIOM,"over n")
129
|| strstr(pTM_OPENAXIOM,"over 0"))
130
option_use_over=0;
131
if (strstr(pTM_OPENAXIOM,"over on")
132
|| strstr(pTM_OPENAXIOM,"over y")
133
|| strstr(pTM_OPENAXIOM,"over 1"))
134
option_use_over=1;
135
if (strstr(pTM_OPENAXIOM,"cdot off")
136
|| strstr(pTM_OPENAXIOM,"cdot n")
137
|| strstr(pTM_OPENAXIOM,"cdot 0"))
138
option_use_cdot=0;
139
if (strstr(pTM_OPENAXIOM,"cdot on")
140
|| strstr(pTM_OPENAXIOM,"cdot y")
141
|| strstr(pTM_OPENAXIOM,"cdot 1"))
142
option_use_cdot=1;
143
if (strstr(pTM_OPENAXIOM,"space off")
144
|| strstr(pTM_OPENAXIOM,"space n")
145
|| strstr(pTM_OPENAXIOM,"space 0"))
146
option_big_space=0;
147
if (strstr(pTM_OPENAXIOM,"space on")
148
|| strstr(pTM_OPENAXIOM,"space y")
149
|| strstr(pTM_OPENAXIOM,"space 1"))
150
option_big_space=1;
151
if (strstr(pTM_OPENAXIOM,"big( off")
152
|| strstr(pTM_OPENAXIOM,"big( n")
153
|| strstr(pTM_OPENAXIOM,"big( 0"))
154
option_big_paren=0;
155
if (strstr(pTM_OPENAXIOM,"big( on")
156
|| strstr(pTM_OPENAXIOM,"big( y")
157
|| strstr(pTM_OPENAXIOM,"big( 1"))
158
option_big_paren=1;
159
if (pOption=strstr(pTM_OPENAXIOM,"width ")) {
160
sscanf(pOption+strlen("width "),"%f",&w);
161
maxLineWidth=trunc(1000.0*w);
162
};
163
};
164
};
165
}
166
167
/* This is the OpenAxiom Reader thread. It runs asynchronously and
168
* in parallel with the main thread. It reads output from OpenAxiom
169
* and after some selection and conversion, it is sent on to
170
* TeXmacs. */
171
172
unsigned __stdcall StdOutReadThread ( void* pArguments )
173
{
174
int nExitCode = STILL_ACTIVE;
175
176
fputs("\2verbatim:",stdout); /* ---> to TeXmacs */
177
178
GetExitCodeProcess ( hProcess, (unsigned long*) &nExitCode );
179
180
while ( nExitCode == STILL_ACTIVE ) {
181
#ifdef DEBUG_OUT
182
fprintf ( stderr, " - Stdout read loop\n" );
183
fflush ( stderr );
184
#endif /* DEBUG_OUT */
185
nRead = _read ( fdStdOutPipe[READ_HANDLE], &szBuffer[nBuffer],
186
OUT_BUFF_SIZE-nBuffer ); /* Read <--- from OpenAxiom */
187
188
szBuffer[nBuffer+nRead]='\0';
189
#ifdef DEBUG_OUT
190
fprintf ( stderr, "After _read on stdoutpipe (%d bytes read)\n%s\n",
191
nRead, &szBuffer[nBuffer] ); fflush ( stderr );
192
#endif /* DEBUG_OUT */
193
while (nRead>0) { /* fill buffer until we see OpenAxiom prompt */
194
if ( strncmp(&szBuffer[nBuffer],"-> ",3)==0 ) { /* done */
195
HandleOutput(szBuffer, nBuffer); /* send output ---> to TeXmacs */
196
nRead = nRead-3; /* keep the left overs */
197
if (nRead>0) strncpy(szBuffer,&szBuffer[nBuffer+3],nRead);
198
nBuffer = 0; szBuffer[nRead]='\0';
199
#ifdef DEBUG_OUT
200
fprintf(stderr, "Leftovers\n%s\n",&szBuffer);
201
fflush(stderr);
202
#endif /* DEBUG_OUT */
203
} else {
204
nBuffer++;
205
nRead--;
206
};
207
};
208
GetExitCodeProcess ( hProcess, (unsigned long*) &nExitCode );
209
};
210
211
fputs("\2latex:\\red The end\\black\5\5",stdout); /* The ends --> TeXmacs */
212
fflush(stdout);
213
_endthreadex(0);
214
}
215
216
/* This routine parses all OpenAxiom output between -> prompts */
217
218
HandleOutput(char Buffer[], int n) /* sends output ---> to TeXmacs */
219
{
220
int mmode, i, j;
221
222
#ifdef DEBUG_OUT
223
fprintf(stderr, "HandleOutput IgnorePrompts:%d\n%s\n",IgnorePrompts,
224
Buffer);
225
fflush(stderr);
226
#endif /* DEBUG_OUT */
227
if (IgnorePrompts) --IgnorePrompts; /* counting down */
228
else { /* its a good packet */
229
while (n>0 && Buffer[n-1]=='\n') n--;
230
Buffer[n]='\0'; /* mark the real end */
231
mmode = 0; j=0;
232
while (Buffer[j]=='\n') j++; /* find the real start */
233
for (i=j;i<n;i++) {
234
if (strncmp(&Buffer[i],"$$\n",3)==0) { /* Found a LaTeX marker */
235
#ifdef DEBUG_OUT
236
fprintf(stderr, "LaTeX marker at: %d, mode: %d\n",i,mmode);
237
fflush(stderr);
238
#endif /* DEBUG_OUT */
239
Buffer[i]='\0'; /* something ends here */
240
if (mmode<=0) { /* we were not in mathmode */
241
fputs(&Buffer[j],stdout); /* send the plain text ---> to TeXmacs */
242
mmode = i+3; /* start of LaTeX */
243
fputs("\2latex:$$",stdout);/* tell ---> TeXmacs */
244
} else { /* we were in mathmode */
245
HandleLatex(&Buffer[mmode]); /* make some adjustments */
246
fputs("$$\5",stdout); /* Say "that's all" ---> to TeXmacs */
247
mmode = -1; j=i+3; /* aftermath */
248
}
249
} else { /* this is not a marker */
250
if (mmode<=0) { /* if not in mathmode */
251
if (strncmp(&Buffer[i],"Type:",5)==0) { /* look for OpenAxiom Type */
252
int k;
253
k=i-1; while (Buffer[k]==' ') k--;
254
Buffer[k]='\0'; /* mark end of previous */
255
fputs(&Buffer[j],stdout); /* send the plain text -> to TeXmacs */
256
fprintf(stdout,"\2latex:\\openaxiomtype{%s}\5",
257
&Buffer[i+6]);
258
i=n; j=n; /* and we are done */
259
}
260
}
261
}
262
};
263
if (j<n) {
264
fputs(&Buffer[j],stdout); /* send the plain text ---> to TeXmacs */
265
};
266
/* ask for some more work from ---> TeXmacs */
267
fputs("\2channel:prompt\5\2latex:\\red$\\rightarrow$\\ \5\5",stdout);
268
fflush(stdout); /* Say "give me a prompt" ---> to TeXmacs */
269
fputs("\2verbatim:",stdout); /* maybe plain text next ---> to TeXmacs */
270
}
271
}
272
273
HandleLatex(char buf[]) { /* fixup Latex coding */
274
275
char *ptr1, *ptr2, *ptr3;
276
char label[64];
277
278
/* /n -> blank */
279
while (ptr1=strchr(buf,'\n')) { *ptr1=' '; };
280
281
if (option_texbreak) { /* break long TeX lines */
282
283
/* prepare OpenAxiom output in buf for call to texbreak */
284
285
/* remove the label and save it for later */
286
label[0]='\0';
287
while (ptr1=strstr(buf,"\\leqno(")) {
288
if ((ptr2=strchr(ptr1,')')) && (ptr2-ptr1<64)) {
289
ptr2++;
290
strncpy(label,ptr1,ptr2-ptr1); label[ptr2-ptr1]='\0';
291
strcpy(ptr1,ptr2);
292
}
293
};
294
295
texbreak(buf); /* output is in global external called bufout */
296
strcat(bufout,"\\hfill \\leqno ");
297
strcat(bufout,&label[6]); /* put label back */
298
} else {
299
strcpy(bufout,buf);
300
};
301
302
/* do some LaTex conversions for TeXmacs */
303
304
/* \root { a } \of { b } ---> \sqrt[ a ] { b } */
305
/* ptr1^ ptr2^ ^ptr3 ^ ^ ptr1^ ^ */
306
307
while (ptr1=strstr(bufout,"\\root")) {
308
ptr2=ptr1+5; while (*ptr2==' ') ptr2++;
309
if ((*ptr2=='{') && (ptr3=strstr(ptr2,"}"))) {
310
#ifdef DEBUG_OUT
311
fprintf(stderr, "ptr1: %s\nptr2: %s\nptr3: %s\n",ptr1,ptr2,ptr3);
312
fflush(stderr);
313
#endif /* DEBUG_OUT */
314
strncpy(ptr1,"\\sqrt[",6); ptr1=ptr1+6;
315
strncpy(ptr1,ptr2+1,ptr3-ptr2-1); ptr1=ptr1+(ptr3-ptr2-1);
316
strncpy(ptr1,"]",1); ptr1++;
317
ptr3++; while (*ptr3==' ') ptr3++;
318
#ifdef DEBUG_OUT
319
fprintf(stderr, "ptr1: %s\nptr2: %s\nptr3: %s\n",ptr1,ptr2,ptr3);
320
fflush(stderr);
321
#endif /* DEBUG_OUT */
322
if (strncmp(ptr3,"\\of",3)==0) {
323
ptr3+=3; while (*ptr3==' ') ptr3++;
324
if (*ptr3=='{') {
325
strcpy(ptr1,ptr3);
326
} else {
327
error("No \\of { \n");
328
}
329
} else {
330
error("No \\of \n");
331
}
332
} else {
333
error("No \\root { } \n");
334
}
335
};
336
337
if (!option_big_space) { /* use smaller spaces \ ---> \, */
338
while (ptr1=strstr(bufout,"\\ ")) {
339
strncpy(ptr1,"\\,",2); /* use thin spaces */
340
};
341
};
342
343
/* other possible conversions */
344
345
if (!option_use_cdot) {
346
while (ptr1=strstr(bufout,"\\cdot")) {
347
strncpy(ptr1,"\\ ",2);
348
strcpy(ptr1+2,ptr1+5);
349
};
350
};
351
352
if (!option_big_paren) {
353
while (ptr1=strstr(bufout,"\\left(")) {
354
strncpy(ptr1,"(",1);
355
strcpy(ptr1+1,ptr1+6);
356
};
357
while (ptr1=strstr(bufout,"\\right)")) {
358
strncpy(ptr1,")",1);
359
strcpy(ptr1+1,ptr1+7);
360
};
361
};
362
if (!option_use_over) {
363
while (ptr1=strstr(bufout,"\\over")) {
364
strncpy(ptr1,"/",1);
365
strcpy(ptr1+1,ptr1+5);
366
};
367
};
368
#ifdef DEBUG_OUT
369
fprintf(stderr, "HandleLatex:\n%s\n",bufout);
370
fflush(stderr);
371
#endif /* DEBUG_OUT */
372
fputs(bufout,stdout); /* send the LaTeX code ---> to TeXmacs */
373
}
374
375
unsigned __stdcall StdErrReadThread ( void* pArguments )
376
{
377
int nExitCode = STILL_ACTIVE;
378
int nRead;
379
char szBuffer[OUT_BUFF_SIZE];
380
381
GetExitCodeProcess ( hProcess, (unsigned long*) &nExitCode );
382
383
while ( nExitCode == STILL_ACTIVE ) {
384
#ifdef DEBUG_OUT
385
fprintf ( stderr, " - Stderr read loop\n" ); fflush ( stderr );
386
#endif /* DEBUG_OUT */
387
nRead = _read ( fdStdErrPipe[READ_HANDLE], szBuffer, OUT_BUFF_SIZE );
388
#ifdef DEBUG_OUT
389
fprintf ( stderr, "After _read on stderrpipe (%d bytes read)\n",
390
nRead );
391
fflush ( stderr );
392
#endif /* DEBUG_OUT */
393
if ( nRead ) { /* just pass the message on through to TeXmacs */
394
fwrite(szBuffer, 1, nRead, stderr);
395
}
396
GetExitCodeProcess ( hProcess, (unsigned long*) &nExitCode );
397
}
398
_endthreadex(0);
399
}
400
401
void pipe_write(int fdPipe, char Buffer[])
402
{
403
_write(fdPipe, Buffer, strlen(Buffer) );
404
}
405
406
/* process texmacs options */
407
408
process_options(char line[]) {
409
char *optargs[2];
410
411
optargs[1]=line;
412
if (*(optargs[1])!='\n') {
413
parse_options(2,optargs);
414
} else { /* display current options */
415
show_options();
416
};
417
/* ask for some more work from ---> TeXmacs */
418
fputs("\2channel:prompt\5\2latex:\\red$\\rightarrow$\\ \5\5",stdout);
419
fflush(stdout); /* Say "give me a prompt" ---> to TeXmacs */
420
fputs("\2verbatim:",stdout); /* maybe plain text next ---> to TeXmacs */
421
422
#ifdef DEBUG_OUT
423
fprintf ( stderr,
424
"TM_OPENAXIOM=texbreak:%d,use_over:%d,use_cdot:%d,big_space:%d,big_paren:%d,\n",
425
option_texbreak, option_use_over, option_use_cdot,
426
option_big_space, option_big_paren );
427
fprintf ( stderr,
428
" maxLineWidth:%d\n", maxLineWidth );
429
fflush ( stderr );
430
#endif /* DEBUG_OUT */
431
}
432
433
show_options() {
434
fprintf(stdout,
435
"--------------------------- The texmacs Option ----------------------------\n\
436
\n\
437
Description: options for display of OPENAXIOM output in TeXmacs\n\
438
\n\
439
)set output texmacs is used to control the TeXmacs-OPENAXIOM interface\n\
440
The default values are controlled by environment variable TM_OPENAXIOM\n\
441
and may be overriden by command line options.\n\
442
\n\
443
Syntax: )set output texmacs <arg>\n\
444
where arg can be one or more of\n\
445
break <on>|<off> line-break algorithm\n\
446
over <on>|<off> convert 2-d \\over to 1-d /\n\
447
cdot <on>|<off> convert \\cdot to \\ (space)\n\
448
space <on>|<off> convert \\ (space) to \\,\n\
449
big( <on>|<off> convert \\left( \\right to ( )\n\
450
width <9.99> line width in inches\n\
451
\n\
452
<on> may be on, yes, 1\n\
453
<off> may be off, no , 0\n\
454
\n\
455
The current settings are:\n\
456
break %d, over %d, cdot %d, space %d, big( %d, width %2.3f\n",
457
option_texbreak, option_use_over, option_use_cdot,
458
option_big_space, option_big_paren, maxLineWidth/1000.0 );
459
460
};
461
462
int main(int nargs, char *args[])
463
{
464
HANDLE hStdOutReadThread;
465
int fdStdOut, fdStdIn;
466
unsigned threadIDOut;
467
HANDLE hStdErrReadThread;
468
int fdStdErr;
469
unsigned threadIDErr;
470
int i;
471
char line[INP_BUFF_SIZE];
472
473
parse_options(nargs,args);
474
475
#ifdef DEBUG_OUT
476
fprintf ( stderr, "CREATE PROCESS: %s\n", OPENAXIOM_cmd );
477
fprintf ( stderr, "Setting env var: %s\n", ENV_OPENAXIOM );
478
fprintf ( stderr,
479
"TM_OPENAXIOM=texbreak:%d,use_over:%d,use_cdot:%d,big_space:%d,big_paren:%d,\n",
480
option_texbreak, option_use_over, option_use_cdot,
481
option_big_space, option_big_paren );
482
fprintf ( stderr,
483
" maxLineWidth:%d\n", maxLineWidth );
484
fflush ( stderr );
485
#endif /* DEBUG_OUT */
486
487
if ( -1 == _setmode( _fileno( stdin ), _O_BINARY ) ) {
488
perror ( "machinfo: Cannot set stdin BINARY mode" ); exit(1);
489
};
490
if ( -1 == _setmode( _fileno( stdout ), _O_BINARY ) ) {
491
perror ( "machinfo: Cannot set stdout BINARY mode" ); exit(1);
492
};
493
if ( -1 == _setmode( _fileno( stderr ), _O_BINARY ) ) {
494
perror ( "machinfo: Cannot set stderr BINARY mode" ); exit(1);
495
};
496
497
/* Make pipes to be passed to the spawned process as stdin/out/err */
498
if ( _pipe ( fdStdOutPipe, 512, O_BINARY | O_NOINHERIT ) == -1 ) return 1;
499
if ( _pipe ( fdStdInPipe, 512, O_BINARY | O_NOINHERIT ) == -1 ) return 1;
500
if ( _pipe ( fdStdErrPipe, 512, O_BINARY | O_NOINHERIT ) == -1 ) return 1;
501
502
/* Duplicate and save original stdin/out/err handles */
503
fdStdOut = _dup ( _fileno(stdout) );
504
fdStdIn = _dup ( _fileno(stdin) );
505
fdStdErr = _dup ( _fileno(stderr) );
506
507
/* Duplicate write end of new pipes to current stdout/err handles,
508
* read to stdin */
509
if ( _dup2 ( fdStdOutPipe[WRITE_HANDLE], _fileno(stdout) ) != 0 ) return 2;
510
if ( _dup2 ( fdStdInPipe[READ_HANDLE], _fileno(stdin) ) != 0 ) return 2;
511
if ( _dup2 ( fdStdErrPipe[WRITE_HANDLE], _fileno(stderr) ) != 0 ) return 2;
512
/* Close the duplicated handles to the new pipes */
513
close ( fdStdOutPipe[WRITE_HANDLE] );
514
close ( fdStdInPipe[READ_HANDLE] );
515
close ( fdStdErrPipe[WRITE_HANDLE] );
516
517
putenv ( ENV_OPENAXIOM );
518
519
/* Zero startup and process info structures, take care of Windows
520
* startup info structure future proofing. */
521
ZeroMemory( &si, sizeof(si) );
522
si.cb = sizeof(si);
523
ZeroMemory( &pi, sizeof(pi) );
524
525
/* Start the child process. */
526
if ( !CreateProcess(
527
NULL, /* No module name (use command line). */
528
OPENAXIOM_cmd, /* Command line. */
529
NULL, /* Process handle not inheritable. */
530
NULL, /* Thread handle not inheritable. */
531
TRUE, /* Allow handle inheritance. */
532
0, /* No creation flags. */
533
NULL, /* Use parent's environment block. */
534
NULL, /* Use parent's starting directory. */
535
&si, /* Pointer to STARTUPINFO structure.*/
536
&pi ) /* Pointer to PROCESS_INFORMATION structure. */ ) {
537
fprintf(stderr, "CreateProcess failed: %s\n", args[1]);
538
fflush(stderr);
539
return -1;
540
}
541
hProcess = pi.hProcess;
542
543
/* Now that the process is launched,
544
* replace the original stdin/out/err handles */
545
if ( _dup2 ( fdStdOut, _fileno ( stdout ) ) != 0 ) return 3;
546
if ( _dup2 ( fdStdIn, _fileno ( stdin ) ) != 0 ) return 3;
547
if ( _dup2 ( fdStdErr, _fileno ( stderr ) ) != 0 ) return 3;
548
549
/* Close duplicates */
550
close(fdStdOut);
551
close(fdStdIn);
552
close(fdStdErr);
553
554
/* The child process will become the OpenAxiom read filter and
555
* we will be the OpenAxiom write filter. */
556
557
/* Create the OpenAxiom stderr listening thread. (Doesn't do much.) */
558
hStdErrReadThread = (HANDLE)_beginthreadex( NULL, 0, &StdErrReadThread,
559
NULL, 0, &threadIDErr );
560
if ( 0 == hStdErrReadThread ) return 5;
561
562
/* * * * * * * * * */
563
/* start talking! */
564
/* * * * * * * * * */
565
566
IgnorePrompts = 5; /* Tell the OpenAxiom Reader to ignore first 5 prompts */
567
/* then create the OpenAxiom stdout Reader thread.*/
568
hStdOutReadThread = (HANDLE)_beginthreadex( NULL, 0, &StdOutReadThread,
569
NULL, 0, &threadIDOut );
570
if ( 0 == hStdOutReadThread ) return 5;
571
/* start force-feeding ---> to OpenAxiom */
572
pipe_write(fdStdInPipe[WRITE_HANDLE],")set message prompt plain\n" ); /* 1 */
573
pipe_write(fdStdInPipe[WRITE_HANDLE],")set messages autoload off\n" );/* 2 */
574
pipe_write(fdStdInPipe[WRITE_HANDLE],")set quit unprotected\n" ); /* 3 */
575
pipe_write(fdStdInPipe[WRITE_HANDLE],")set output tex on\n" ); /* 4 */
576
pipe_write(fdStdInPipe[WRITE_HANDLE],")set output algebra off\n" ); /* 5 */
577
while (fgets(line,INP_BUFF_SIZE,stdin)!=NULL) { /* wait <--- for TeXmacs */
578
#ifdef DEBUG_OUT
579
fprintf ( stderr, "Input:\n%s", line );
580
#endif /* DEBUG_OUT */
581
if (strncmp(line,")set output texmacs",
582
strlen(")set output texmacs"))==0) { /* process texmacs options */
583
process_options(&line[strlen(")set output texmacs")]);
584
} else {
585
pipe_write(fdStdInPipe[WRITE_HANDLE], line ); /* Start ---> OpenAxiom */
586
}
587
};
588
if (nBuffer) HandleOutput(szBuffer,nBuffer); /* anything leftover? */
589
pipe_write(fdStdInPipe[WRITE_HANDLE], ")quit\n" ); /* stop work */
590
591
WaitForSingleObject ( hStdErrReadThread, INFINITE );
592
WaitForSingleObject ( hStdOutReadThread, INFINITE );
593
594
/* Wait until child process exits to block the terminal. */
595
WaitForSingleObject( pi.hProcess, INFINITE );
596
597
/* As we are using gebinthreadex/endthreadex,
598
* we must close the thread handles. */
599
CloseHandle ( hStdOutReadThread );
600
CloseHandle ( hStdErrReadThread );
601
602
return 0;
603
}
604
605