source: git/Singular/feread.cc @ 50cbdc

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