source: git/Singular/feread.cc @ 2c694a2

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