source: git/Singular/fereadl.c @ 8847e42

spielwiese
Last change on this file since 8847e42 was 8847e42, checked in by Hans Schönemann <hannes@…>, 21 years ago
*hannes: FEREAD fix git-svn-id: file:///usr/local/Singular/svn/trunk@6740 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 23.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: fereadl.c,v 1.25 2003-05-22 17:29:59 Singular Exp $ */
5/*
6* ABSTRACT: input from ttys, simulating fgets
7*/
8
9
10#include "mod2.h"
11#include "tok.h"
12#include "febase.h"
13#include "omalloc.h"
14#include "structs.h"
15#include "febase.h"
16
17#ifdef HAVE_FEREAD
18  #include <unistd.h>
19  #include <stdio.h>
20  #include <stdlib.h>
21  #include <sys/time.h>
22  #include <sys/types.h>
23  #include <string.h>
24
25  #if 0
26    #include <pc.h>
27  #else
28    #ifdef SunOS_5
29      /* solaris special, found with v 5.7 */
30      #define _XOPEN_SOURCE_EXTENDED
31      #include "/usr/xpg4/include/term.h"
32    #endif
33    #if 0
34      #ifndef SunOS_5
35        #include <term.h>
36      #endif
37    #elif HAVE_TERMCAP_H
38      #ifndef SunOS_5
39      #include <termcap.h>
40      #endif
41    #endif
42    #if defined(HAVE_TERMIOS_H) && ! defined(TCSANOW)
43      #include <termios.h>
44    #endif
45    #if defined(HAVE_TERM_H) && ! defined(TCSANOW)
46      #include <term.h>
47    #endif
48
49    #ifdef atarist
50      #include <ioctl.h>
51    #else
52      #ifdef NeXT
53        #include <sgtty.h>
54        #include <sys/ioctl.h>
55      #endif
56    #endif
57  #endif
58
59
60#ifndef STDIN_FILENO
61  #define STDIN_FILENO 0
62#endif
63#ifndef STDOUT_FILENO
64  #define STDOUT_FILENO 1
65#endif
66
67#define feCTRL(C) ((C) & 0x1F)    /* <ctrl> character  */
68
69#ifndef MSDOS
70
71  /* Use this variable to remember original terminal attributes. */
72  #if defined( atarist ) || defined( NeXT )
73    struct sgttyb  fe_saved_attributes;
74  #else
75    struct termios fe_saved_attributes;
76  #endif
77#endif
78
79static BOOLEAN fe_stdout_is_tty;
80static BOOLEAN fe_stdin_is_tty;
81BOOLEAN fe_use_fgets=FALSE;
82static BOOLEAN fe_is_initialized=FALSE;
83FILE *  fe_echo; /*the output file for echoed characters*/
84
85#define fe_hist_max 32
86char ** fe_hist=NULL;
87short   fe_hist_pos;
88BOOLEAN fe_is_raw_tty=0;
89int     fe_cursor_pos; /* 0..colmax-1*/
90int     fe_cursor_line; /* 0..pagelength-1*/
91
92#ifndef MSDOS
93  #ifndef HAVE_ATEXIT
94    int on_exit(void (*f)(int, void *), void *arg);
95    #ifdef HAVE_FEREAD
96      void fe_reset_fe (int i, void *v)
97    #endif
98  #else
99    #ifdef HAVE_FEREAD
100      void fe_reset_fe (void)
101    #endif
102  #endif
103  {
104    if (fe_stdin_is_tty)
105    {
106      int i;
107      if (fe_is_raw_tty)
108      {
109        #ifdef atarist
110          stty(0, &fe_saved_attributes);
111        #else
112          #ifdef NeXT
113            ioctl(STDIN_FILENO, TIOCSETP, &fe_saved_attributes);
114          #else
115            tcsetattr (STDIN_FILENO, TCSANOW, &fe_saved_attributes);
116          #endif
117        #endif
118        fe_is_raw_tty=0;
119      }
120      if (fe_hist!=NULL)
121      {
122        for(i=fe_hist_max-1;i>=0;i--)
123        {
124          if (fe_hist[i] != NULL) omFree((ADDRESS)fe_hist[i]);
125        }
126        omFreeSize((ADDRESS)fe_hist,fe_hist_max*sizeof(char *));
127        fe_hist=NULL;
128      }
129      if (!fe_stdout_is_tty)
130      {
131        fclose(fe_echo);
132      }
133    }
134  }
135  void fe_temp_reset (void)
136  {
137    if (fe_is_raw_tty)
138    {
139      #ifdef atarist
140        stty(0, &fe_saved_attributes);
141      #else
142        #ifdef NeXT
143          ioctl(STDIN_FILENO, TIOCSETP, &fe_saved_attributes);
144        #else
145          tcsetattr (STDIN_FILENO, TCSANOW, &fe_saved_attributes);
146        #endif
147      #endif
148      fe_is_raw_tty=0;
149    }
150  }
151  void fe_temp_set (void)
152  {
153    if(fe_is_raw_tty==0)
154    {
155      #ifdef atarist
156        /*set line wrap mode*/
157        if(fe_stdout_is_tty)
158        {
159          printf("\033v");
160        }
161      #endif
162      #if defined( atarist ) || defined( NeXT )
163        struct sgttyb tattr;
164      #else
165        struct termios tattr;
166      #endif
167
168      /* Set the funny terminal modes. */
169      #ifdef atarist
170         gtty(0, &tattr);
171         tattr.sg_flags |= RAW;
172         tattr.sg_flags |= CBREAK;
173         tattr.sg_flags &= ~ECHO;
174         stty(0, &tattr);
175      #else
176        #ifdef NeXT
177          ioctl(STDIN_FILENO, TIOCGETP, &tattr);
178          //tattr.sg_flags |= RAW;
179          tattr.sg_flags |= CBREAK;
180          tattr.sg_flags &= ~ECHO;
181          ioctl(STDIN_FILENO, TIOCSETP, &tattr);
182          ioctl(STDOUT_FILENO, TIOCGETP, &tattr);
183          tattr.sg_flags |= CRMOD;
184          ioctl(STDOUT_FILENO, TIOCSETP, &tattr);
185        #else
186          tcgetattr (STDIN_FILENO, &tattr);
187          tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
188          tattr.c_cc[VMIN] = 1;
189          tattr.c_cc[VTIME] = 0;
190          tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
191        #endif
192      #endif
193      fe_is_raw_tty=1;
194    }
195  }
196#endif
197
198static char termcap_buff[2048];
199static int fe_out_char(int c)
200{
201  fputc(c,fe_echo);
202  return c;
203}
204void fe_init (void)
205{
206  #ifdef MSDOS
207  /*extern short ospeed;*/
208  #endif
209  fe_is_initialized=TRUE;
210  if ((!fe_use_fgets) && (isatty (STDIN_FILENO)))
211  {
212    /* Make sure stdin is a terminal. */
213    #ifndef MSDOS
214      char *term=getenv("TERM");
215
216      /*setup echo*/
217      if(isatty(STDOUT_FILENO))
218      {
219        fe_stdout_is_tty=1;
220        fe_echo=stdout;
221      }
222      else
223      {
224        fe_stdout_is_tty=0;
225        #ifdef atarist
226          fe_echo = fopen( "/dev/tty", "w" );
227        #else
228          fe_echo = fopen( ttyname(fileno(stdin)), "w" );
229        #endif
230      }
231      /* Save the terminal attributes so we can restore them later. */
232      {
233        #if defined( atarist ) || defined( NeXT )
234          struct sgttyb tattr;
235          #ifdef atarist
236            gtty(0, &fe_saved_attributes);
237          #else
238            ioctl(STDIN_FILENO, TIOCGETP, &fe_saved_attributes);
239          #endif
240        #else
241          struct termios tattr;
242          tcgetattr (STDIN_FILENO, &fe_saved_attributes);
243        #endif
244        #ifdef HAVE_FEREAD
245          #ifdef HAVE_ATEXIT
246            atexit(fe_reset_fe);
247          #else
248            on_exit(fe_reset_fe,NULL);
249          #endif
250        #endif
251
252      /* Set the funny terminal modes. */
253        #ifdef atarist
254          gtty(0, &tattr);
255          tattr.sg_flags |= RAW;
256          tattr.sg_flags |= CBREAK;
257          tattr.sg_flags &= ~ECHO;
258          stty(0, &tattr);
259        #else
260          #ifdef NeXT
261            ioctl(STDIN_FILENO, TIOCGETP, &tattr);
262            //tattr.sg_flags |= RAW;
263            tattr.sg_flags |= CBREAK;
264            tattr.sg_flags &= ~ECHO;
265            ioctl(STDIN_FILENO, TIOCSETP, &tattr);
266            ioctl(STDOUT_FILENO, TIOCGETP, &tattr);
267            tattr.sg_flags |= CRMOD;
268            ioctl(STDOUT_FILENO, TIOCSETP, &tattr);
269          #else
270            tcgetattr (STDIN_FILENO, &tattr);
271            tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
272            tattr.c_cc[VMIN] = 1;
273            tattr.c_cc[VTIME] = 0;
274            tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
275          #endif
276          /*ospeed=cfgetospeed(&tattr);*/
277        #endif
278      }
279    #endif
280    if(term==NULL)
281    {
282      printf("need TERM\n");
283    }
284    else if(tgetent(termcap_buff,term)<=0)
285    {
286      printf("could not access termcap data base\n");
287    }
288    else
289    {
290      #ifndef ix86_Win
291      extern char *BC;
292      extern char *UP;
293      extern char PC;
294      #endif
295      /* OB: why this ??? */
296      /* char *t_buf=(char *)omAlloc(128); */
297      char t_buf[128];
298      char *temp;
299
300      /* Extract information that termcap functions use.  */
301      temp = tgetstr ("pc", (char **)&t_buf);
302      PC = (temp!=NULL) ? *temp : '\0';
303      BC=tgetstr("le",(char **)&t_buf);
304      UP=tgetstr("up",(char **)&t_buf);
305
306      /* Extract information we will use */
307      colmax=tgetnum("co");
308      pagelength=tgetnum("li");
309      fe_cursor_line=pagelength-1;
310
311      /* init screen */
312      temp = tgetstr ("ti", (char **)&t_buf);
313      #if 0
314      if (temp!=NULL) tputs(temp,1,fe_out_char);
315      #endif
316
317      /* printf("TERM=%s, co=%d, li=%d\n",term,colmax,pagelength);*/
318    }
319
320    fe_stdin_is_tty=1;
321    fe_is_raw_tty=1;
322
323    /* setup history */
324    fe_hist=(char **)omAlloc0(fe_hist_max*sizeof(char *));
325    omMarkAsStaticAddr(fe_hist);
326    fe_hist_pos=0;
327  }
328  else
329  {
330    fe_stdin_is_tty=0;
331    fe_echo=stdout;
332  }
333}
334
335/* delete to end of line */
336static void fe_ctrl_k(char *s,int i)
337{
338  int j=i;
339  while(s[j]!='\0')
340  {
341    fputc(' ',fe_echo);
342    j++;
343  }
344  while(j>i)
345  {
346    fputc('\b',fe_echo);
347    j--;
348  }
349}
350
351/* delete the line */
352static void fe_ctrl_u(char *s,int *i)
353{
354  fe_ctrl_k(s,*i);
355  while((*i)>0)
356  {
357    (*i)--;
358    fputc('\b',fe_echo);
359    fputc(' ',fe_echo);
360    fputc('\b',fe_echo);
361  }
362}
363
364/*2
365* add s to the history
366* if s is no the previous one, duplicate it
367*/
368static void fe_add_hist(char *s)
369{
370  if (s[0]!='\0') /* skip empty lines */
371  {
372    /* compare this line*/
373    if (fe_hist_pos!=0)
374    {
375      if ((fe_hist[fe_hist_pos-1]!=NULL)
376      && (strcmp(fe_hist[fe_hist_pos-1],s)==0))
377        return;
378    }
379    else
380    {
381      if ((fe_hist[fe_hist_max-1]!=NULL)
382      && (strcmp(fe_hist[fe_hist_max-1],s)==0))
383        return;
384    }
385    /* normal case: enter a new line */
386    /* first free the slot at position fe_hist_pos */
387    if (fe_hist[fe_hist_pos]!=NULL)
388    {
389      omFree((ADDRESS)fe_hist[fe_hist_pos]);
390    }
391    /* and store a duplicate */
392    fe_hist[fe_hist_pos]=omStrDup(s);
393    omMarkAsStaticAddr(fe_hist[fe_hist_pos]);
394    /* increment fe_hist_pos in a circular manner */
395    fe_hist_pos++;
396    if (fe_hist_pos==fe_hist_max) fe_hist_pos=0;
397  }
398}
399
400static void fe_get_hist(char *s, int size, int *pos,int change, int incr)
401{
402  if (change)
403    fe_add_hist(s);
404  do
405  {
406    (*pos)+=incr;
407    if((*pos)>=fe_hist_max) (*pos)-=fe_hist_max;
408    else if((*pos)<0)       (*pos)+=fe_hist_max;
409  }
410  while (((*pos)!=0)&&(fe_hist[(*pos)]==NULL));
411  memset(s,0,size);
412  if (fe_hist[(*pos)]!=NULL)
413  {
414    strncpy(s,fe_hist[(*pos)],size-2);
415  }
416}
417
418static int fe_getchar()
419{
420  #ifndef MSDOS
421  char c='\0';
422  while (1!=read (STDIN_FILENO, &c, 1));
423  #else
424  int c=getkey();
425  #endif
426  #ifndef MSDOS
427  if (c == 033)
428  {
429    /* check for CSI */
430    c='\0';
431    read (STDIN_FILENO, &c, 1);
432    if (c == '[')
433    {
434      /* get command character */
435      c='\0';
436      read (STDIN_FILENO, &c, 1);
437      switch (c)
438      {
439        case 'D': /* left arrow key */
440          c = feCTRL('B')/*002*/;
441          break;
442        case 'C': /* right arrow key */
443          c = feCTRL('F')/*006*/;
444          break;
445        case 'A': /* up arrow key */
446          c = feCTRL('P')/*020*/;
447          break;
448        case 'B': /* down arrow key */
449          c = feCTRL('N')/*016*/;
450          break;
451      }
452    }
453  }
454  #endif
455  return c;
456}
457
458static void fe_set_cursor(char *s,int i)
459{
460  char tgoto_buf[40];
461  if (0)/*(fe_cursor_pos>1) && (i>0))*/
462  {
463    /*fputs(tgoto(tgetstr("cm",&tgoto_buf),fe_cursor_pos-1,fe_cursor_line),fe_echo);*/
464    tputs(
465      tgoto(tgetstr("cm",(char **)&tgoto_buf),fe_cursor_pos-1,fe_cursor_line),
466      pagelength,fe_out_char);
467    fputc(s[i-1],fe_echo);
468  }
469  else
470  {
471    /*fputs(
472      tgoto(tgetstr("cm",&tgoto_buf),fe_cursor_pos,fe_cursor_line),fe_echo);*/
473    tputs(tgoto(tgetstr("cm",(char **)&tgoto_buf),fe_cursor_pos,fe_cursor_line),
474      pagelength,fe_out_char);
475  }
476  fflush(fe_echo);
477}
478
479char * fe_fgets_stdin_fe(char *pr,char *s, int size)
480{
481  if(!fe_is_initialized)
482    fe_init();
483  if (fe_stdin_is_tty)
484  {
485    int h=fe_hist_pos;
486    int change=0;
487    #ifdef MSDOS
488      int c;
489    #else
490      char c;
491    #endif
492    int i=0;
493
494    if (fe_is_raw_tty==0)
495    {
496      fe_temp_set();
497    }
498
499    fputs(pr,fe_echo); fflush(fe_echo);
500    fe_cursor_pos=strlen(pr); /* prompt */
501
502    memset(s,0,size);
503
504    loop
505    {
506      c=fe_getchar();
507      switch(c)
508      {
509        case feCTRL('M'):
510        case feCTRL('J'):
511        {
512          fd_set fdset;
513          struct timeval tv;
514          int sel;
515
516          fe_add_hist(s);
517          i=strlen(s);
518          if (i<size-1) s[i]='\n';
519          fputc('\n',fe_echo);
520          fflush(fe_echo);
521
522          FD_ZERO (&fdset);
523          FD_SET(STDIN_FILENO, &fdset);
524          tv.tv_sec = 0;
525          tv.tv_usec = 0;
526          #ifdef hpux
527            sel = select (STDIN_FILENO+1, (int *)fdset.fds_bits, NULL, NULL, &tv);
528          #else
529            sel = select (STDIN_FILENO+1, &fdset, NULL, NULL, &tv);
530          #endif
531          if (sel==0)
532            fe_temp_reset();
533          return s;
534        }
535        #ifdef MSDOS
536        case 0x153:
537        #endif
538        case feCTRL('H'):
539        case 127:       /*delete the character left of the cursor*/
540        {
541          if (i==0) break;
542          i--;
543          fe_cursor_pos--;
544          if(fe_cursor_pos<0)
545          {
546            fe_cursor_line--;
547            fe_cursor_pos=colmax-1;
548            fe_set_cursor(s,i);
549          }
550          else
551          {
552            fputc('\b',fe_echo);
553          }
554          /* NO BREAK : next: feCTRL('D') */
555        }
556        case feCTRL('D'):  /*delete the character under the cursor or eof*/
557        {
558          int j;
559          if ((i==0) &&(s[0]=='\0')) return NULL; /*eof*/
560          if (s[i]!='\0')
561          {
562            j=i;
563            while(s[j]!='\0')
564            {
565              s[j]=s[j+1];
566              fputc(s[j],fe_echo);
567              j++;
568            }
569            fputc(' ',fe_echo);
570            if (fe_cursor_pos+(j-i)>=colmax)
571            {
572              fe_set_cursor(s,i);
573            }
574            else
575            {
576              while(j>i)
577              {
578                fputc('\b',fe_echo);
579                j--;
580              }
581            }
582          }
583          #ifdef MSDOS
584          fputc('\b',fe_echo);
585          #endif
586          change=1;
587          fflush(fe_echo);
588          break;
589        }
590        case feCTRL('A'):  /* move the cursor to the beginning of the line */
591        {
592          if (i>=colmax-strlen(pr))
593          {
594            while (i>=colmax-strlen(pr))
595            {
596              i-=colmax;
597              fe_cursor_line--;
598            }
599            i=0;
600            fe_cursor_pos=strlen(pr);
601            fe_set_cursor(s,i);
602          }
603          else
604          {
605            while(i>0)
606            {
607              i--;
608              fputc('\b',fe_echo);
609            }
610            fe_cursor_pos=strlen(pr);
611          }
612          break;
613        }
614        case feCTRL('E'): /* move the cursor to the end of the line */
615        {
616          while(s[i]!='\0')
617          {
618            fputc(s[i],fe_echo);
619            i++;
620            fe_cursor_pos++;
621            if(fe_cursor_pos>=colmax)
622            {
623              fe_cursor_pos=0;
624              if(fe_cursor_line!=(pagelength-1))
625                fe_cursor_line++;
626            }
627          }
628          break;
629        }
630        case feCTRL('B'): /* move the cursor backward one character */
631        {
632          if (i>0)
633          {
634            i--;
635            fputc('\b',fe_echo);
636            fe_cursor_pos--;
637            if(fe_cursor_pos<0)
638            {
639              fe_cursor_pos=colmax-1;
640              fe_cursor_line--;
641            }
642          }
643          break;
644        }
645        case feCTRL('F'): /* move the cursor forward  one character */
646        {
647          if(s[i]!='\0')
648          {
649            fputc(s[i],fe_echo);
650            i++;
651            fe_cursor_pos++;
652            if(fe_cursor_pos>=colmax)
653            {
654              fe_cursor_pos=0;
655              if(fe_cursor_line!=(pagelength-1))
656                fe_cursor_line++;
657            }
658          }
659          break;
660        }
661        case feCTRL('U'): /* delete entire input line */
662        {
663          fe_ctrl_u(s,&i);
664          fe_cursor_pos=strlen(pr);
665          memset(s,0,size);
666          change=1;
667          break;
668        }
669        #if 0
670        case feCTRL('W'): /* test hist. */
671        {
672          int i;
673          PrintS("\nstart hist\n");
674          for(i=0;i<fe_hist_max;i++)
675          {
676            if(fe_hist[i]!=NULL)
677            {
678              Print("%2d ",i);
679              if(i==fe_hist_pos) PrintS("-"); else PrintS(" ");
680              if(i==h) PrintS(">"); else PrintS(" ");
681              PrintS(fe_hist[i]);
682              PrintLn();
683            }
684          }
685          Print("end hist, next_pos=%d\n",fe_hist_pos);
686          break;
687        }
688        #endif
689        case feCTRL('K'): /* delete up to the end of the line */
690        {
691          fe_ctrl_k(s,i);
692          memset(&(s[i]),'\0',size-i);
693          /* s[i]='\0';*/
694          change=1;
695          break;
696        }
697        case feCTRL('L'): /* redraw screen */
698        {
699          char t_buf[40];
700          char *t=t_buf;
701          fe_cursor_line=i/colmax;
702          /*fputs(tgetstr("cl",&t),fe_echo);*/
703          tputs(tgetstr("cl",&t),pagelength,fe_out_char);
704          fflush(fe_echo);
705          fputs(pr,fe_echo);
706          fputs(s,fe_echo);
707          fe_set_cursor(s,i);
708          break;
709        }
710        case feCTRL('P'): /* previous line */
711        {
712          fe_ctrl_u(s,&i);
713          fe_get_hist(s,size,&h,change,-1);
714          while(s[i]!='\0')
715          {
716            fputc(s[i],fe_echo);
717            i++;
718          }
719          fe_cursor_pos=strlen(pr)+i/*strlen(s)*/;
720          change=0;
721          break;
722        }
723        case feCTRL('N'): /* next line */
724        {
725          fe_ctrl_u(s,&i);
726          fe_get_hist(s,size,&h,change,1);
727          while(s[i]!='\0')
728          {
729            fputc(s[i],fe_echo);
730            i++;
731          }
732          fe_cursor_pos=strlen(pr)+i/*strlen(s)*/;
733          change=0;
734          break;
735        }
736        default:
737        {
738          if ((c>=' ')&&(c<=126))
739          {
740            fputc (c,fe_echo);
741            fe_cursor_pos++;
742            if(fe_cursor_pos>=colmax)
743            {
744              fe_cursor_pos=0;
745              if(fe_cursor_line!=(pagelength-1))
746                fe_cursor_line++;
747            }
748            if (s[i]!='\0')
749            {
750              /* shift by 1 to the right */
751              int j=i;
752              int l;
753              while ((s[j]!='\0')&&(j<size-2)) j++;
754              l=j-i;
755              while (j>i) { s[j]=s[j-1]; j--; }
756              /* display */
757              fwrite(s+i+1,l,1,fe_echo);
758              fflush(fe_echo);
759              /* set cursor */
760              if(fe_cursor_pos+l>=colmax)
761              {
762                while(fe_cursor_pos+l>=colmax)
763                {
764                  fe_cursor_line--;
765                  l-=colmax;
766                }
767                fe_set_cursor(s,i);
768              }
769              else
770              {
771                while(l>0)
772                {
773                  l--;
774                  fputc('\b',fe_echo);
775                }
776              }
777              fflush(fe_echo);
778            }
779            if (i<size-1) s[i]=c;
780            i++;
781            change=1;
782          }
783        }
784      } /* switch */
785      fflush(fe_echo);
786    } /* loop */
787  }
788  /*else*/
789    return fgets(s,size,stdin);
790}
791
792//int main (void)
793//{
794//  char b[200];
795//  char * m_eof;
796//
797//  fe_init();
798//  while(1)
799//  {
800//    m_eof=fe_fgets_stdin_fe("> ",b,200);
801//    if (!m_eof) break;
802//    printf(">>%s<<\n",b);
803//  }
804//
805//  return 0;
806//}
807#endif
808
809/* ================================================================ */
810#if defined(HAVE_DYN_RL)
811#include <unistd.h>
812//#include <stdio.h>
813//#include <stdlib.h>
814//#include <sys/types.h>
815//#include <sys/file.h>
816//#include <sys/stat.h>
817//#include <sys/errno.h>
818//#include <dlfcn.h>
819#include "mod_raw.h"
820
821  typedef char **CPPFunction ();
822
823  char *(*fe_filename_completion_function)(); /* 3 */
824  char *(* fe_readline) ();                   /* 4 */
825  void (*fe_add_history) ();                  /* 5 */
826  char ** fe_rl_readline_name;                /* 6 */
827  char **fe_rl_line_buffer;                   /* 7 */
828  char **(*fe_completion_matches)();          /* 8 */
829  CPPFunction **fe_rl_attempted_completion_function; /* 9 */
830  FILE ** fe_rl_outstream;                    /* 10 */
831  int (*fe_write_history) ();                 /* 11 */
832  int (*fe_history_total_bytes) ();           /* 12 */
833  void (*fe_using_history) ();                /* 13 */
834  int (*fe_read_history) ();                  /* 14 */
835
836void * fe_rl_hdl=NULL;
837
838char *command_generator (char *text, int state);
839
840/* Attempt to complete on the contents of TEXT.  START and END show the
841*   region of TEXT that contains the word to complete.  We can use the
842*   entire line in case we want to do some simple parsing.  Return the
843*   array of matches, or NULL if there aren't any.
844*/
845char ** singular_completion (char *text, int start, int end)
846{
847  /* If this word is not in a string, then it may be a command
848     to complete.  Otherwise it may be the name of a file in the current
849     directory. */
850  char **m;
851  if ((*fe_rl_line_buffer)[start-1]=='"')
852    return (*fe_completion_matches) (text, *fe_filename_completion_function);
853  m=(*fe_completion_matches) (text, command_generator);
854  if (m==NULL)
855  {
856    m=(char **)malloc(2*sizeof(char*));
857    m[0]=(char *)malloc(end-start+2);
858    strncpy(m[0],text,end-start+1);
859    m[1]=NULL;
860  }
861  return m;
862}
863
864
865int fe_init_dyn_rl()
866{
867  int res=0;
868  loop
869  {
870    #if defined(HPUX_9) || defined(HPUX_10)
871    fe_rl_hdl=dynl_open("libreadline.sl");
872    if (fe_rl_hdl==NULL)
873      fe_rl_hdl=dynl_open("/lib/libreadline.sl");
874    if (fe_rl_hdl==NULL)
875      fe_rl_hdl=dynl_open("/usr/lib/libreadline.sl");
876    #else
877    fe_rl_hdl=dynl_open("libreadline.so");
878    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.2");
879    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.3");
880    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.4");
881    #endif
882    if (fe_rl_hdl==NULL) { return 1;}
883
884    fe_filename_completion_function= 
885      dynl_sym(fe_rl_hdl, "filename_completion_function");
886    if (fe_filename_completion_function==NULL) { res=3; break; }
887    fe_readline=dynl_sym(fe_rl_hdl,"readline");
888    if (fe_readline==NULL) { res=4; break; }
889    fe_add_history=dynl_sym(fe_rl_hdl,"add_history");
890    if (fe_add_history==NULL) { res=5; break; }
891    fe_rl_readline_name=(char**)dynl_sym(fe_rl_hdl,"rl_readline_name");
892    if (fe_rl_readline_name==NULL) { res=6; break; }
893    fe_rl_line_buffer=(char**)dynl_sym(fe_rl_hdl,"rl_line_buffer");
894    if (fe_rl_line_buffer==NULL) { res=7; break; }
895    fe_completion_matches=dynl_sym(fe_rl_hdl,"completion_matches");
896    if (fe_completion_matches==NULL) { res=8; break; }
897    fe_rl_attempted_completion_function=
898      dynl_sym(fe_rl_hdl,"rl_attempted_completion_function");
899    if (fe_rl_attempted_completion_function==NULL) { res=9; break; }
900    fe_rl_outstream=(FILE**)dynl_sym(fe_rl_hdl,"rl_outstream");
901    if (fe_rl_outstream==NULL) { res=10; break; }
902    fe_write_history=dynl_sym(fe_rl_hdl,"write_history");
903    if (fe_write_history==NULL) { res=11; break; }
904    fe_history_total_bytes=dynl_sym(fe_rl_hdl,"history_total_bytes");
905    if (fe_history_total_bytes==NULL) { res=12; break; }
906    fe_using_history=dynl_sym(fe_rl_hdl,"using_history");
907    if (fe_using_history==NULL) { res=13; break; }
908    fe_read_history=dynl_sym(fe_rl_hdl,"read_history");
909    if (fe_read_history==NULL) { res=14; break; }
910    return 0;
911  }
912  dynl_close(fe_rl_hdl);
913  if (res==0)
914  {
915    char *p;
916    /* more init stuff: */
917    /* Allow conditional parsing of the ~/.inputrc file. */
918    (*fe_rl_readline_name) = "Singular";
919    /* Tell the completer that we want a crack first. */
920    (*fe_rl_attempted_completion_function) = (CPPFunction *)singular_completion;
921    /* try to read a history */
922    (*fe_using_history)();
923    p = getenv("SINGULARHIST");
924    if (p != NULL)
925    {
926      (*fe_read_history) (p);
927    }
928  }
929  return res;
930}
931#endif
932
933/* ===================================================================*/
934/* =          fe_reset_input_mode (all possibilities)               = */
935/* ===================================================================*/
936void fe_reset_input_mode ()
937{
938#if defined(HAVE_DYN_RL)
939  char *p = getenv("SINGULARHIST");
940  if ((p != NULL) && (fe_history_total_bytes != NULL))
941  {
942    if((*fe_history_total_bytes)()!=0)
943      (*fe_write_history) (p);
944  }
945#endif
946#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD) && !defined(HAVE_DYN_RL)
947  char *p = getenv("SINGULARHIST");
948  if (p != NULL)
949  {
950    if(history_total_bytes()!=0)
951      write_history (p);
952  }
953#endif
954#if !defined(MSDOS) && defined(HAVE_FEREAD)
955  #ifndef HAVE_ATEXIT
956  fe_reset_fe(NULL,NULL);
957  #else
958  fe_reset_fe();
959  #endif
960#endif
961}
Note: See TracBrowser for help on using the repository browser.