Update the changelog
[opencv] / apps / cvenv / EiC / readline.c
1 /* GNUPLOT - readline.c */
2 /*
3  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
4  *
5  * Permission to use, copy, and distribute this software and its
6  * documentation for any purpose with or without fee is hereby granted, 
7  * provided that the above copyright notice appear in all copies and 
8  * that both that copyright notice and this permission notice appear 
9  * in supporting documentation.
10  *
11  * Permission to modify the software is granted, but not the right to
12  * distribute the modified code.  Modifications are to be distributed 
13  * as patches to released version.
14  *  
15  * This software is provided "as is" without express or implied warranty.
16  * 
17  *
18  * AUTHORS
19  *
20  *   Original Software:
21  *     Tom Tkacik
22  *
23  * HISTORY:
24  *   Enhancements:
25  *     Gershon Elber and many others.
26  *
27  *   Ed Breen (Jun 10 08:11:14 EST 1996)
28  *     Stripped down: EiC port.
29  *     Added standalone capability -- for testing and experimenting:
30  *        To make the stand alone version of readline:
31  *            gcc -D_STANDALONE -Wall -o readline readline.c
32  *     Added a limiter to the history recording mechanism:
33  *        The default limit means that only the last 500 lines 
34  *        can be recalled. This can be set via the macro _HistLimit.
35  *        Note, by setting _HistLimit to 0, effectively turns  off the
36  *        limiter; that is,
37  *          gcc -D_STANDALONE -D_HistLimit=0 -Wall -o readline readline.c
38  *     Added tab recognition -- no, not file completion.
39  *     Added show_history.
40  *            void EiC_show_history(FILE *fp)
41  *               outputs the history list to stream fp.
42  *            last_history.
43  *              returns a pointer to the last entered string in the history
44  *              list. Will return NULL if no entry exists.
45  *              Do not attempt to free this space, it is under control
46  *              of history.
47  *     Added bracket balancing routine:
48  *              void backupTo(char to, char from);
49  *     Optimized for speedy cursor movements:     
50  *     Tested under:
51  *        ultrix, solaris, dec alpha, sunos, linux, irix-5.3, irix-6.x. 
52  *   Ed Breen (July 17 1999)
53  *       Added win95, win98, NT win32 support
54  *   Ed Breen (July 16 2000)
55  *       Added DJGPP support
56  */
57
58 /* a small version of GNU's readline */
59 /* this is not the BASH or GNU EMACS version of READLINE due to Copyleft 
60         restrictions */
61 /* do not need any terminal capabilities except , */
62
63
64 /* NANO-EMACS line editing facility */
65 /* printable characters print as themselves (insert not overwrite) */
66 /* ^A moves to the beginning of the line */
67 /* ^B moves back a single character */
68 /* ^E moves to the end of the line */
69 /* ^F moves forward a single character */
70 /* ^K kills from current position to the end of line */
71 /* ^P moves back through history */
72 /* ^N moves forward through history */
73 /* ^H and DEL delete the previous character */
74 /* ^D deletes the current character, or EOF if line is empty */
75 /* ^L/^R redraw line in case it gets trashed */
76 /* ^U kills the entire line */
77 /* ^W kills last word */
78 /* LF and CR return the entire line regardless of the cursor postition */
79 /* EOF  with an empty line returns (char *)NULL */
80
81 /* all other characters are ignored */
82
83 #ifndef NO_READLINE
84
85 /*#define _POSIX_SOURCE*/
86   #include <stdio.h>
87   #include <stdlib.h>
88   #include <string.h>
89   #include <ctype.h>
90   #include <signal.h>
91   #include <time.h>
92
93 #if defined(WIN32) 
94
95 #include <conio.h>
96 #include <io.h>
97
98 # define special_getc() msdos_getch()
99 static char msdos_getch();
100
101 #else
102
103 #include <unistd.h> 
104 #include <termios.h>
105
106 #define special_getc() ansi_getc()
107 static int ansi_getc();
108
109 /* watch out for SV4 and BSD+4.3 stuff */
110 #ifndef  VREPRINT
111 #define  VREPRINT 18
112 #endif
113 #ifndef VWERASE
114 #define VWERASE 23
115 #endif
116 #ifndef SIGTSTP
117 #define SIGTSTP 26
118 #endif
119
120 #endif
121
122 #ifndef CLOCKS_PER_SEC
123 #define CLOCKS_PER_SEC 1000000
124 #endif
125
126
127 /* stubbs added by Ed Breen */
128 #define ralloc(x,y,z) realloc(x,y)
129 #define alloc(x,y)    malloc(x)
130 #define int_error(text,code)  {fprintf(stderr,"Fatal error..\n");\
131                                    fprintf(stderr,"%s\n",text);\
132                                    fprintf(stderr,"...now exiting to system ...\n");\
133                                    exit(1);}
134
135 #if !defined(WIN32)
136
137 static struct termios orig_termio, rl_termio;
138
139 /* ULTRIX defines VRPRNT instead of VREPRINT */
140 #if defined(VRPRNT) && !defined(VREPRINT)
141 #define VREPRINT VRPRNT
142 #endif
143
144 /* define characters to use with our input character handler */
145 static char term_chars[NCCS];
146
147 static int term_set = 0;        /* =1 if rl_termio set */
148
149 #endif
150
151
152 #define MAXBUF  512     /* initial size and increment of input line length */
153 #define BACKSPACE 0x08  /* ^H */
154 #define SPACE   ' '
155 #define NEWLINE '\n'
156 #define BELL    '\a'
157 #define TABSTOPS 4       /* number of spaces per tab stop */
158
159 struct hist {
160         char *line;
161         struct hist *prev;
162         struct hist *next;
163 };
164
165 static struct hist *history = NULL;      /* no history yet */
166 static struct hist *EndHist = NULL;      /* end of history list */
167 static struct hist *cur_entry = NULL;
168
169
170 static char *cur_line;  /* current contents of the line */
171 static int line_len=0;
172 static int cur_pos = 0; /* current position of the cursor */
173 static int max_pos = 0; /* maximum character position */
174 static int HistLineNo = 0;  /* Current Line Number in history list */
175
176 static void fix_line  (void)  ;
177 static void redraw_line  (char *prompt)  ;
178 static void clear_line  (char *prompt)  ;
179 static void clear_eoline  (void)  ;
180 static void copy_line  (char *line)  ;
181 static void set_termio  (void)  ;
182 static void reset_termio  (void)  ;
183 static int ansi_getc  (void)  ;
184 static void  user_putc  (char ch)  ;
185 static int user_putsn(char *str, int n)  ;
186
187 static void extend_cur_line  (void)  ;
188 static void backupTo(char to, char from);
189 static char _BS = BACKSPACE;
190
191 #if  defined(WIN32)
192 #define backspace() _putch(BACKSPACE)
193 #else
194 #define backspace()   write(STDIN_FILENO,&_BS,1)
195 #endif
196
197 #define user_puts(x)  user_putsn(x,strlen(x))
198
199
200 void delay(clock_t d)
201 {
202     clock_t et = clock() + d;
203     while(et> clock());
204 }
205
206 static void user_putc(char ch)
207 {
208 #if defined(WIN32)
209         _putch(ch);
210 #else   
211    write(STDIN_FILENO,&ch,1);
212 #endif
213
214 }
215
216 static int user_putsn(char *str, int n)
217 {
218         int rv;
219 #if defined(WIN32)
220         for(rv=0;rv<n;rv++)
221             _putch(*str++);
222 #else
223         rv = write(STDIN_FILENO,str,n);
224 #endif
225         return rv;
226 }
227
228 static void extend_cur_line()
229 {
230   char *new_line;
231
232   /* extent input line length */
233   new_line=ralloc(cur_line, line_len+MAXBUF, NULL);
234   if(!new_line) {
235     reset_termio();
236     int_error("Can't extend readline length", NO_CARET);
237   }
238   cur_line=new_line;
239   line_len+=MAXBUF;
240
241 }
242
243 unsigned char * EiC_readline(char *prompt)
244 {
245     
246     /* start with a string of MAXBUF chars */
247     char * editLine(char *);
248     if(line_len!=0) {
249                 free(cur_line);
250                 line_len=0;
251     }
252     
253     cur_line=alloc((unsigned long)MAXBUF, "readline");
254     line_len=MAXBUF;
255     
256     /* set the termio so we can do our own input processing */
257     set_termio();
258     
259     /* print the prompt */
260
261     user_puts(prompt);
262     cur_line[0] = '\0';
263     cur_pos = 0;
264     max_pos = 0;
265     cur_entry = NULL;
266     return editLine(prompt);
267 }
268
269
270 char * editLine(char *prompt)
271 {
272     /* The line to be edited is stored in cur_line.*/
273     /* get characters */
274     int cur_char;
275     
276     for(;;) {
277         cur_char = special_getc();
278         
279         if(isprint(cur_char) || (((unsigned char)cur_char > 0x7f) &&
280                                  cur_char != EOF) || cur_char == '\t') {
281             int i,inc = 1;
282             if(cur_char == '\t') {
283                 inc = TABSTOPS;
284                 cur_char = ' ';
285             }
286             
287
288             if(max_pos+inc>=line_len) 
289                 extend_cur_line();
290
291             for(i=max_pos+inc-1; i-inc>=cur_pos; i--) {
292                     cur_line[i] = cur_line[i-inc];
293                 }
294             max_pos += inc;
295             while(inc--) {
296                 user_putc(cur_char);
297                 cur_line[cur_pos++] = cur_char;
298             }
299             if (cur_pos < max_pos)
300                 fix_line();
301             cur_line[max_pos] = '\0';
302             switch(cur_char) {
303               case ')':backupTo('(',')');break;
304               case ']':backupTo('[',']');break;
305             }
306 #if defined(VERASE) 
307         } else if(cur_char == term_chars[VERASE] ){ /* DEL? */
308             if(cur_pos > 0) {
309                 int i;
310                 cur_pos -= 1;
311                 backspace();
312                 for(i=cur_pos; i<max_pos; i++)
313                     cur_line[i] = cur_line[i+1];
314                 max_pos -= 1;
315                 fix_line();
316             }
317         } else if(cur_char == term_chars[VEOF] ){ /* ^D? */
318             if(max_pos == 0) {
319                 copy_line("to exit EiC, enter  :exit\n");
320                 user_putc(BELL);
321
322                 reset_termio();         
323                 return((char*)NULL);
324             }
325             if((cur_pos < max_pos)&&(cur_char == 004)) { /* ^D */
326                 int i;
327                 for(i=cur_pos; i<max_pos; i++)
328                     cur_line[i] = cur_line[i+1];
329                 max_pos -= 1;
330                 fix_line();
331             }
332
333         } else if(cur_char == term_chars[VKILL] ){ /* ^U? */
334             clear_line(prompt);
335
336         } else if(cur_char == term_chars[VWERASE] ){ /* ^W? */
337             while((cur_pos > 0) &&
338                   (cur_line[cur_pos-1] == SPACE)) {
339                 cur_pos -= 1;
340                 backspace();
341             }
342             while((cur_pos > 0) &&
343                   (cur_line[cur_pos-1] != SPACE)) {
344                 cur_pos -= 1;
345                 backspace();
346             }
347             clear_eoline();
348             max_pos = cur_pos;
349
350
351         } else if(cur_char == term_chars[VREPRINT] ){ /* ^R? */
352             user_putc(NEWLINE); /* go to a fresh line */
353             redraw_line(prompt);
354
355
356         } else if(cur_char == term_chars[VSUSP]) {
357             reset_termio();
358             kill(0, SIGTSTP);
359
360             /* process stops here */
361
362             set_termio();
363             /* print the prompt */
364             redraw_line(prompt);
365 #endif
366         } else {
367             /* do normal editing commands */
368             /* some of these are also done above */
369             int i;
370             switch(cur_char) {
371               case EOF:
372                 reset_termio();
373                 return((char *)NULL);
374               case 001:         /* ^A */
375                 while(cur_pos > 0) {
376                     cur_pos -= 1;
377                     backspace();
378                 }
379                 break;
380               case 002:         /* ^B */
381                 if(cur_pos > 0) {
382                     cur_pos -= 1;
383                     backspace();
384                 }
385                 break;
386               case 005:         /* ^E */
387                 while(cur_pos < max_pos) {
388                     user_putc(cur_line[cur_pos]);
389                     cur_pos += 1;
390                 }
391                 break;
392               case 006:         /* ^F */
393                 if(cur_pos < max_pos) {
394                     user_putc(cur_line[cur_pos]);
395                     cur_pos += 1;
396                 }
397                 break;
398               case 013:         /* ^K */
399                 clear_eoline();
400                 max_pos = cur_pos;
401                 break;
402                 
403               case 020:         /* ^P */
404                 if(history != NULL) {
405                     if(cur_entry == NULL) {
406                         cur_entry = history;
407                         clear_line(prompt);
408                         copy_line(cur_entry->line);
409                     } else if(cur_entry->prev != NULL) {
410                         cur_entry = cur_entry->prev;
411                         clear_line(prompt);
412                         copy_line(cur_entry->line);
413                     }else
414                         user_putc(BELL);
415                 }else
416                     user_putc(BELL);
417                 break;
418
419             case 016:           /* ^N */
420                 if(cur_entry != NULL) {
421                     cur_entry = cur_entry->next;
422                     clear_line(prompt);
423                     if(cur_entry != NULL) 
424                         copy_line(cur_entry->line);
425                     else
426                         cur_pos = max_pos = 0;
427                 }else
428                     user_putc(BELL);
429                 break;
430               case 014:         /* ^L */
431               case 022:         /* ^R */
432                 user_putc(NEWLINE); /* go to a fresh line */
433                 redraw_line(prompt);
434                 break;
435               case 0177:        /* DEL */
436               case 010:         /* ^H */
437                 if(cur_pos > 0) {
438                     cur_pos -= 1;
439                     backspace();
440                     for(i=cur_pos; i<max_pos; i++)
441                         cur_line[i] = cur_line[i+1];
442                     max_pos -= 1;
443                     fix_line();
444                 }
445                 break;
446               case 004:         /* ^D */
447                 if(max_pos == 0) {
448                     reset_termio();
449                     return((char *)NULL);
450                 }
451                 if(cur_pos < max_pos) {
452                     for(i=cur_pos; i<max_pos; i++)
453                         cur_line[i] = cur_line[i+1];
454                     max_pos -= 1;
455                     fix_line();
456                 }
457                 break;
458               case 025:         /* ^U */
459                 clear_line(prompt);
460                 break;
461               case 027:         /* ^W */
462                 while((cur_pos > 0) &&
463                       (cur_line[cur_pos-1] == SPACE)) {
464                     cur_pos -= 1;
465                     backspace();
466                 }
467                 while((cur_pos > 0) &&
468                       (cur_line[cur_pos-1] != SPACE)) {
469                     cur_pos -= 1;
470                     backspace();
471                 }
472                 clear_eoline();
473                 max_pos = cur_pos;
474                 break;
475             case '\n':  /* ^J */
476             case '\r':  /* ^M */
477                 user_putc(NEWLINE);
478                 cur_line[max_pos+1] = '\0';
479                 cur_line = (char *)ralloc(cur_line,
480                                           (unsigned
481                                            long)(strlen(cur_line)+2),
482                                           "line resize");
483                 line_len=0;
484                 
485                 reset_termio();
486                 return cur_line;
487               default:
488                 break;
489             }
490         }
491     }
492 }
493
494
495 /* fix up the line from cur_pos to max_pos */
496 /* do not need any terminal capabilities except backspace, */
497 /* and space overwrites a character */
498 static void fix_line()
499 {
500     int i;
501
502     /* write tail of string */
503     user_putsn(&cur_line[cur_pos],max_pos - cur_pos);
504     
505     
506     /* write a space at the end of the line in case we deleted one */
507     user_putc(SPACE);
508
509     /* backup to original position */
510     for(i=max_pos+1; i>cur_pos; i--)
511         backspace();
512
513 }
514
515 /* redraw the entire line, putting the cursor where it belongs */
516 static void redraw_line(char *prompt)
517 {
518     int i;
519
520     user_puts(prompt);
521     user_puts(cur_line);
522
523     /* put the cursor where it belongs */
524     for(i=max_pos; i>cur_pos; i--)
525         backspace();
526 }
527
528 /* clear cur_line and the screen line */
529 static void clear_line(char *prompt)
530 {
531     int i;
532
533     memset(cur_line,0,max_pos);
534
535     for(i=cur_pos; i>0; i--)
536         backspace();
537
538     for(i=0; i<max_pos; i++)
539         user_putc(SPACE);
540
541     user_putc('\r');
542     user_puts(prompt);
543
544     cur_pos = 0;
545     max_pos = 0;
546 }
547
548 static void backupTo(char to, char from)
549 {
550     int cmode = 0;
551     int k = 1,i = cur_pos-1;
552
553     backspace();
554     while(i-- > 0) {
555         backspace();
556         if(cur_line[i] == '\'') {
557             if(cmode & 1)
558                 cmode &= ~1;
559             else
560                 cmode |= 1;
561             continue;
562         }else if(cur_line[i] == '\"') {
563             if(cmode & 2)
564                 cmode &= ~2;
565             else
566                 cmode |= 2;
567             continue;
568         }
569             
570         if(cur_line[i] == to && !cmode) {
571             if(!--k)
572                 break;
573         }else if(cur_line[i] == from && !cmode)
574             k++;
575     }
576     if(k) {
577         user_putc(BELL);
578         i = 0;
579     } else
580         delay(CLOCKS_PER_SEC / 2);
581
582     user_putsn(&cur_line[i],cur_pos - i);
583
584 }
585     
586 /* clear to end of line and the screen end of line */
587 static void clear_eoline()
588 {
589     int i;
590     for(i=cur_pos; i<max_pos; i++)
591         cur_line[i] = '\0';
592
593     for(i=cur_pos; i<max_pos; i++)
594         user_putc(SPACE);
595     for(i=cur_pos; i<max_pos; i++)
596         backspace();
597 }
598
599 /* copy line to cur_line, draw it and set cur_pos and max_pos */
600 static void copy_line(char *line)
601 {
602     while(strlen(line)+1>line_len) {
603         extend_cur_line();
604     }
605     strcpy(cur_line, line);
606     user_puts(cur_line);
607     cur_pos = max_pos = strlen(cur_line);
608 }
609
610 /* add line to the history */
611 #ifndef _HistLimit       /* history limiter */
612 #define _HistLimit 500
613 #endif
614
615 void EiC_add_history(unsigned char *line)
616 {
617     static unsigned int limit = 0;
618     struct hist *entry;
619
620     if(limit == _HistLimit && EndHist) {
621         free(EndHist->line);
622         entry = EndHist;
623         EndHist = EndHist->next;
624         EndHist->prev = NULL;
625     } else {
626         entry = (struct hist *)alloc((unsigned long)sizeof(struct hist),"history");
627         limit++;
628     }
629     entry->line = alloc((unsigned long)(strlen(line)+1),"history");
630     strcpy(entry->line, line);
631     
632     entry->prev = history;
633     entry->next = NULL;
634     if(history != NULL) {
635         history->next = entry;
636     } else /* get first entry */
637         EndHist = entry;
638     
639     history = entry;
640     HistLineNo++;
641 }
642
643 int  EiC_getHistLineNo()
644 {
645     return HistLineNo;
646 }
647             
648 void EiC_save_history(FILE *to, int from)
649 {
650     int cl = HistLineNo - 1;
651     struct hist *p;
652     p = history;
653     while(cl-- > from)
654         p = p->prev;
655     while(p) {
656         fprintf(to,"%s\n",p->line);
657         p = p->next;
658     }
659 }
660
661 /* show all history lines */
662 void EiC_show_history(FILE *fp)
663 {
664     struct hist *p;
665     p = EndHist;
666     while(p) {
667         fputs(p->line,fp);
668         putc(NEWLINE,fp);
669         p = p->next;
670     }
671     fflush(fp);
672 }
673
674 int EiC_load_history(char * fname, int prompt)
675 {
676 #define BufSz  512
677
678     int i;
679     char buff[BufSz];
680     char *line;
681     
682     FILE *fp = fopen(fname,"r");
683     if(prompt)
684         set_termio();    
685     if(fp) {
686         while(fgets(buff,BufSz-2,fp)) {
687             for(i=0;buff[i] && buff[i] != '\n';++i)
688                 ;
689             if(!buff[i])
690                 buff[i++] = '\\';
691             buff[i] = 0;
692             if(prompt) {
693                 printf("Re-enter [%s] (Y/N/E)?",buff);
694                 switch(special_getc()) {
695                 case 'y':
696                 case 'Y':
697                     user_puts(" Y\n");
698                     break;
699                 case 'e':
700                 case 'E':
701                     user_puts(" E\n");
702                     copy_line(buff);
703                     line = editLine("edit: ");
704                     if(*line)
705                         EiC_add_history(line);
706                     free(line);
707                     set_termio();
708                     continue;
709                 default:
710                     user_puts(" N\n");
711                     continue;
712                     
713                 }
714             }
715             EiC_add_history(buff);
716         }
717         fclose(fp);
718         i = 1;
719     } else
720         i = 0;
721     if(prompt)
722         reset_termio();
723     printf("added %d lines\n",HistLineNo);
724     return i;
725
726 #undef BufSz
727 }
728     
729
730 #if defined(WIN32)
731
732 /* Convert Arrow keystrokes to Control characters: */
733 static char msdos_getch()
734 {
735     int c = _getch();
736     if (c == 224 || c== 0) {
737                 c = _getch();           /* Get the extended code. */
738                 switch (c) {
739                 case 75:                /* Left Arrow. */
740                         c = 002;
741                  break;
742                 case 77:                /* Right Arrow. */
743                         c = 006;
744                         break;
745                 case 72:                /* Up Arrow. */
746                         c = 020;
747                         break;
748                 case 80:                /* Down Arrow. */
749                         c = 016;
750                         break;
751                 case 115:               /* Ctl Left Arrow. */
752                 case 71:                /* Home */
753                         c = 001;
754                         break;
755                 case 116:               /* Ctl Right Arrow. */
756                 case 79:                /* End */
757                         c = 005;
758                         break;
759                 case 83:                /* Delete */
760                         c = 004;
761                         break;
762                 default:
763                         c = 0;
764             break;
765                 }
766         } else if (c == 033) {  /* ESC */
767                 c = 025;
768     }
769     return c;
770 }
771
772 static void set_termio() {} 
773 static void reset_termio() {}
774
775 #else
776
777 /* Convert ANSI arrow keys to control characters */
778 static int ansi_getc()
779 {
780   int c = getc(stdin);
781   if (c == 033) {
782     c = getc(stdin); /* check for CSI */
783     if (c == '[') {
784       c = getc(stdin); /* get command character */
785       switch (c) {
786       case 'D': /* left arrow key */
787         c = 002;
788         break;
789       case 'C': /* right arrow key */
790         c = 006;
791         break;
792       case 'A': /* up arrow key */
793         c = 020;
794         break;
795         
796       case 'B': /* down arrow key */
797         c = 016;
798         break;
799       }
800     }
801   }
802   return c;
803 }
804
805 /* set termio so we can do our own input processing */
806 static void set_termio()
807 {
808     if(term_set == 0) {
809         tcgetattr(0, &orig_termio);
810         rl_termio = orig_termio;
811         rl_termio.c_iflag &= ~(BRKINT|PARMRK|INPCK/*|IUCLC*/|IXON|IXOFF);
812         rl_termio.c_iflag |=  (IGNBRK|IGNPAR);
813         /* rl_termio.c_oflag &= ~(ONOCR); Costas Sphocleous Irvine,CA */
814         rl_termio.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH);
815         rl_termio.c_lflag |=  (ISIG);
816         rl_termio.c_cc[VMIN] = 1;
817         rl_termio.c_cc[VTIME] = 0;
818         term_chars[VERASE]   = orig_termio.c_cc[VERASE];
819         term_chars[VEOF]     = orig_termio.c_cc[VEOF];
820         term_chars[VKILL]    = orig_termio.c_cc[VKILL];
821         term_chars[VWERASE]  = orig_termio.c_cc[VWERASE];
822         term_chars[VREPRINT] = orig_termio.c_cc[VREPRINT];
823         term_chars[VSUSP]    = orig_termio.c_cc[VSUSP];
824         /* disable suspending process on ^Z */
825         rl_termio.c_cc[VSUSP] = 0;
826         tcsetattr(0, TCSADRAIN, &rl_termio);
827         term_set = 1;
828     }
829     
830 }
831   
832 static void reset_termio()
833 {
834     if(term_set == 1) {
835         tcsetattr(0, TCSADRAIN, &orig_termio);
836         term_set = 0;
837     }
838 }
839
840 #endif
841
842 #ifdef _STANDALONE
843 int main()
844 {
845     char * line = NULL;
846     printf("**Press ^D in empty line to exit**\n");
847     do {
848         line = EiC_readline("$$> ");
849         if (line) {
850             if(*line)
851                 EiC_add_history(line);
852             free(line);
853         }
854     } while(line);
855     printf("\n-----------------\n");
856     EiC_show_history(stdout);
857     return 0;
858 }
859 #endif
860
861 #endif      
862