source: git/Singular/feread.cc @ c06a32

spielwiese
Last change on this file since c06a32 was c06a32, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* New Handling of Command-line options git-svn-id: file:///usr/local/Singular/svn/trunk@3623 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.23 1999-09-20 18:03:48 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 "mmemory.h"
14#ifdef HAVE_TCL
15#include "ipid.h"
16#endif
17
18static char * fe_fgets_stdin_init(char *pr,char *s, int size);
19char * (*fe_fgets_stdin)(char *pr,char *s, int size)
20 = fe_fgets_stdin_init;
21
22/* ===================================================================*/
23/* =                   static/dymanic readline                      = */
24/* ===================================================================*/
25#if defined(HAVE_READLINE) || defined(HAVE_DYN_RL)
26
27#include "ipshell.h"
28
29#ifndef STDOUT_FILENO
30#define STDOUT_FILENO 1
31#endif
32
33/* Generator function for command completion.  STATE lets us know whether
34*   to start from scratch; without any state (i.e. STATE == 0), then we
35*   start at the top of the list.
36*/
37char *command_generator (char *text, int state)
38{
39  static int list_index, len;
40  char *name;
41
42  /* If this is a new word to complete, initialize now.  This includes
43     saving the length of TEXT for efficiency, and initializing the index
44     variable to 0. */
45  if (state==0)
46  {
47    list_index = 1;
48    len = strlen (text);
49  }
50
51  /* Return the next name which partially matches from the command list. */
52  while ((name = cmds[list_index].name)!=NULL)
53  {
54    list_index++;
55
56    if (strncmp (name, text, len) == 0)
57      return (strdup(name));
58  }
59
60  /* If no names matched, then return NULL. */
61  return ((char *)NULL);
62}
63
64
65#endif
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
128void fe_reset_input_mode (void)
129{
130  char *p = getenv("SINGULARHIST");
131  if (p != NULL)
132  {
133    if(history_total_bytes()!=0)
134      write_history (p);
135  }
136}
137
138char * fe_fgets_stdin_rl(char *pr,char *s, int size)
139{
140  if (!BVERBOSE(V_PROMPT))
141  {
142    pr="";
143  }
144  mflush();
145
146  char *line;
147  line = readline (pr);
148
149  if (line==NULL)
150    return NULL;
151
152  if (*line!='\0')
153  {
154    add_history (line);
155  }
156  int l=strlen(line);
157  if (l>=size-1)
158  {
159    strncpy(s,line,size);
160  }
161  else
162  {
163    strncpy(s,line,l);
164    s[l]='\n';
165    s[l+1]='\0';
166  }
167  free (line);
168
169  return s;
170}
171#endif
172
173/* ===================================================================*/
174/* =                    emulated readline                           = */
175/* ===================================================================*/
176#if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
177extern "C" {
178char * fe_fgets_stdin_fe(char *pr,char *s, int size);
179}
180char * fe_fgets_stdin_emu(char *pr,char *s, int size)
181{
182  if (!BVERBOSE(V_PROMPT))
183  {
184    pr="";
185  }
186  mflush();
187  return fe_fgets_stdin_fe(pr,s,size);
188}
189#endif
190
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
207extern "C" {
208  char *(*fe_filename_completion_function)(); /* 3 */
209  char *(* fe_readline) ();                   /* 4 */
210  void (*fe_add_history) ();                  /* 5 */
211  char ** fe_rl_readline_name;                /* 6 */
212  char **fe_rl_line_buffer;                   /* 7 */
213  char **(*fe_completion_matches)();          /* 8 */
214  typedef char **CPPFunction ();
215  CPPFunction **fe_rl_attempted_completion_function; /* 9 */
216  FILE ** fe_rl_outstream;                    /* 10 */
217  int (*fe_write_history) ();                 /* 11 */
218  int (*fe_history_total_bytes) ();           /* 12 */
219  void (*fe_using_history) ();                /* 13 */
220  int (*fe_read_history) ();                  /* 14 */
221}
222
223void * fe_rl_hdl=NULL;
224
225char * fe_fgets_stdin_rl(char *pr,char *s, int size);
226static int fe_init_dyn_rl()
227{
228  int res=0;
229  loop
230  {
231    fe_rl_hdl=dlopen("libreadline.so",RTLD_LAZY|RTLD_GLOBAL);
232    if (fe_rl_hdl==NULL) { res=1; break;}
233
234    fe_readline=dlsym(fe_rl_hdl,"readline");
235    if (fe_readline==NULL) { res=4; break; }
236    fe_add_history=dlsym(fe_rl_hdl,"add_history");
237    if (fe_add_history==NULL) { res=5; break; }
238    fe_rl_readline_name=dlsym(fe_rl_hdl,"rl_readline_name");
239    if (fe_rl_readline_name==NULL) { res=6; break; }
240    fe_rl_line_buffer=dlsym(fe_rl_hdl,"rl_line_buffer");
241    if (fe_rl_line_buffer==NULL) { res=7; break; }
242    fe_rl_line_buffer=dlsym(fe_rl_hdl,"rl_line_buffer");
243    if (fe_rl_line_buffer==NULL) { res=7; break; }
244    fe_completion_matches=dlsym(fe_rl_hdl,"completion_matches");
245    if (fe_completion_matches==NULL) { res=8; break; }
246    fe_rl_attempted_completion_function=
247      dlsym(fe_rl_hdl,"rl_attempted_completion_function");
248    if (fe_rl_attempted_completion_function==NULL) { res=9; break; }
249    fe_rl_outstream=dlsym(fe_rl_hdl,"rl_outstream");
250    if (fe_rl_outstream==NULL) { res=10; break; }
251    fe_write_history=dlsym(fe_rl_hdl,"write_history");
252    if (fe_write_history==NULL) { res=11; break; }
253    fe_history_total_bytes=dlsym(fe_rl_hdl,"history_total_bytes");
254    if (fe_history_total_bytes==NULL) { res=12; break; }
255    fe_using_history=dlsym(fe_rl_hdl,"using_history");
256    if (fe_using_history==NULL) { res=13; break; }
257    fe_read_history=dlsym(fe_rl_hdl,"read_history");
258    if (fe_read_history==NULL) { res=14; break; }
259    return 0;
260  }
261  dlclose(fe_rl_hdl);
262  return res;
263}
264
265
266/* Attempt to complete on the contents of TEXT.  START and END show the
267*   region of TEXT that contains the word to complete.  We can use the
268*   entire line in case we want to do some simple parsing.  Return the
269*   array of matches, or NULL if there aren't any.
270*/
271char ** singular_completion (char *text, int start, int end)
272{
273  /* If this word is not in a string, then it may be a command
274     to complete.  Otherwise it may be the name of a file in the current
275     directory. */
276  if ((*fe_rl_line_buffer)[start-1]=='"')
277    return (*fe_completion_matches) (text, *fe_filename_completion_function);
278  char **m=(*fe_completion_matches) (text, command_generator);
279  if (m==NULL)
280  {
281    m=(char **)malloc(2*sizeof(char*));
282    m[0]=(char *)malloc(end-start+2);
283    strncpy(m[0],text,end-start+1);
284    m[1]=NULL;
285  }
286  return m;
287}
288
289void fe_reset_input_mode (void)
290{
291  char *p = getenv("SINGULARHIST");
292  if (p != NULL)
293  {
294    if((*fe_history_total_bytes)()!=0)
295      (*fe_write_history) (p);
296  }
297}
298
299char * fe_fgets_stdin_drl(char *pr,char *s, int size)
300{
301  if (!BVERBOSE(V_PROMPT))
302  {
303    pr="";
304  }
305  mflush();
306
307  char *line;
308  line = (*fe_readline) (pr);
309
310  if (line==NULL)
311    return NULL;
312
313  if (*line!='\0')
314  {
315    (*fe_add_history) (line);
316  }
317  int l=strlen(line);
318  if (l>=size-1)
319  {
320    strncpy(s,line,size);
321  }
322  else
323  {
324    strncpy(s,line,l);
325    s[l]='\n';
326    s[l+1]='\0';
327  }
328  free (line);
329
330  return s;
331}
332#endif
333
334/* ===================================================================*/
335/* =                        fgets                                   = */
336/* ===================================================================*/
337char * fe_fgets(char *pr,char *s, int size)
338{
339  if (BVERBOSE(V_PROMPT))
340  {
341    fprintf(stdout,pr);
342  }
343  mflush();
344  return fgets(s,size,stdin);
345}
346
347/* ===================================================================*/
348/* =       init for static rl, dyn. rl, emu. rl                     = */
349/* ===================================================================*/
350static char * fe_fgets_stdin_init(char *pr,char *s, int size)
351{
352#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD)
353  /* Allow conditional parsing of the ~/.inputrc file. */
354  rl_readline_name = "Singular";
355  /* Tell the completer that we want a crack first. */
356  rl_attempted_completion_function = (CPPFunction *)singular_completion;
357
358  /* set the output stream */
359  if(!isatty(STDOUT_FILENO))
360  {
361    #ifdef atarist
362      rl_outstream = fopen( "/dev/tty", "w" );
363    #else
364      rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
365    #endif
366  }
367
368  /* try to read a history */
369  using_history();
370  char *p = getenv("SINGULARHIST");
371  if (p != NULL)
372  {
373    read_history (p);
374  }
375  fe_fgets_stdin=fe_fgets_stdin_rl;
376  return(fe_fgets_stdin_rl(pr,s,size));
377#endif
378#ifdef HAVE_DYN_RL
379  /* do dynamic loading */
380  int res=fe_init_dyn_rl();
381  if (res!=0)
382  {
383    Warn("dynamic loading failed: %d\n",res);
384    fe_fgets_stdin=fe_fgets_stdin_emu;
385    return fe_fgets_stdin_emu(pr,s,size);
386  }
387  /* Allow conditional parsing of the ~/.inputrc file. */
388  (*fe_rl_readline_name) = "Singular";
389  /* Tell the completer that we want a crack first. */
390  (*fe_rl_attempted_completion_function) = (CPPFunction *)singular_completion;
391
392  /* set the output stream */
393  if(!isatty(STDOUT_FILENO))
394  {
395    #ifdef atarist
396      *fe_rl_outstream = fopen( "/dev/tty", "w" );
397    #else
398      *fe_rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
399    #endif
400  }
401
402  /* try to read a history */
403  (*fe_using_history)();
404  char *p = getenv("SINGULARHIST");
405  if (p != NULL)
406  {
407    (*fe_read_history) (p);
408  }
409  fe_fgets_stdin=fe_fgets_stdin_drl;
410  return fe_fgets_stdin_drl(pr,s,size);
411#else
412  #if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
413    fe_fgets_stdin=fe_fgets_stdin_emu;
414    return(fe_fgets_stdin_emu(pr,s,size));
415  #endif
416#endif
417}
418
419/* ===================================================================*/
420/* =                          TCL                                   = */
421/* ===================================================================*/
422#ifdef HAVE_TCL
423/* tcl: */
424char * fe_fgets_tcl(char *pr,char *s, int size)
425{
426  if(currRing!=NULL) PrintTCLS('P',pr);
427  else               PrintTCLS('U',pr);
428  mflush();
429  return fgets(s,size,stdin);
430}
431#endif
432
433/* ===================================================================*/
434/* =                      batch mode                                = */
435/* ===================================================================*/
436/* dummy (for batch mode): */
437char * fe_fgets_dummy(char *pr,char *s, int size)
438{
439  return NULL;
440}
Note: See TracBrowser for help on using the repository browser.