source: git/kernel/feread.cc @ a5b80a

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