source: git/Singular/feread.cc @ 48aa42

fieker-DuValspielwiese
Last change on this file since 48aa42 was 1be9b03, checked in by Olaf Bachmann <obachman@…>, 24 years ago
cleaned up feread.cc git-svn-id: file:///usr/local/Singular/svn/trunk@4635 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: feread.cc,v 1.39 2000-09-25 14:46:55 obachman 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
15#include "static.h"
16
17#ifdef HAVE_STATIC
18#undef HAVE_DYN_RL
19#endif
20
21#ifdef HAVE_TCL
22#include "ipid.h"
23#endif
24
25static char * fe_fgets_stdin_init(char *pr,char *s, int size);
26char * (*fe_fgets_stdin)(char *pr,char *s, int size)
27 = fe_fgets_stdin_init;
28
29/* ===================================================================*/
30/* =                   static/dymanic readline                      = */
31/* ===================================================================*/
32#if defined(HAVE_READLINE) || defined(HAVE_DYN_RL)
33
34#include "ipshell.h"
35
36#ifndef STDOUT_FILENO
37#define STDOUT_FILENO 1
38#endif
39
40/* Generator function for command completion.  STATE lets us know whether
41*   to start from scratch; without any state (i.e. STATE == 0), then we
42*   start at the top of the list.
43*/
44char *command_generator (char *text, int state)
45{
46  static int list_index, len;
47  char *name;
48
49  /* If this is a new word to complete, initialize now.  This includes
50     saving the length of TEXT for efficiency, and initializing the index
51     variable to 0. */
52  if (state==0)
53  {
54    list_index = 1;
55    len = strlen (text);
56  }
57
58  /* Return the next name which partially matches from the command list. */
59  while ((name = cmds[list_index].name)!=NULL)
60  {
61    list_index++;
62
63    if (strncmp (name, text, len) == 0)
64      return (strdup(name));
65  }
66
67  /* If no names matched, then return NULL. */
68  return ((char *)NULL);
69}
70#endif
71
72/* ===================================================================*/
73/* =                      static readline                           = */
74/* ===================================================================*/
75/* some procedure are shared with "dynamic readline" */
76#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD)
77#include <unistd.h>
78#include <stdio.h>
79#include <stdlib.h>
80#include <sys/types.h>
81#include <sys/file.h>
82#include <sys/stat.h>
83#include <sys/errno.h>
84
85// #undef READLINE_READLINE_H_OK
86
87extern "C" {
88 #ifdef READLINE_READLINE_H_OK
89  #include <readline/readline.h>
90  #ifdef HAVE_READLINE_HISTORY_H
91   #include <readline/history.h>
92  #endif
93 #else /* declare everything we need explicitely and do not rely on includes */
94  extern char * rl_readline_name;
95  extern char *rl_line_buffer;
96  char *filename_completion_function();
97  typedef char **CPPFunction ();
98  extern char ** completion_matches ();
99  extern CPPFunction * rl_attempted_completion_function;
100  extern FILE * rl_outstream;
101  extern char * readline ();
102  extern void add_history ();
103  extern int write_history ();
104  extern void using_history();
105  extern int read_history();
106  extern int history_total_bytes();
107 #endif /* READLINE_READLINE_H_OK */
108}
109
110
111char * fe_fgets_stdin_rl(char *pr,char *s, int size);
112
113/* Tell the GNU Readline library how to complete.  We want to try to complete
114   on command names  or on filenames if it is preceded by " */
115
116/* Attempt to complete on the contents of TEXT.  START and END show the
117*   region of TEXT that contains the word to complete.  We can use the
118*   entire line in case we want to do some simple parsing.  Return the
119*   array of matches, or NULL if there aren't any.
120*/
121char ** singular_completion (char *text, int start, int end)
122{
123  /* If this word is not in a string, then it may be a command
124     to complete.  Otherwise it may be the name of a file in the current
125     directory. */
126  if (rl_line_buffer[start-1]=='"')
127    return completion_matches (text, filename_completion_function);
128  char **m=completion_matches (text, command_generator);
129  if (m==NULL)
130  {
131    m=(char **)malloc(2*sizeof(char*));
132    m[0]=(char *)malloc(end-start+2);
133    strncpy(m[0],text,end-start+1);
134    m[1]=NULL;
135  }
136  return m;
137}
138
139char * fe_fgets_stdin_rl(char *pr,char *s, int size)
140{
141  if (!BVERBOSE(V_PROMPT))
142  {
143    pr="";
144  }
145  mflush();
146
147  char *line;
148  line = readline (pr);
149
150  if (line==NULL)
151    return NULL;
152
153  if (*line!='\0')
154  {
155    add_history (line);
156  }
157  int l=strlen(line);
158  if (l>=size-1)
159  {
160    strncpy(s,line,size);
161  }
162  else
163  {
164    strncpy(s,line,l);
165    s[l]='\n';
166    s[l+1]='\0';
167  }
168  free (line);
169
170  return s;
171}
172#endif
173
174/* ===================================================================*/
175/* =                    emulated readline                           = */
176/* ===================================================================*/
177#if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
178extern "C" {
179char * fe_fgets_stdin_fe(char *pr,char *s, int size);
180}
181char * fe_fgets_stdin_emu(char *pr,char *s, int size)
182{
183  if (!BVERBOSE(V_PROMPT))
184  {
185    pr="";
186  }
187  mflush();
188  return fe_fgets_stdin_fe(pr,s,size);
189}
190#endif
191
192/* ===================================================================*/
193/* =                     dynamic readline                           = */
194/* ===================================================================*/
195/* some procedure are shared with "static readline" */
196
197#if defined(HAVE_DYN_RL)
198#include <unistd.h>
199//#include <stdio.h>
200//#include <stdlib.h>
201//#include <sys/types.h>
202//#include <sys/file.h>
203//#include <sys/stat.h>
204//#include <sys/errno.h>
205//#include <dlfcn.h>
206#include "mod_raw.h"
207
208extern "C" {
209  typedef char* (*String_Func)();
210  typedef void  (*Void_Func)();
211  typedef int  (*Int_Func)();
212  typedef char** (*CharStarStar_Func)();
213  char *(*fe_filename_completion_function)(); /* 3 */
214  char *(* fe_readline) ();                   /* 4 */
215  void (*fe_add_history) ();                  /* 5 */
216  char ** fe_rl_readline_name;                /* 6 */
217  char **fe_rl_line_buffer;                   /* 7 */
218  char **(*fe_completion_matches)();          /* 8 */
219  typedef char **CPPFunction ();
220  CPPFunction **fe_rl_attempted_completion_function; /* 9 */
221  FILE ** fe_rl_outstream;                    /* 10 */
222  int (*fe_write_history) ();                 /* 11 */
223  int (*fe_history_total_bytes) ();           /* 12 */
224  void (*fe_using_history) ();                /* 13 */
225  int (*fe_read_history) ();                  /* 14 */
226}
227
228void * fe_rl_hdl=NULL;
229
230char * fe_fgets_stdin_rl(char *pr,char *s, int size);
231static int fe_init_dyn_rl()
232{
233  int res=0;
234  loop
235  {
236    #if defined(HPUX_9) || defined(HPUX_10)
237    fe_rl_hdl=dynl_open("libreadline.sl");
238    if (fe_rl_hdl==NULL)
239      fe_rl_hdl=dynl_open("/lib/libreadline.sl");
240    if (fe_rl_hdl==NULL)
241      fe_rl_hdl=dynl_open("/usr/lib/libreadline.sl");
242    #else
243    fe_rl_hdl=dynl_open("libreadline.so");
244    #endif
245    if (fe_rl_hdl==NULL) { return 1;}
246
247    fe_filename_completion_function= (String_Func)
248      dynl_sym(fe_rl_hdl, "filename_completion_function");
249    if (fe_filename_completion_function==NULL) { res=3; break; }
250    fe_readline=(String_Func)dynl_sym(fe_rl_hdl,"readline");
251    if (fe_readline==NULL) { res=4; break; }
252    fe_add_history=(Void_Func)dynl_sym(fe_rl_hdl,"add_history");
253    if (fe_add_history==NULL) { res=5; break; }
254    fe_rl_readline_name=(char**)dynl_sym(fe_rl_hdl,"rl_readline_name");
255    if (fe_rl_readline_name==NULL) { res=6; break; }
256    fe_rl_line_buffer=(char**)dynl_sym(fe_rl_hdl,"rl_line_buffer");
257    if (fe_rl_line_buffer==NULL) { res=7; break; }
258    fe_completion_matches=(CharStarStar_Func)dynl_sym(fe_rl_hdl,"completion_matches");
259    if (fe_completion_matches==NULL) { res=8; break; }
260    fe_rl_attempted_completion_function=
261      (CPPFunction**) dynl_sym(fe_rl_hdl,"rl_attempted_completion_function");
262    if (fe_rl_attempted_completion_function==NULL) { res=9; break; }
263    fe_rl_outstream=(FILE**)dynl_sym(fe_rl_hdl,"rl_outstream");
264    if (fe_rl_outstream==NULL) { res=10; break; }
265    fe_write_history=(Int_Func)dynl_sym(fe_rl_hdl,"write_history");
266    if (fe_write_history==NULL) { res=11; break; }
267    fe_history_total_bytes=(Int_Func)dynl_sym(fe_rl_hdl,"history_total_bytes");
268    if (fe_history_total_bytes==NULL) { res=12; break; }
269    fe_using_history=(Void_Func)dynl_sym(fe_rl_hdl,"using_history");
270    if (fe_using_history==NULL) { res=13; break; }
271    fe_read_history=(Int_Func)dynl_sym(fe_rl_hdl,"read_history");
272    if (fe_read_history==NULL) { res=14; break; }
273    return 0;
274  }
275  dynl_close(fe_rl_hdl);
276  return res;
277}
278
279/* Attempt to complete on the contents of TEXT.  START and END show the
280*   region of TEXT that contains the word to complete.  We can use the
281*   entire line in case we want to do some simple parsing.  Return the
282*   array of matches, or NULL if there aren't any.
283*/
284char ** singular_completion (char *text, int start, int end)
285{
286  /* If this word is not in a string, then it may be a command
287     to complete.  Otherwise it may be the name of a file in the current
288     directory. */
289  if ((*fe_rl_line_buffer)[start-1]=='"')
290    return (*fe_completion_matches) (text, *fe_filename_completion_function);
291  char **m=(*fe_completion_matches) (text, command_generator);
292  if (m==NULL)
293  {
294    m=(char **)malloc(2*sizeof(char*));
295    m[0]=(char *)malloc(end-start+2);
296    strncpy(m[0],text,end-start+1);
297    m[1]=NULL;
298  }
299  return m;
300}
301
302char * fe_fgets_stdin_drl(char *pr,char *s, int size)
303{
304  if (!BVERBOSE(V_PROMPT))
305  {
306    pr="";
307  }
308  mflush();
309
310  char *line;
311  line = (*fe_readline) (pr);
312
313  if (line==NULL)
314    return NULL;
315
316  if (*line!='\0')
317  {
318    (*fe_add_history) (line);
319  }
320  int l=strlen(line);
321  if (l>=size-1)
322  {
323    strncpy(s,line,size);
324  }
325  else
326  {
327    strncpy(s,line,l);
328    s[l]='\n';
329    s[l+1]='\0';
330  }
331  free (line);
332
333  return s;
334}
335#endif
336
337/* ===================================================================*/
338/* =                        fgets                                   = */
339/* ===================================================================*/
340char * fe_fgets(char *pr,char *s, int size)
341{
342  if (BVERBOSE(V_PROMPT))
343  {
344    fprintf(stdout,pr);
345  }
346  mflush();
347  return fgets(s,size,stdin);
348}
349
350/* ===================================================================*/
351/* =       init for static rl, dyn. rl, emu. rl                     = */
352/* ===================================================================*/
353static char * fe_fgets_stdin_init(char *pr,char *s, int size)
354{
355#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD)
356  /* Allow conditional parsing of the ~/.inputrc file. */
357  rl_readline_name = "Singular";
358  /* Tell the completer that we want a crack first. */
359  rl_attempted_completion_function = (CPPFunction *)singular_completion;
360
361  /* set the output stream */
362  if(!isatty(STDOUT_FILENO))
363  {
364    #ifdef atarist
365      rl_outstream = fopen( "/dev/tty", "w" );
366    #else
367      rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
368    #endif
369  }
370
371  /* try to read a history */
372  using_history();
373  char *p = getenv("SINGULARHIST");
374  if (p != NULL)
375  {
376    read_history (p);
377  }
378  fe_fgets_stdin=fe_fgets_stdin_rl;
379  return(fe_fgets_stdin_rl(pr,s,size));
380#endif
381#ifdef HAVE_DYN_RL
382  /* do dynamic loading */
383  int res=fe_init_dyn_rl();
384  if (res!=0)
385  {
386    //if (res==1)
387    //  WarnS("dynamic loading of libreadline failed");
388    //else
389    //  Warn("dynamic loading failed: %d\n",res);
390    if (res!=1)
391      Warn("dynamic loading failed: %d\n",res);
392    fe_fgets_stdin=fe_fgets_stdin_emu;
393    return fe_fgets_stdin_emu(pr,s,size);
394  }
395  /* Allow conditional parsing of the ~/.inputrc file. */
396  (*fe_rl_readline_name) = "Singular";
397  /* Tell the completer that we want a crack first. */
398  (*fe_rl_attempted_completion_function) = (CPPFunction *)singular_completion;
399
400  /* set the output stream */
401  if(!isatty(STDOUT_FILENO))
402  {
403    #ifdef atarist
404      *fe_rl_outstream = fopen( "/dev/tty", "w" );
405    #else
406      *fe_rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
407    #endif
408  }
409
410  /* try to read a history */
411  (*fe_using_history)();
412  char *p = getenv("SINGULARHIST");
413  if (p != NULL)
414  {
415    (*fe_read_history) (p);
416  }
417  fe_fgets_stdin=fe_fgets_stdin_drl;
418  return fe_fgets_stdin_drl(pr,s,size);
419#else
420  #if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
421    fe_fgets_stdin=fe_fgets_stdin_emu;
422    return(fe_fgets_stdin_emu(pr,s,size));
423  #endif
424#endif
425}
426
427/* ===================================================================*/
428/* =                          TCL                                   = */
429/* ===================================================================*/
430#ifdef HAVE_TCL
431/* tcl: */
432char * fe_fgets_tcl(char *pr,char *s, int size)
433{
434  if(currRing!=NULL) PrintTCLS('P',pr);
435  else               PrintTCLS('U',pr);
436  mflush();
437  return fgets(s,size,stdin);
438}
439
440#endif
441
442/* ===================================================================*/
443/* =                      batch mode                                = */
444/* ===================================================================*/
445/* dummy (for batch mode): */
446char * fe_fgets_dummy(char *pr,char *s, int size)
447{
448  return NULL;
449}
450
451/* ===================================================================*/
452/* =          fe_reset_input_mode (all possibilities)               = */
453/* ===================================================================*/
454void fe_reset_input_mode ()
455{
456#if defined(HAVE_DYN_RL)
457  char *p = getenv("SINGULARHIST");
458  if ((p != NULL) && (fe_history_total_bytes != NULL))
459  {
460    if((*fe_history_total_bytes)()!=0)
461      (*fe_write_history) (p);
462  }
463#endif
464#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD) && !defined(HAVE_DYN_RL)
465  char *p = getenv("SINGULARHIST");
466  if (p != NULL)
467  {
468    if(history_total_bytes()!=0)
469      write_history (p);
470  }
471#endif
472#if !defined(MSDOS) && (defined(HAVE_FEREAD) || defined(HAVE_DYN_RL))
473  #ifndef HAVE_ATEXIT
474  fe_reset_fe(NULL,NULL);
475  #else
476  fe_reset_fe();
477  #endif
478#endif
479}
Note: See TracBrowser for help on using the repository browser.