source: git/kernel/feread.cc @ e6cbed

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