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