source: git/Singular/feread.cc @ 5ca9807

spielwiese
Last change on this file since 5ca9807 was bd5917, checked in by Hans Schönemann <hannes@…>, 22 years ago
*hannes: MAC-Port git-svn-id: file:///usr/local/Singular/svn/trunk@5857 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: feread.cc,v 1.44 2002-02-12 12:31:39 Singular Exp $ */
5/*
6* ABSTRACT: input from ttys, simulating fgets
7*/
8
9#include "mod2.h"
10#ifdef ix86_Win
11#define READLINE_STATIC
12#endif
13#include "tok.h"
14#include "febase.h"
15#ifdef ix86_Win
16#define OM_NO_MALLOC_MACROS
17#endif
18#ifdef PowerMacintosh_darwin
19#define OM_NO_MALLOC_MACROS
20#endif
21#include "omalloc.h"
22
23#include "static.h"
24
25#ifdef HAVE_STATIC
26#undef HAVE_DYN_RL
27#endif
28
29#ifdef HAVE_TCL
30#include "ipid.h"
31#endif
32
33static char * fe_fgets_stdin_init(char *pr,char *s, int size);
34char * (*fe_fgets_stdin)(char *pr,char *s, int size)
35 = fe_fgets_stdin_init;
36
37/* ===================================================================*/
38/* =                   static/dymanic readline                      = */
39/* ===================================================================*/
40#if defined(HAVE_READLINE) || defined(HAVE_DYN_RL)
41
42#include "ipshell.h"
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*/
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 = cmds[list_index].name)!=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_FEREAD)
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 #ifdef READLINE_READLINE_H_OK
97  #include <readline/readline.h>
98  #ifdef HAVE_READLINE_HISTORY_H
99   #include <readline/history.h>
100  #endif
101 #else /* declare everything we need explicitely and do not rely on includes */
102  extern char * rl_readline_name;
103  extern char *rl_line_buffer;
104  char *filename_completion_function();
105  typedef char **CPPFunction ();
106  extern char ** completion_matches ();
107  extern CPPFunction * rl_attempted_completion_function;
108  extern FILE * rl_outstream;
109  extern char * readline ();
110  extern void add_history ();
111  extern int write_history ();
112  extern void using_history();
113  extern int read_history();
114  extern int history_total_bytes();
115 #endif /* READLINE_READLINE_H_OK */
116 typedef char * (*PROC)();
117}
118
119
120char * fe_fgets_stdin_rl(char *pr,char *s, int size);
121
122/* Tell the GNU Readline library how to complete.  We want to try to complete
123   on command names  or on filenames if it is preceded by " */
124
125/* Attempt to complete on the contents of TEXT.  START and END show the
126*   region of TEXT that contains the word to complete.  We can use the
127*   entire line in case we want to do some simple parsing.  Return the
128*   array of matches, or NULL if there aren't any.
129*/
130char ** singular_completion (char *text, int start, int end)
131{
132  /* If this word is not in a string, then it may be a command
133     to complete.  Otherwise it may be the name of a file in the current
134     directory. */
135  if (rl_line_buffer[start-1]=='"')
136    return completion_matches (text, (PROC)filename_completion_function);
137  char **m=completion_matches (text, (PROC)command_generator);
138  if (m==NULL)
139  {
140    m=(char **)malloc(2*sizeof(char*));
141    m[0]=(char *)malloc(end-start+2);
142    strncpy(m[0],text,end-start+1);
143    m[1]=NULL;
144  }
145  return m;
146}
147
148char * fe_fgets_stdin_rl(char *pr,char *s, int size)
149{
150  if (!BVERBOSE(V_PROMPT))
151  {
152    pr="";
153  }
154  mflush();
155
156  char *line;
157  line = readline (pr);
158
159  if (line==NULL)
160    return NULL;
161
162  if (*line!='\0')
163  {
164    add_history (line);
165  }
166  int l=strlen(line);
167  if (l>=size-1)
168  {
169    strncpy(s,line,size);
170  }
171  else
172  {
173    strncpy(s,line,l);
174    s[l]='\n';
175    s[l+1]='\0';
176  }
177  free (line);
178
179  return s;
180}
181#endif
182
183/* ===================================================================*/
184/* =                    emulated readline                           = */
185/* ===================================================================*/
186#if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
187extern "C" {
188char * fe_fgets_stdin_fe(char *pr,char *s, int size);
189}
190char * fe_fgets_stdin_emu(char *pr,char *s, int size)
191{
192  if (!BVERBOSE(V_PROMPT))
193  {
194    pr="";
195  }
196  mflush();
197  return fe_fgets_stdin_fe(pr,s,size);
198}
199#endif
200
201/* ===================================================================*/
202/* =                     dynamic readline                           = */
203/* ===================================================================*/
204/* some procedure are shared with "static readline" */
205
206#if defined(HAVE_DYN_RL)
207#include <unistd.h>
208//#include <stdio.h>
209//#include <stdlib.h>
210//#include <sys/types.h>
211//#include <sys/file.h>
212//#include <sys/stat.h>
213//#include <sys/errno.h>
214//#include <dlfcn.h>
215#include "mod_raw.h"
216
217extern "C" {
218  typedef char* (*String_Func)();
219  typedef void  (*Void_Func)();
220  typedef int  (*Int_Func)();
221  typedef char** (*CharStarStar_Func)();
222  char *(*fe_filename_completion_function)(); /* 3 */
223  char *(* fe_readline) ();                   /* 4 */
224  void (*fe_add_history) ();                  /* 5 */
225  char ** fe_rl_readline_name;                /* 6 */
226  char **fe_rl_line_buffer;                   /* 7 */
227  char **(*fe_completion_matches)();          /* 8 */
228  typedef char **CPPFunction ();
229  CPPFunction **fe_rl_attempted_completion_function; /* 9 */
230  FILE ** fe_rl_outstream;                    /* 10 */
231  int (*fe_write_history) ();                 /* 11 */
232  int (*fe_history_total_bytes) ();           /* 12 */
233  void (*fe_using_history) ();                /* 13 */
234  int (*fe_read_history) ();                  /* 14 */
235}
236
237void * fe_rl_hdl=NULL;
238
239char * fe_fgets_stdin_rl(char *pr,char *s, int size);
240static int fe_init_dyn_rl()
241{
242  int res=0;
243  loop
244  {
245    #if defined(HPUX_9) || defined(HPUX_10)
246    fe_rl_hdl=dynl_open("libreadline.sl");
247    if (fe_rl_hdl==NULL)
248      fe_rl_hdl=dynl_open("/lib/libreadline.sl");
249    if (fe_rl_hdl==NULL)
250      fe_rl_hdl=dynl_open("/usr/lib/libreadline.sl");
251    #else
252    fe_rl_hdl=dynl_open("libreadline.so");
253    #endif
254    if (fe_rl_hdl==NULL) { return 1;}
255
256    fe_filename_completion_function= (String_Func)
257      dynl_sym(fe_rl_hdl, "filename_completion_function");
258    if (fe_filename_completion_function==NULL) { res=3; break; }
259    fe_readline=(String_Func)dynl_sym(fe_rl_hdl,"readline");
260    if (fe_readline==NULL) { res=4; break; }
261    fe_add_history=(Void_Func)dynl_sym(fe_rl_hdl,"add_history");
262    if (fe_add_history==NULL) { res=5; break; }
263    fe_rl_readline_name=(char**)dynl_sym(fe_rl_hdl,"rl_readline_name");
264    if (fe_rl_readline_name==NULL) { res=6; break; }
265    fe_rl_line_buffer=(char**)dynl_sym(fe_rl_hdl,"rl_line_buffer");
266    if (fe_rl_line_buffer==NULL) { res=7; break; }
267    fe_completion_matches=(CharStarStar_Func)dynl_sym(fe_rl_hdl,"completion_matches");
268    if (fe_completion_matches==NULL) { res=8; break; }
269    fe_rl_attempted_completion_function=
270      (CPPFunction**) dynl_sym(fe_rl_hdl,"rl_attempted_completion_function");
271    if (fe_rl_attempted_completion_function==NULL) { res=9; break; }
272    fe_rl_outstream=(FILE**)dynl_sym(fe_rl_hdl,"rl_outstream");
273    if (fe_rl_outstream==NULL) { res=10; break; }
274    fe_write_history=(Int_Func)dynl_sym(fe_rl_hdl,"write_history");
275    if (fe_write_history==NULL) { res=11; break; }
276    fe_history_total_bytes=(Int_Func)dynl_sym(fe_rl_hdl,"history_total_bytes");
277    if (fe_history_total_bytes==NULL) { res=12; break; }
278    fe_using_history=(Void_Func)dynl_sym(fe_rl_hdl,"using_history");
279    if (fe_using_history==NULL) { res=13; break; }
280    fe_read_history=(Int_Func)dynl_sym(fe_rl_hdl,"read_history");
281    if (fe_read_history==NULL) { res=14; break; }
282    return 0;
283  }
284  dynl_close(fe_rl_hdl);
285  return res;
286}
287
288/* Attempt to complete on the contents of TEXT.  START and END show the
289*   region of TEXT that contains the word to complete.  We can use the
290*   entire line in case we want to do some simple parsing.  Return the
291*   array of matches, or NULL if there aren't any.
292*/
293char ** singular_completion (char *text, int start, int end)
294{
295  /* If this word is not in a string, then it may be a command
296     to complete.  Otherwise it may be the name of a file in the current
297     directory. */
298  if ((*fe_rl_line_buffer)[start-1]=='"')
299    return (*fe_completion_matches) (text, *fe_filename_completion_function);
300  char **m=(*fe_completion_matches) (text, command_generator);
301  if (m==NULL)
302  {
303    m=(char **)malloc(2*sizeof(char*));
304    m[0]=(char *)malloc(end-start+2);
305    strncpy(m[0],text,end-start+1);
306    m[1]=NULL;
307  }
308  return m;
309}
310
311char * fe_fgets_stdin_drl(char *pr,char *s, int size)
312{
313  if (!BVERBOSE(V_PROMPT))
314  {
315    pr="";
316  }
317  mflush();
318
319  char *line;
320  line = (*fe_readline) (pr);
321
322  if (line==NULL)
323    return NULL;
324
325  if (*line!='\0')
326  {
327    (*fe_add_history) (line);
328  }
329  int l=strlen(line);
330  if (l>=size-1)
331  {
332    strncpy(s,line,size);
333  }
334  else
335  {
336    strncpy(s,line,l);
337    s[l]='\n';
338    s[l+1]='\0';
339  }
340  free (line);
341
342  return s;
343}
344#endif
345
346/* ===================================================================*/
347/* =                        fgets                                   = */
348/* ===================================================================*/
349char * fe_fgets(char *pr,char *s, int size)
350{
351  if (BVERBOSE(V_PROMPT))
352  {
353    fprintf(stdout,pr);
354  }
355  mflush();
356  return fgets(s,size,stdin);
357}
358
359/* ===================================================================*/
360/* =       init for static rl, dyn. rl, emu. rl                     = */
361/* ===================================================================*/
362static char * fe_fgets_stdin_init(char *pr,char *s, int size)
363{
364#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD)
365  /* Allow conditional parsing of the ~/.inputrc file. */
366  rl_readline_name = "Singular";
367  /* Tell the completer that we want a crack first. */
368  rl_attempted_completion_function = (CPPFunction *)singular_completion;
369
370  /* set the output stream */
371  if(!isatty(STDOUT_FILENO))
372  {
373    #ifdef atarist
374      rl_outstream = fopen( "/dev/tty", "w" );
375    #else
376      rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
377    #endif
378  }
379
380  /* try to read a history */
381  using_history();
382  char *p = getenv("SINGULARHIST");
383  if (p != NULL)
384  {
385    read_history (p);
386  }
387  fe_fgets_stdin=fe_fgets_stdin_rl;
388  return(fe_fgets_stdin_rl(pr,s,size));
389#endif
390#ifdef HAVE_DYN_RL
391  /* do dynamic loading */
392  int res=fe_init_dyn_rl();
393  if (res!=0)
394  {
395    //if (res==1)
396    //  WarnS("dynamic loading of libreadline failed");
397    //else
398    //  Warn("dynamic loading failed: %d\n",res);
399    if (res!=1)
400      Warn("dynamic loading failed: %d\n",res);
401    fe_fgets_stdin=fe_fgets_stdin_emu;
402    return fe_fgets_stdin_emu(pr,s,size);
403  }
404  /* Allow conditional parsing of the ~/.inputrc file. */
405  (*fe_rl_readline_name) = "Singular";
406  /* Tell the completer that we want a crack first. */
407  (*fe_rl_attempted_completion_function) = (CPPFunction *)singular_completion;
408
409  /* set the output stream */
410  if(!isatty(STDOUT_FILENO))
411  {
412    #ifdef atarist
413      *fe_rl_outstream = fopen( "/dev/tty", "w" );
414    #else
415      *fe_rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
416    #endif
417  }
418
419  /* try to read a history */
420  (*fe_using_history)();
421  char *p = getenv("SINGULARHIST");
422  if (p != NULL)
423  {
424    (*fe_read_history) (p);
425  }
426  fe_fgets_stdin=fe_fgets_stdin_drl;
427  return fe_fgets_stdin_drl(pr,s,size);
428#else
429  #if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
430    fe_fgets_stdin=fe_fgets_stdin_emu;
431    return(fe_fgets_stdin_emu(pr,s,size));
432  #else
433    fe_fgets_stdin=fe_fgets;
434    return(fe_fgets(pr,s,size));
435  #endif
436#endif
437}
438
439/* ===================================================================*/
440/* =                          TCL                                   = */
441/* ===================================================================*/
442#ifdef HAVE_TCL
443/* tcl: */
444char * fe_fgets_tcl(char *pr,char *s, int size)
445{
446  if(currRing!=NULL) PrintTCLS('P',pr);
447  else               PrintTCLS('U',pr);
448  mflush();
449  return fgets(s,size,stdin);
450}
451
452#endif
453
454/* ===================================================================*/
455/* =                      batch mode                                = */
456/* ===================================================================*/
457/* dummy (for batch mode): */
458char * fe_fgets_dummy(char *pr,char *s, int size)
459{
460  return NULL;
461}
462
463/* ===================================================================*/
464/* =          fe_reset_input_mode (all possibilities)               = */
465/* ===================================================================*/
466void fe_reset_input_mode ()
467{
468#if defined(HAVE_DYN_RL)
469  char *p = getenv("SINGULARHIST");
470  if ((p != NULL) && (fe_history_total_bytes != NULL))
471  {
472    if((*fe_history_total_bytes)()!=0)
473      (*fe_write_history) (p);
474  }
475#endif
476#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD) && !defined(HAVE_DYN_RL)
477  char *p = getenv("SINGULARHIST");
478  if (p != NULL)
479  {
480    if(history_total_bytes()!=0)
481      write_history (p);
482  }
483#endif
484#if !defined(MSDOS) && (defined(HAVE_FEREAD) || defined(HAVE_DYN_RL))
485  #ifndef HAVE_ATEXIT
486  fe_reset_fe(NULL,NULL);
487  #else
488  fe_reset_fe();
489  #endif
490#endif
491}
Note: See TracBrowser for help on using the repository browser.