source: git/kernel/feread.cc @ 854405

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