source: git/kernel/feread.cc @ 788529d

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