source: git/kernel/feread.cc @ b1c0a9

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