source: git/kernel/fereadl.c @ eab144e

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