source: git/kernel/feread.cc @ cbeafc2

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