My Project  debian-1:4.1.2-p1+ds-2
feread.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5 * ABSTRACT: input from ttys, simulating fgets
6 */
7 
8 #include "kernel/mod2.h"
9 #include <errno.h>
10 
11 // ----------------------------------------
12 // system settings:
13 
14 #undef USE_READLINE4
15 
16 //----------------------------------------
17 #ifdef __CYGWIN__
18 #define READLINE_STATIC
19 #endif
20 #include "omalloc/omalloc.h"
21 #include "misc/options.h"
22 
24 
25 #ifdef HAVE_STATIC
26 #undef HAVE_DYN_RL
27 #endif
28 
29 #if defined(HAVE_DYN_RL)
30 #include <unistd.h>
31 #endif
32 
33 static char * fe_fgets_stdin_init(const char *pr,char *s, int size);
34 char * (*fe_fgets_stdin)(const char *pr,char *s, int size)
36 
37 extern char *iiArithGetCmd(int);
38 
39 /* ===================================================================*/
40 /* = static/dymanic readline = */
41 /* ===================================================================*/
42 #if defined(HAVE_READLINE) || defined(HAVE_DYN_RL) || defined(HAVE_LIBREADLINE)
43 
44 #ifndef STDOUT_FILENO
45 #define STDOUT_FILENO 1
46 #endif
47 
48 /* Generator function for command completion. STATE lets us know whether
49 * to start from scratch; without any state (i.e. STATE == 0), then we
50 * start at the top of the list.
51 */
52 #include "Singular/ipid.h"
53 extern "C"
54 char *command_generator (char *text, int state)
55 {
56  STATIC_VAR int list_index, len;
58  const 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  h=basePack->idroot;
68  }
69 
70  /* Return the next name which partially matches from the command list. */
71  while ((name = iiArithGetCmd(list_index))!=NULL)
72  {
73  list_index++;
74 
75  if (strncmp (name, text, len) == 0)
76  return (strdup(name));
77  }
78  if (len>1)
79  {
80  while (h!=NULL)
81  {
82  name=h->id;
83  h=h->next;
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 
105 // #undef READLINE_READLINE_H_OK
106 
107 extern "C" {
108  typedef char * (*RL_PROC)(const char*,int);
109  #ifdef READLINE_READLINE_H_OK
110  #include <readline/readline.h>
111  #ifdef HAVE_READLINE_HISTORY_H
112  #include <readline/history.h>
113  #endif
114  #endif
115 
116  #ifdef RL_VERSION_MAJOR
117  #if (RL_VERSION_MAJOR >= 4)
118  #define USE_READLINE4
119  #endif
120  #endif
121 
122  #ifndef USE_READLINE4
123  #define rl_filename_completion_function filename_completion_function
124  #define rl_completion_matches completion_matches
125  #endif
126  #ifndef READLINE_READLINE_H_OK
127  /* declare everything we need explicitely and do not rely on includes */
130  char *rl_filename_completion_function(const char*, int);
131  typedef char **CPPFunction ();
132 
133  extern char ** rl_completion_matches (const char*, RL_PROC);
136  extern char * readline (const char *);
137  extern void add_history (char *);
138  extern int write_history ();
139  extern void using_history();
140  extern int read_history(char *);
141  extern int history_total_bytes();
142  #endif /* READLINE_READLINE_H_OK */
143 
144  typedef char * (*PROC)();
145 
146  typedef char **RL_CPPFunction (const char*, int,int);
147 }
148 
149 
150 char * fe_fgets_stdin_rl(const char *pr,char *s, int size);
151 
152 /* Tell the GNU Readline library how to complete. We want to try to complete
153  on command names or on filenames if it is preceded by " */
154 
155 /* Attempt to complete on the contents of TEXT. START and END show the
156 * region of TEXT that contains the word to complete. We can use the
157 * entire line in case we want to do some simple parsing. Return the
158 * array of matches, or NULL if there aren't any.
159 */
160 #if defined(HAVE_DYN_RL)
161 extern "C"
162 {
163  int fe_init_dyn_rl();
164  char *(*fe_filename_completion_function)(); /* 3 */
165  char *(* fe_readline) (char *); /* 4 */
166  VAR void (*fe_add_history) (char *); /* 5 */
167  VAR char ** fe_rl_readline_name; /* 6 */
168  VAR char **fe_rl_line_buffer; /* 7 */
169  char **(*fe_completion_matches)(...); /* 8 */
171  VAR FILE ** fe_rl_outstream; /* 10 */
172  VAR int (*fe_write_history) (); /* 11 */
173  VAR int (*fe_history_total_bytes) (); /* 12 */
174  VAR void (*fe_using_history) (); /* 13 */
175  VAR int (*fe_read_history) (char *); /* 14 */
176 
177 }
178 #endif
179 char ** singular_completion (char *text, int start, int end)
180 {
181  /* If this word is not in a string, then it may be a command
182  to complete. Otherwise it may be the name of a file in the current
183  directory. */
184 #ifdef HAVE_DYN_RL
185  #define x_rl_line_buffer (*fe_rl_line_buffer)
186  #define x_rl_completion_matches (*fe_completion_matches)
187  #define x_rl_filename_completion_function (*fe_filename_completion_function)
188 #else
189  #define x_rl_line_buffer rl_line_buffer
190  #define x_rl_completion_matches rl_completion_matches
191  #define x_rl_filename_completion_function rl_filename_completion_function
192 #endif
193  if ((start>0) && (x_rl_line_buffer[start-1]=='"'))
196 #undef x_rl_line_buffer
197 #undef x_rl_completion_matches
198  if (m==NULL)
199  {
200  m=(char **)malloc(2*sizeof(char*));
201  m[0]=(char *)malloc(end-start+2);
202  strncpy(m[0],text,end-start+1);
203  m[1]=NULL;
204  }
205  return m;
206 }
207 
208 #ifndef HAVE_DYN_RL
209 char * fe_fgets_stdin_rl(const char *pr,char *s, int size)
210 {
211  if (!BVERBOSE(V_PROMPT))
212  {
213  pr="";
214  }
215  mflush();
216 
217  char *line;
218  line = readline (pr);
219 
220  if (line==NULL)
221  return NULL;
222 
223  int l=strlen(line);
224  for (int i=l-1;i>=0;i--) line[i]=line[i]&127;
225 
226  if (*line!='\0')
227  {
228  add_history (line);
229  }
230  if (l>=size-1)
231  {
232  strncpy(s,line,size);
233  }
234  else
235  {
236  strncpy(s,line,l);
237  s[l]='\n';
238  s[l+1]='\0';
239  }
240  free (line);
241 
242  return s;
243 }
244 #endif
245 #endif
246 
247 /* ===================================================================*/
248 /* = emulated readline = */
249 /* ===================================================================*/
250 #if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
251 extern "C" {
252 char * fe_fgets_stdin_fe(const char *pr,char *s, int size);
253 }
254 char * fe_fgets_stdin_emu(const char *pr,char *s, int size)
255 {
256  if (!BVERBOSE(V_PROMPT))
257  {
258  pr="";
259  }
260  mflush();
261  return fe_fgets_stdin_fe(pr,s,size);
262 }
263 #endif
264 
265 /* ===================================================================*/
266 /* = dynamic readline = */
267 /* ===================================================================*/
268 /* some procedure are shared with "static readline" */
269 #if defined(HAVE_DYN_RL)
270 char * fe_fgets_stdin_drl(const char *pr,char *s, int size)
271 {
272  if (!BVERBOSE(V_PROMPT))
273  {
274  pr="";
275  }
276  mflush();
277 
278  char *line;
279  line = (*fe_readline) ((char*)pr);
280 
281  if (line==NULL)
282  return NULL;
283 
284  int l=strlen(line);
285  for (int i=l-1;i>=0;i--) line[i]=line[i]&127;
286 
287  if (*line!='\0')
288  {
289  (*fe_add_history) (line);
290  }
291  if (l>=size-1)
292  {
293  strncpy(s,line,size);
294  }
295  else
296  {
297  strncpy(s,line,l);
298  s[l]='\n';
299  s[l+1]='\0';
300  }
301  free (line);
302 
303  return s;
304 }
305 #endif
306 
307 /* ===================================================================*/
308 /* = fgets = */
309 /* ===================================================================*/
310 char * fe_fgets(const char *pr,char *s, int size)
311 {
312  if (BVERBOSE(V_PROMPT))
313  {
314  fputs(pr,stdout);
315  }
316  mflush();
317  errno=0;
318  char *line=fgets(s,size,stdin);
319  if (line!=NULL)
320  {
321  for (int i=strlen(line)-1;i>=0;i--) line[i]=line[i]&127;
322  }
323  else
324  {
325  /* NULL can mean various things... */
326  switch(errno)
327  {
328  case 0: return NULL; /*EOF */
329  case EBADF: return NULL; /* stdin got closed */
330  case EINTR: return strcpy(s,"\n"); /* CTRL-C or other signal */
331  default: /* other error */
332  {
333  int errsv = errno;
334  fprintf(stderr,"fgets() failed with errno %d\n%s\n",errsv,strerror(errsv));
335  return NULL;
336  }
337  }
338  }
339  return line;
340 }
341 
342 /* ===================================================================*/
343 /* = init for static rl, dyn. rl, emu. rl = */
344 /* ===================================================================*/
345 static char * fe_fgets_stdin_init(const char *pr,char *s, int size)
346 {
347 #if (defined(HAVE_READLINE) || defined(HAVE_LIBREADLINE)) && !defined(HAVE_DYN_RL) && !defined(HAVE_FEREAD)
348  /* Allow conditional parsing of the ~/.inputrc file. */
349  rl_readline_name = (char*)"Singular";
350  /* Tell the completer that we want a crack first. */
351 #ifdef USE_READLINE4
352  rl_attempted_completion_function = (rl_completion_func_t *)singular_completion;
353 #else
355 #endif
356 
357  /* set the output stream */
358  if(!isatty(STDOUT_FILENO))
359  {
360  #ifdef atarist
361  rl_outstream = fopen( "/dev/tty", "w" );
362  #else
363  char *fn=ttyname(fileno(stdin));//if stdout is not a tty, maybe stdin is?
364  if (fn!=NULL) rl_outstream = fopen( fn, "w" );
365  #endif
366  }
367 
368  if(isatty(fileno(stdin)))
369  {
370  /* try to read a history */
371  using_history();
372  char *p = getenv("SINGULARHIST");
373  if (p != NULL)
374  {
375  read_history (p);
376  }
378  return(fe_fgets_stdin_rl(pr,s,size));
379  }
380  else
381  {
383  return(fe_fgets(pr,s,size));
384  }
385 #endif
386 #ifdef HAVE_DYN_RL
387  /* do dynamic loading */
388  int res=fe_init_dyn_rl();
389  if (res!=0)
390  {
391  //if (res==1)
392  // WarnS("dynamic loading of libreadline failed");
393  //else
394  // Warn("dynamic loading failed: %d\n",res);
395  if (res!=1)
396  Warn("dynamic loading failed: %d\n",res);
397  #ifdef HAVE_FEREAD
399  #else
401  #endif
402  return fe_fgets_stdin(pr,s,size);
403  }
404  else if (isatty(STDIN_FILENO))/*and could load libreadline: */
405  {
406  /* Allow conditional parsing of the ~/.inputrc file. */
407  *fe_rl_readline_name = "Singular";
408  /* Tell the completer that we want a crack first. */
410  /* try to read a history */
411  (*fe_using_history)();
412  char *p = getenv("SINGULARHIST");
413  if (p != NULL)
414  {
415  (*fe_read_history) (p);
416  }
417 
418  /* set the output stream */
419  if(!isatty(STDOUT_FILENO))
420  {
421  #ifdef atarist
422  *fe_rl_outstream = fopen( "/dev/tty", "w" );
423  #else
424  char *fn=ttyname(fileno(stdin));//if stdout is not a tty, maybe stdin is?
425  if (fn!=NULL) *fe_rl_outstream = fopen( fn, "w" );
426  #endif
427  }
429  return fe_fgets_stdin_drl(pr,s,size);
430  }
431  else
432  {
434  return fe_fgets(pr,s,size);
435  }
436 #else
437  #if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
439  return(fe_fgets_stdin_emu(pr,s,size));
440  #else
442  return(fe_fgets(pr,s,size));
443  #endif
444 #endif
445 }
446 
447 /* ===================================================================*/
448 /* = batch mode = */
449 /* ===================================================================*/
450 /* dummy (for batch mode): */
451 char * fe_fgets_dummy(const char */*pr*/,char */*s*/, int /*size*/)
452 {
453  return NULL;
454 }
455 
fe_read_history
VAR int(* fe_read_history)(char *)
Definition: feread.cc:175
fe_fgets_dummy
char * fe_fgets_dummy(const char *, char *, int)
Definition: feread.cc:451
omalloc.h
getenv
char * getenv()
read_history
int read_history(char *)
rl_readline_name
EXTERN_VAR char * rl_readline_name
Definition: feread.cc:128
fe_history_total_bytes
VAR int(* fe_history_total_bytes)()
Definition: feread.cc:173
readline
char * readline(const char *)
h
STATIC_VAR Poly * h
Definition: janet.cc:971
fe_rl_readline_name
VAR char ** fe_rl_readline_name
Definition: feread.cc:167
STDOUT_FILENO
#define STDOUT_FILENO
Definition: feread.cc:45
RL_CPPFunction
char ** RL_CPPFunction(const char *, int, int)
Definition: feread.cc:146
rl_filename_completion_function
#define rl_filename_completion_function
Definition: feread.cc:123
STATIC_VAR
#define STATIC_VAR
Definition: globaldefs.h:7
options.h
fe_fgets_stdin
char *(* fe_fgets_stdin)(const char *pr, char *s, int size)
Definition: feread.cc:34
fe_rl_outstream
VAR FILE ** fe_rl_outstream
Definition: feread.cc:171
using_history
void using_history()
fe_init_dyn_rl
int fe_init_dyn_rl()
Definition: fereadl.c:754
fe_fgets_stdin_rl
char * fe_fgets_stdin_rl(const char *pr, char *s, int size)
fe_write_history
VAR int(* fe_write_history)()
Definition: feread.cc:172
x_rl_filename_completion_function
#define x_rl_filename_completion_function
fe_fgets
char * fe_fgets(const char *pr, char *s, int size)
Definition: feread.cc:310
x_rl_line_buffer
#define x_rl_line_buffer
STDIN_FILENO
#define STDIN_FILENO
Definition: fereadl.c:50
i
int i
Definition: cfEzgcd.cc:125
feread.h
res
CanonicalForm res
Definition: facAbsFact.cc:64
fe_using_history
VAR void(* fe_using_history)()
Definition: feread.cc:174
singular_completion
char ** singular_completion(char *text, int start, int end)
Definition: feread.cc:179
fe_rl_attempted_completion_function
VAR CPPFunction ** fe_rl_attempted_completion_function
Definition: feread.cc:170
malloc
void * malloc(size_t size)
Definition: omalloc.c:91
VAR
#define VAR
Definition: globaldefs.h:5
write_history
int write_history()
mod2.h
fe_fgets_stdin_init
static char * fe_fgets_stdin_init(const char *pr, char *s, int size)
Definition: feread.cc:345
size
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
free
#define free
Definition: omAllocFunc.c:13
rl_completion_matches
#define rl_completion_matches
Definition: feread.cc:124
RL_PROC
char *(* RL_PROC)(const char *, int)
Definition: feread.cc:108
fe_fgets_stdin_fe
char * fe_fgets_stdin_fe(const char *pr, char *s, int size)
fe_add_history
VAR void(* fe_add_history)(char *)
Definition: feread.cc:166
fe_fgets_stdin_drl
char * fe_fgets_stdin_drl(const char *pr, char *s, int size)
Definition: feread.cc:270
rl_attempted_completion_function
EXTERN_VAR CPPFunction * rl_attempted_completion_function
Definition: feread.cc:134
history_total_bytes
int history_total_bytes()
V_PROMPT
#define V_PROMPT
Definition: options.h:52
idrec
Definition: idrec.h:33
CPPFunction
char ** CPPFunction()
Definition: feread.cc:131
BVERBOSE
#define BVERBOSE(a)
Definition: options.h:33
fe_rl_line_buffer
VAR char ** fe_rl_line_buffer
Definition: feread.cc:168
x_rl_completion_matches
#define x_rl_completion_matches
iiArithGetCmd
char * iiArithGetCmd(int)
Definition: iparith.cc:9317
fe_fgets_stdin_emu
char * fe_fgets_stdin_emu(const char *pr, char *s, int size)
Definition: feread.cc:254
name
char name(const Variable &v)
Definition: factory.h:180
strdup
#define strdup
Definition: omAllocFunc.c:18
m
int m
Definition: cfEzgcd.cc:121
basePack
VAR package basePack
Definition: ipid.cc:57
NULL
#define NULL
Definition: omList.c:11
mflush
#define mflush()
Definition: reporter.h:56
l
int l
Definition: cfEzgcd.cc:93
Warn
#define Warn
Definition: emacs.cc:76
p
int p
Definition: cfModGcd.cc:4019
s
const CanonicalForm int s
Definition: facAbsFact.cc:55
command_generator
char * command_generator(char *text, int state)
Definition: feread.cc:54
rl_outstream
EXTERN_VAR FILE * rl_outstream
Definition: feread.cc:135
ipid.h
EXTERN_VAR
#define EXTERN_VAR
Definition: globaldefs.h:6
add_history
void add_history(char *)
rl_line_buffer
EXTERN_VAR char * rl_line_buffer
Definition: feread.cc:129