source: git/Singular/feread.cc @ f413ec5

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