1 /* ---------------------------------------------------------------------
2 $Id: redparent.c 3642 2016-05-02 21:54:38Z arthurcnorman $
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 debug;
40 extern int verbose;
41 extern int unicode;
42
43 extern int redfrontcolor;
44 extern int normalcolor;
45 extern int promptcolor;
46 extern int inputcolor;
47 extern int outputcolor;
48 extern int debugcolor;
49
50 void parent(void);
51 void atoploop(void);
52 char *load_package(const char *);
53 void read_until_first_prompt(char *);
54 char *read_valid_line(char *);
55 int is_too_long(const char *);
56 int badline(const char *);
57 char *append_line(char *,char *);
58 void send_reduce(char *);
59 void read_until_prompt(char *);
60
61 #include <fcntl.h>
62
parent(void)63 void parent(void) {
64 sig_installHandlers();
65
66 #ifdef HAVE_SETLINEBUF
67 setlinebuf(stdout);
68 #endif
69
70 redclose(MeToReduce[0]);
71 redclose(ReduceToMe[1]);
72
73 deb_fprintf(stderr,"child: MeToReduce[1]= %d, ReduceToMe[0] = %d\n",
74 MeToReduce[1], ReduceToMe[0]);
75
76 atoploop();
77 }
78
atoploop(void)79 void atoploop(void) {
80 char der_prompt[50],old_prompt[50];
81 char *line = (char *)NULL;
82 char *this_command = (char *)NULL;
83
84 load_package(unicode ? "redfront,utf8": "redfront");
85
86 read_until_first_prompt(der_prompt);
87
88 deb_fprintf(stderr,"parent: read first prompt\n");
89
90 line_learn_completion(der_prompt);
91
92 while (1) {
93
94 signal(SIGINT,SIG_IGN);
95
96 line = read_valid_line(der_prompt);
97
98 signal(SIGINT,sig_sigInt);
99
100 this_command = append_line(this_command,line);
101
102 send_reduce(line);
103
104 strcpy(old_prompt,der_prompt);
105
106 read_until_prompt(der_prompt);
107
108 if (strcmp(old_prompt,der_prompt) != 0) {
109 line_add_history(this_command);
110 this_command = NULL;
111 }
112 }
113 }
114
load_package(const char * package)115 char *load_package(const char *package) {
116 char *cmd;
117 int len;
118
119 len = strlen(package)+strlen("load_package $");
120 cmd = (char *)malloc(len + 1);
121 sprintf(cmd,"load_package %s$",package);
122 send_reduce(cmd);
123
124 deb_fprintf(stderr,"parent: sending %s\n",cmd);
125
126 return cmd;
127 }
128
read_until_first_prompt(char der_prompt[])129 void read_until_first_prompt(char der_prompt[]) {
130 int status=READING_OUTPUT;
131 char buffer[1000];
132 int ncharread;
133 int ii;
134 int pii=0;
135 char ch;
136 struct strbuf *b=(struct strbuf *)0,*t=(struct strbuf *)0;
137
138 textcolor(normalcolor);
139
140 while(status != FINISHED) {
141 ncharread = redread(ReduceToMe[0],buffer,1000);
142 for (ii=0; ii < ncharread; ii++) {
143 ch = buffer[ii];
144 if (ch == (char) 0x01 ) {
145 status = READING_PROMPT;
146 pii = 0;
147 } else if (ch == (char) 0x02) {
148 status = FINISHED;
149 }
150 if (status == READING_OUTPUT) {
151 b = addchar(ch,b);
152 } else if (status == READING_PROMPT) {
153 if ((int) ch > 31) {
154 der_prompt[pii++] = ch;
155 t = addchar(ch,t);
156 }
157 } else { /* (status == FINISHED) */
158 der_prompt[pii] = 0x00;
159 }
160 }
161 }
162 b = remtail(t,b);
163 prtbuf(b);
164 fflush(stdout);
165 }
166
read_valid_line(char der_prompt[])167 char *read_valid_line(char der_prompt[]) {
168 char orig_prompt[50];
169 char *line;
170
171 strcpy(orig_prompt,der_prompt);
172
173 der_prompt = line_color_prompt(der_prompt);
174
175 line = line_read(der_prompt);
176
177 if (line)
178 while (is_too_long(line)) {
179 line = line_read(der_prompt);
180 }
181 else {
182 if (strcmp(orig_prompt,"?") == 0) {
183 line = line_quit("n");
184 } else if (orig_prompt[strlen(orig_prompt) - 2] == '%') {
185 line = line_quit("(exit)");
186 } else if (orig_prompt[strlen(orig_prompt) - 2] == '>') {
187 line = line_quit("q");
188 } else if (orig_prompt[strlen(orig_prompt) - 2] == ':') {
189 line = line_quit("quit;");
190 } else if (orig_prompt[strlen(orig_prompt) - 2] == '*') {
191 line = line_quit("quit;");
192 } else {
193 line = line_quit("");
194 }
195 }
196
197 strcpy(der_prompt,orig_prompt);
198
199 return line;
200 }
201
is_too_long(const char line[])202 int is_too_long(const char line[]) {
203 #if PSL
204 if (badline(line)) {
205 textcolor(redfrontcolor);
206 printf("redfront: overlong input line\n");
207 textcolor(inputcolor);
208 return 1;
209 }
210 #endif
211 return 0;
212 }
213
badline(const char line[])214 int badline(const char line[]) {
215 int i=0,n=0;
216
217 while (n <= SYSMAXBUFFER && line[i]) {
218 if (line[i] == 0x0a)
219 n = 0;
220 i++;
221 n++;
222 }
223 return (n > SYSMAXBUFFER);
224 }
225
226
append_line(char * c,char * l)227 char *append_line(char *c,char *l) {
228 char *s;
229 int lenc,lenl;
230
231 deb_fprintf(stderr,"parent: entering append_line() ... c=%s, l=%s\n",
232 (c != (char *)NULL) ? c : "NULL",(l != (char *)NULL) ? l : "NULL");
233
234 lenc = (c != (char *)NULL) ? strlen(c) : 0;
235 lenl = (l != (char *)NULL) ? strlen(l) : 0;
236
237 s = malloc((lenc + lenl + 2) * sizeof(char)); /* 2 >= [ |\x0a| ] + |\0| */
238 *s = 0;
239 if (c != (char *)NULL) {
240 strcpy(s,c);
241 if (lenc != 0 && lenl != 0) strcat(s,"\x0a");
242 }
243
244 if (l != (char *)NULL)
245 strcat(s,l);
246
247 deb_fprintf(stderr,"parent: s=%s ... leaving append_line()\n",s);
248
249 return s;
250 }
251
send_reduce(char line[])252 void send_reduce(char line[]) {
253 char dummy_prompt[50];
254 char ch;
255 int ii;
256 ssize_t ret;
257
258 deb_fprintf(stderr,"parent: entering send_reduce() ... line=%s\n",line);
259
260 if (line == (char *)NULL) {
261 ch=0x04;
262 ret = redwrite(MeToReduce[1],&ch,1);
263 ch = 0x0a;
264 ret = redwrite(MeToReduce[1],&ch,1);
265 } else {
266 for (ii=0; line[ii] != 0; ii++) {
267 ch = line[ii] & 0x7f;
268 ret = redwrite(MeToReduce[1],&ch,1);
269 if (ch == 0x0a) {
270 strcpy(dummy_prompt,"dummy_prompt");
271 read_until_prompt(dummy_prompt);
272 }
273 }
274 ch = 0x0a;
275 ret = redwrite(MeToReduce[1],&ch,1);
276 }
277
278 deb_fprintf(stderr,"parent: ... leaving send_reduce()\n");
279 }
280
read_until_prompt(char der_prompt[])281 void read_until_prompt(char der_prompt[]){
282 int status=READING_OUTPUT;
283 char buffer[1000];
284 int ncharread;
285 int ii;
286 int pii=0;
287 char ch;
288
289 deb_fprintf(stderr,"parent: entering read_until_prompt() ... der_prompt=%s\n",
290 der_prompt);
291
292 textcolor(normalcolor);
293
294 while(status != FINISHED) {
295 ncharread = redread(ReduceToMe[0],buffer,1000);
296 if (ncharread < 0) {
297 perror("read_until_prompt");
298 rf_exit(-1);
299 }
300 if (ncharread == 0) {
301 #ifndef NATIVE_WINDOWS
302 /* There is a SIGCHLD in the air, but I already know that it is over. */
303 signal(SIGCHLD, SIG_IGN);
304 #endif
305 line_end_history();
306 line_end();
307 if (verbose) {
308 textcolor(redfrontcolor);
309 printf("Redfront normally exiting on EOF from Reduce.\n");
310 }
311 rf_exit(0);
312 }
313 for (ii=0; ii < ncharread; ii++) {
314 ch = buffer[ii];
315 if (ch == (char) 0x01) {
316 status = READING_PROMPT;
317 pii = 0;
318 } else if (ch == (char) 0x02) {
319 status = FINISHED;
320 }
321 if (status == READING_OUTPUT) {
322 if (ch == (char) 0x03 ) {
323 textcolor(outputcolor);
324 }
325 else if (ch == (char) 0x04 ) {
326 textcolor(normalcolor);
327 }
328 else {
329 printf("%c",ch);
330 }
331 } else if (status == READING_PROMPT) {
332 if ((int) ch > 31)
333 der_prompt[pii++] = ch;
334 } else { /* (status == FINISHED) */
335 der_prompt[pii] = 0x00;
336 }
337 }
338 fflush(stdout);
339 }
340
341 deb_fprintf(stderr,"parent: ... leaving read_until_prompt()\n");
342 }
343
344 /* end of redparent.c */
345