1 /* ---------------------------------------------------------------------
2 $Id: redparent.c 3050 2015-03-26 15:26:28Z thomas-sturm $
3 ---------------------------------------------------------------------
4 (c) 1999-2009 A. Dolzmann and T. Sturm, 1999-2014 T. Sturm
5 ---------------------------------------------------------------------
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 * Redistributions of source code must retain the relevant
11 copyright notice, this list of conditions and the following
12 disclaimer.
13 * Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following
15 disclaimer in the documentation and/or other materials provided
16 with the distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "redfront.h"
32
33 #define SYSMAXBUFFER 198
34
35 #define READING_OUTPUT 1
36 #define READING_PROMPT 2
37 #define FINISHED 0
38
39 extern int dist;
40 extern int MeToReduce[];
41 extern int ReduceToMe[];
42 extern int debug;
43 extern int verbose;
44 extern int unicode;
45
46 extern int redfrontcolor;
47 extern int normalcolor;
48 extern int promptcolor;
49 extern int inputcolor;
50 extern int outputcolor;
51 extern int debugcolor;
52
53 void parent(void);
54 void atoploop(void);
55 char *load_package(const char *);
56 void read_until_first_prompt(char *);
57 char *read_valid_line(char *);
58 int is_too_long(const char *);
59 int badline(const char *);
60 char *append_line(char *,char *);
61 void send_reduce(char *);
62 void read_until_prompt(char *);
63
64 #include <fcntl.h>
65
parent(void)66 void parent(void) {
67 sig_installHandlers();
68
69 #ifdef HAVE_SETLINEBUF
70 setlinebuf(stdout);
71 #endif
72
73 close(MeToReduce[0]);
74 close(ReduceToMe[1]);
75
76 deb_fprintf(stderr,"child: MeToReduce[1]= %d, ReduceToMe[0] = %d\n",
77 MeToReduce[1], ReduceToMe[0]);
78
79 atoploop();
80 }
81
atoploop(void)82 void atoploop(void) {
83 char der_prompt[50],old_prompt[50];
84 char *line = (char *)NULL;
85 char *this_command = (char *)NULL;
86
87 load_package(unicode ? "redfront,utf8": "redfront");
88
89 read_until_first_prompt(der_prompt);
90
91 deb_fprintf(stderr,"parent: read first prompt\n");
92
93 line_learn_completion(der_prompt);
94
95 while (1) {
96
97 // if (dist == PSL)
98 signal(SIGINT,SIG_IGN);
99
100 line = read_valid_line(der_prompt);
101
102 // if (dist == PSL)
103 signal(SIGINT,sig_sigInt);
104
105 this_command = append_line(this_command,line);
106
107 send_reduce(line);
108
109 strcpy(old_prompt,der_prompt);
110
111 read_until_prompt(der_prompt);
112
113 if (!CMDHIST || strcmp(old_prompt,der_prompt) != 0) {
114 line_add_history(this_command);
115 this_command = NULL;
116 }
117 }
118 }
119
load_package(const char * package)120 char *load_package(const char *package) {
121 char *cmd;
122 int len;
123
124 len = strlen(package)+strlen("load_package $");
125 cmd = (char *)malloc(len + 1);
126 sprintf(cmd,"load_package %s$",package);
127 send_reduce(cmd);
128
129 deb_fprintf(stderr,"parent: sending %s\n",cmd);
130
131 return cmd;
132 }
133
read_until_first_prompt(char der_prompt[])134 void read_until_first_prompt(char der_prompt[]) {
135 int status=READING_OUTPUT;
136 char buffer[1000];
137 int ncharread;
138 int ii;
139 int pii=0;
140 char ch;
141 struct strbuf *b=(struct strbuf *)0,*t=(struct strbuf *)0;
142
143 textcolor(normalcolor);
144
145 while(status != FINISHED) {
146 ncharread = read(ReduceToMe[0],buffer,1000);
147 for (ii=0; ii < ncharread; ii++) {
148 ch = buffer[ii];
149 if (ch == (char) 0x01 ) {
150 status = READING_PROMPT;
151 pii = 0;
152 } else if (ch == (char) 0x02) {
153 status = FINISHED;
154 }
155 if (status == READING_OUTPUT) {
156 b = addchar(ch,b);
157 } else if (status == READING_PROMPT) {
158 if ((int) ch > 31) {
159 der_prompt[pii++] = ch;
160 t = addchar(ch,t);
161 }
162 } else { /* (status == FINISHED) */
163 der_prompt[pii] = 0x00;
164 }
165 }
166 }
167 b = remtail(t,b);
168 prtbuf(b);
169 fflush(stdout);
170 }
171
read_valid_line(char der_prompt[])172 char *read_valid_line(char der_prompt[]) {
173 char orig_prompt[50];
174 char *line;
175
176 strcpy(orig_prompt,der_prompt);
177
178 der_prompt = line_color_prompt(der_prompt);
179
180 line = line_read(der_prompt);
181
182 if (line)
183 while (is_too_long(line)) {
184 line = line_read(der_prompt);
185 }
186 else {
187 if (strcmp(orig_prompt,"?") == 0) {
188 line = line_quit("n");
189 } else if (orig_prompt[strlen(orig_prompt) - 2] == '%') {
190 line = line_quit("(exit)");
191 } else if (orig_prompt[strlen(orig_prompt) - 2] == '>') {
192 line = line_quit("q");
193 } else if (orig_prompt[strlen(orig_prompt) - 2] == ':') {
194 line = line_quit("quit;");
195 } else if (orig_prompt[strlen(orig_prompt) - 2] == '*') {
196 line = line_quit("quit;");
197 } else {
198 line = line_quit("");
199 }
200 }
201
202 strcpy(der_prompt,orig_prompt);
203
204 return line;
205 }
206
is_too_long(const char line[])207 int is_too_long(const char line[]) {
208 if (dist == PSL && badline(line)) {
209 textcolor(redfrontcolor);
210 printf("redfront: overlong input line\n");
211 textcolor(inputcolor);
212 return 1;
213 }
214 return 0;
215 }
216
badline(const char line[])217 int badline(const char line[]) {
218 int i=0,n=0;
219
220 while (n <= SYSMAXBUFFER && line[i]) {
221 if (line[i] == 0x0a)
222 n = 0;
223 i++;
224 n++;
225 }
226 return (n > SYSMAXBUFFER);
227 }
228
229
append_line(char * c,char * l)230 char *append_line(char *c,char *l) {
231 #ifdef HAVE_HISTORY
232 char *s;
233 int lenc,lenl;
234
235 deb_fprintf(stderr,"parent: entering append_line() ... c=%s, l=%s\n",
236 (c != (char *)NULL) ? c : "NULL",(l != (char *)NULL) ? l : "NULL");
237
238 lenc = (c != (char *)NULL) ? strlen(c) : 0;
239 lenl = (l != (char *)NULL) ? strlen(l) : 0;
240
241 s = malloc((lenc + lenl + 2) * sizeof(char)); /* 2 >= [ |\x0a| ] + |\0| */
242 *s = 0;
243 if (c != (char *)NULL) {
244 strcpy(s,c);
245 if (CMDHIST && lenc != 0 && lenl != 0) {
246 if (LITHIST)
247 strcat(s,"\x0a");
248 else {
249 strcat(s," ");
250 while (l && isspace(*l))
251 l++;
252 }
253 }
254 }
255
256 if (l != (char *)NULL)
257 strcat(s,l);
258
259 deb_fprintf(stderr,"parent: s=%s ... leaving append_line()\n",s);
260
261 return s;
262 #endif
263 }
264
send_reduce(char line[])265 void send_reduce(char line[]) {
266 char dummy_prompt[50];
267 char ch;
268 int ii;
269 ssize_t ret;
270
271 deb_fprintf(stderr,"parent: entering send_reduce() ... line=%s\n",line);
272
273 if (line == (char *)NULL) {
274 ch=0x04;
275 ret = write(MeToReduce[1],&ch,1);
276 ch = 0x0a;
277 ret = write(MeToReduce[1],&ch,1);
278 } else {
279 for (ii=0; line[ii] != 0; ii++) {
280 ch = line[ii] & 0x7f;
281 ret = write(MeToReduce[1],&ch,1);
282 if (ch == 0x0a) {
283 strcpy(dummy_prompt,"dummy_prompt");
284 read_until_prompt(dummy_prompt);
285 }
286 }
287 ch = 0x0a;
288 ret = write(MeToReduce[1],&ch,1);
289 }
290
291 deb_fprintf(stderr,"parent: ... leaving send_reduce()\n");
292 }
293
read_until_prompt(char der_prompt[])294 void read_until_prompt(char der_prompt[]){
295 int status=READING_OUTPUT;
296 char buffer[1000];
297 int ncharread;
298 int ii;
299 int pii=0;
300 char ch;
301
302 deb_fprintf(stderr,"parent: entering read_until_prompt() ... der_prompt=%s\n",
303 der_prompt);
304
305 textcolor(normalcolor);
306
307 while(status != FINISHED) {
308 ncharread = read(ReduceToMe[0],buffer,1000);
309 if (ncharread < 0) {
310 perror("read_until_prompt");
311 rf_exit(-1);
312 }
313 if (ncharread == 0) {
314 /* There is a SIGCHLD in the air, but I already know that it is over. */
315 signal(SIGCHLD, SIG_IGN);
316 line_end_history();
317 line_end();
318 if (verbose) {
319 textcolor(redfrontcolor);
320 printf("Redfront normally exiting on EOF from Reduce.\n");
321 }
322 rf_exit(0);
323 }
324 for (ii=0; ii < ncharread; ii++) {
325 ch = buffer[ii];
326 if (ch == (char) 0x01) {
327 status = READING_PROMPT;
328 pii = 0;
329 } else if (ch == (char) 0x02) {
330 status = FINISHED;
331 }
332 if (status == READING_OUTPUT) {
333 if (ch == (char) 0x03 ) {
334 textcolor(outputcolor);
335 }
336 else if (ch == (char) 0x04 ) {
337 textcolor(normalcolor);
338 }
339 else {
340 printf("%c",ch);
341 }
342 } else if (status == READING_PROMPT) {
343 if ((int) ch > 31)
344 der_prompt[pii++] = ch;
345 } else { /* (status == FINISHED) */
346 der_prompt[pii] = 0x00;
347 }
348 }
349 fflush(stdout);
350 }
351
352 deb_fprintf(stderr,"parent: ... leaving read_until_prompt()\n");
353 }
354