source: git/kernel/feread.cc @ e4e36c

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