source: git/kernel/fereadl.c @ 5a9e7b

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