My Project
fevoices.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5 * ABSTRACT: i/o system
6 */
7 #include "kernel/mod2.h"
8 
9 /* I need myfread in standalone_parser */
10 #ifndef STANDALONE_PARSER
11 #include "omalloc/omalloc.h"
12 #include "misc/options.h"
13 #include "reporter/reporter.h"
15 #include "Singular/fevoices.h"
16 #include "Singular/subexpr.h"
17 #include "Singular/ipshell.h"
18 #include "Singular/sdb.h"
19 
20 #include "misc/mylimits.h"
21 #include <unistd.h>
22 
23 #ifdef HAVE_PWD_H
24 #include <pwd.h>
25 #endif
26 
27 #define fePutChar(c) fputc((unsigned char)(c),stdout)
28 /*0 implementation */
29 
30 
31 VAR char fe_promptstr[] =" ";
33 
34 // line buffer for reading:
35 // minimal value for MAX_FILE_BUFFER: 4*4096 - see Tst/Long/gcd0_l.tst
36 // this is an upper limit for the size of monomials/numbers read via the interpreter
37 #define MAX_FILE_BUFFER 4*4096
38 
39 /**************************************************************************
40 * handling of 'voices'
41 **************************************************************************/
42 
43 EXTERN_VAR int blocknest; /* scaner.l internal */
44 
45 VAR int yy_noeof=0; // the scanner "state"
46 VAR int yy_blocklineno; // to get the lineno of the block start from scanner
48 // FILE *feFilePending; /*temp. storage for grammar.y */
49 
50 //static const char * BT_name[]={"BT_none","BT_break","BT_proc","BT_example",
51 // "BT_file","BT_execute","BT_if","BT_else"};
52 /*2
53 * the name of the current 'Voice': the procname (or filename)
54 */
55 const char sNoName_fe[]="_";
56 const char * VoiceName()
57 {
58  if ((currentVoice!=NULL)
59  && (currentVoice->filename!=NULL))
60  return currentVoice->filename;
61  return sNoName_fe;
62 }
63 
64 int VoiceLine()
65 {
66  if ((currentVoice!=NULL)
67  && (currentVoice->curr_lineno>=0))
68  return currentVoice->curr_lineno;
69  return -1;
70 }
71 
72 /*2
73 * the calling chain of Voices
74 */
76 {
78  while (p->prev!=NULL)
79  {
80  p=p->prev;
81  char *s=p->filename;
82  if (s==NULL)
83  PrintS("-- called from ? --\n");
84  else
85  Print("-- called from %s --\n",s);
86  }
87 }
88 
89 /*2
90 * init a new voice similar to the current
91 */
93 {
94  Voice *p=new Voice;
95  // OB: ???
96  // Hmm... when Singular is used as batch file
97  // then this voice is never freed
99  if (currentVoice != NULL)
100  {
103  }
104  p->prev=currentVoice;
105  currentVoice=p;
106  //PrintS("Next:");
107 }
108 
110 {
111  switch(typ)
112  {
113  case BT_proc:
114  case BT_example:
115  case BT_file:
116  return typ;
117  default:
118  if (prev==NULL) return (feBufferTypes)0;
119  return prev->Typ();
120  }
121 }
122 
123 /*2
124 * start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
125 * return FALSE on success, TRUE if an error occurs (file cannot be opened)
126 */
127 BOOLEAN newFile(char *fname)
128 {
129  currentVoice->Next();
130  //Print(":File%d(%s):%s(%x)\n",
131  // currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
132  currentVoice->filename = omStrDup(fname);
134  if (strcmp(fname,"STDIN") == 0)
135  {
136  currentVoice->files = stdin;
139  }
140  else
141  {
142  currentVoice->sw = BI_file; /* needed by exitVoice below */
143  currentVoice->files = feFopen(fname,"r",NULL,TRUE);
144  if (currentVoice->files==NULL)
145  {
146  exitVoice();
147  return TRUE;
148  }
150  }
152  //Voice *p=currentVoice;
153  //PrintS("-----------------\ncurr:");
154  //do
155  //{
156  //Print("voice fn:%s\n",p->filename);
157  //p=p->prev;
158  //}
159  //while (p!=NULL);
160  //PrintS("----------------\n");
161  return FALSE;
162 }
163 
164 void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
165 {
166  currentVoice->Next();
167  //Print(":Buffer%d(%s):%s(%x)\n",
168  // t,BT_name[t],pname,currentVoice);
169  if (pi!=NULL)
170  {
171  long l=strlen(pi->procname);
172  if (pi->libname!=NULL) l+=strlen(pi->libname);
173  currentVoice->filename = (char *)omAlloc(l+3);
174  *currentVoice->filename='\0';
175  if (pi->libname!=NULL) strcat(currentVoice->filename,pi->libname);
176  strcat(currentVoice->filename,"::");
177  strcat(currentVoice->filename,pi->procname);
178  currentVoice->pi = pi;
179  }
180  else
181  {
182  if(currentVoice->prev!=NULL)
183  {
186  }
187  else
188  {
190  currentVoice->pi = pi;
191  }
192  }
193  currentVoice->buffer = s;
195  currentVoice->typ = t;
196  switch (t)
197  {
198  case BT_execute:
199  yylineno-=2;
200  break;
201  case BT_proc:
202  case BT_example:
204  yylineno = lineno+1;
205  break;
206  case BT_if:
207  case BT_else:
208  case BT_break:
210  break;
211  //case BT_file:
212  default:
213  yylineno = 1;
214  break;
215  }
216  //Print("start body (%s) at line %d\n",BT_name[t],yylineno);
218  //printf("start buffer typ %d\n",t);
219  //Voice *p=currentVoice;
220  //PrintS("-----------------\ncurr:");
221  //do
222  //{
223  //Print("voice fn:%s\n",p->filename);
224  //p=p->prev;
225  //}
226  //while (p!=NULL);
227  //PrintS("----------------\n");
228 }
229 
230 /*2
231 * exit Buffer of type 'typ':
232 * returns 1 if buffer type could not be found
233 */
235 {
236  //printf("exitBuffer: %d(%s),(%x)\n",
237  // typ,BT_name[typ], currentVoice);
238  //Voice *p=currentVoice;
239  //PrintS("-----------------\ncurr:");
240  //do
241  //{
242  //Print("voice fn:%s\n",p->filename);
243  //p=p->prev;
244  //}
245  //while (p!=NULL);
246  //PrintS("----------------\n");
247  if (typ == BT_break) // valid inside for, while. may skip if, else
248  {
249  /*4 first check for valid buffer type, skip if/else*/
251  loop
252  {
253  if ((p->typ != BT_if)
254  &&(p->typ != BT_else))
255  {
256  if (p->typ == BT_break /*typ*/)
257  {
258  while (p != currentVoice)
259  {
260  exitVoice();
261  }
262  exitVoice();
263  return FALSE;
264  }
265  else return TRUE;
266  }
267  if (p->prev==NULL) break;
268  p=p->prev;
269  }
270  /*4 break not inside a for/while: return an error*/
271  if (/*typ*/ BT_break != currentVoice->typ) return 1;
272  return exitVoice();
273  }
274 
275  if ((typ == BT_proc)
276  || (typ == BT_example))
277  {
279  loop
280  {
281  if ((p->typ == BT_proc)
282  || (p->typ == BT_example))
283  {
284  while (p != currentVoice)
285  {
286  exitVoice();
287  }
288  exitVoice();
289  return FALSE;
290  }
291  if (p->prev==NULL) break;
292  p=p->prev;
293  }
294  }
295  /*4 return not inside a proc: return an error*/
296  return TRUE;
297 }
298 
299 /*2
300 * jump to the beginning of a buffer
301 */
303 {
304  //printf("contBuffer: %d(%s),(%x)\n",
305  // typ,BT_name[typ], currentVoice);
306  if (typ == BT_break) // valid inside for, while. may skip if, else
307  {
308  // first check for valid buffer type
310  loop
311  {
312  if ((p->typ != BT_if)
313  &&(p->typ != BT_else))
314  {
315  if (p->typ == BT_break /*typ*/)
316  {
317  while (p != currentVoice)
318  {
319  exitVoice();
320  }
322  currentVoice->fptr=0;
323  return FALSE;
324  }
325  else return TRUE;
326  }
327  if (p->prev==NULL) break;
328  p=p->prev;
329  }
330  }
331  return TRUE;
332 }
333 
334 /*2
335 * leave a voice: kill local variables
336 * setup everything from the previous level
337 * return 1 if leaving the top level, 0 otherwise
338 */
340 {
341  //printf("exitVoice: %d(%s),(%x)\n",
342  // currentVoice->typ,BT_name[currentVoice->typ], currentVoice);
343  //{
344  //Voice *p=currentVoice;
345  //PrintS("-----------------\ncurr:");
346  //do
347  //{
348  //Print("voice fn:%s\n",p->filename);
349  //p=p->prev;
350  //}
351  //while (p!=NULL);
352  //PrintS("----------------\n");
353  //}
354  if (currentVoice!=NULL)
355  {
356  if (currentVoice->oldb!=NULL)
357  {
360  }
361  if (currentVoice->filename!=NULL)
362  {
365  }
366  if (currentVoice->buffer!=NULL)
367  {
370  }
371  if ((currentVoice->prev==NULL)
372  &&(currentVoice->sw==BI_file)
373  &&(currentVoice->files!=stdin))
374  {
376  }
377  if (currentVoice->prev!=NULL)
378  {
379  //printf("exitVoice typ %d(%s)\n",
380  // currentVoice->typ,BT_name[currentVoice->typ]);
381  if (currentVoice->typ==BT_if)
382  {
383  currentVoice->prev->ifsw=2;
384  }
385  else
386  {
387  currentVoice->prev->ifsw=0;
388  }
389  if ((currentVoice->sw == BI_file)
390  && (currentVoice->files!=NULL))
391  {
392  fclose(currentVoice->files);
393  }
396  }
398  delete currentVoice;
399  currentVoice=p;
400  }
401  return currentVoice==NULL;
402 }
403 
404 /*2
405 * set prompt_char
406 * only called with currentVoice->sw == BI_stdin
407 */
408 static void feShowPrompt(void)
409 {
411 }
412 
413 /*2
414 * print echo (si_echo or TRACE), set my_yylinebuf
415 */
416 static int fePrintEcho(char *anf, char */*b*/)
417 {
418  char *ss=strrchr(anf,'\n');
419  int len_s;
420  if (ss==NULL)
421  {
422  len_s=strlen(anf);
423  }
424  else
425  {
426  len_s=ss-anf+1;
427  }
428  // my_yylinebuf:
429  int mrc=si_min(len_s,79)-1;
430  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
431  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
432  mrc--;
433  // handle echo:
434  if (((si_echo>myynest)
435  && ((currentVoice->typ==BT_proc)
437  || (currentVoice->typ==BT_file)
438  || (currentVoice->typ==BT_none)
439  )
440  && (strncmp(anf,";return();",10)!=0)
441  )
444  {
446  {
447  if (currentVoice->filename==NULL)
448  Print("(none) %3d%c ",yylineno,prompt_char);
449  else
451  }
452  {
453  fwrite(anf,1,len_s,stdout);
454  mflush();
455  }
457  {
458  char c;
459  do
460  {
461  c=fgetc(stdin);
462  if (c=='n') traceit_stop=1;
463  }
464  while(c!='\n');
465  }
466  }
467  else if (traceit&TRACE_SHOW_LINENO)
468  {
469  Print("{%d}",yylineno);
470  mflush();
471  }
472  else if (traceit&TRACE_PROFILING)
473  {
474  if (File_Profiling==NULL)
475  File_Profiling=fopen("smon.out","a");
476  if (File_Profiling==NULL)
477  traceit &= (~TRACE_PROFILING);
478  else
479  {
480  if (currentVoice->filename==NULL)
481  fprintf(File_Profiling,"(none) %d\n",yylineno);
482  else
483  fprintf(File_Profiling,"%s %d\n",currentVoice->filename,yylineno);
484  }
485  }
486 #ifdef HAVE_SDB
487  if ((blocknest==0)
488  && (currentVoice->pi!=NULL)
489  && (currentVoice->pi->trace_flag!=0))
490  {
491  sdb(currentVoice, anf, len_s);
492  }
493 #endif
494  prompt_char = '.';
495  return len_s;
496 }
497 
498 int feReadLine(char* b, int l)
499 {
500  char *s=NULL;
501  int offset = 0; /* will not be used if s==NULL*/
502  // try to read from the buffer into b, max l chars
503  if (currentVoice!=NULL)
504  {
505  if((currentVoice->buffer!=NULL)
506  && (currentVoice->buffer[currentVoice->fptr]!='\0'))
507  {
508  NewBuff:
509  REGISTER int i=0;
510  long startfptr=currentVoice->fptr;
511  long tmp_ptr=currentVoice->fptr;
512  l--;
513  loop
514  {
515  REGISTER char c=
516  b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
517  i++;
518  if (yy_noeof==noeof_block)
519  {
520  if (c<' ') yylineno++;
521  else if (c=='}') break;
522  }
523  else
524  {
525  if ((c<' ') ||
526  (c==';') ||
527  (c==')')
528  )
529  break;
530  }
531  if (i>=l) break;
532  tmp_ptr++;/*currentVoice->fptr++;*/
533  if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
534  }
535  currentVoice->fptr=tmp_ptr;
536  b[i]='\0';
537  if (currentVoice->sw==BI_buffer)
538  {
539  BOOLEAN show_echo=FALSE;
540  char *anf;
541  long len;
542  if (startfptr==0)
543  {
544  anf=currentVoice->buffer;
545  const char *ss=strchr(anf,'\n');
546  if (ss==NULL) len=strlen(anf);
547  else len=ss-anf;
548  show_echo=TRUE;
549  }
550  else if (/*(startfptr>0) &&*/
551  (currentVoice->buffer[startfptr-1]=='\n'))
552  {
553  anf=currentVoice->buffer+startfptr;
554  const char *ss=strchr(anf,'\n');
555  if (ss==NULL) len=strlen(anf);
556  else len=ss-anf;
557  yylineno++;
558  show_echo=TRUE;
559  }
560  if (show_echo)
561  {
562  char *s=(char *)omAlloc(len+2);
563  strncpy(s,anf,len+2);
564  s[len+1]='\0';
565  fePrintEcho(s,b);
566  omFree((ADDRESS)s);
567  }
568  }
569  currentVoice->fptr++;
570  return i;
571  }
572  // no buffer there or e-o-buffer or eoln:
573  if (currentVoice->sw!=BI_buffer)
574  {
575  currentVoice->fptr=0;
576  if (currentVoice->buffer==NULL)
577  {
581  }
582  }
583  offset=0;
584  NewRead:
585  yylineno++;
586  if (currentVoice->sw==BI_stdin)
587  {
588  feShowPrompt();
592  //int i=0;
593  //if (s!=NULL)
594  // while((s[i]!='\0') /*&& (i<MAX_FILE_BUFFER)*/) {s[i] &= (char)127;i++;}
595  }
596  else if (currentVoice->sw==BI_file)
597  {
601  if (s!=NULL)
602  {
604  // ftell returns -1 for non-seekable streams, such as pipes
605  if (currentVoice->ftellptr<0)
607  }
608  }
609  //else /* BI_buffer */ s==NULL => return 0
610  // done by the default return
611  }
612  if (s!=NULL)
613  {
614  // handle prot:
615  if (feProt&SI_PROT_I)
616  {
617  fputs(s,feProtFile);
618  }
619  int rc=fePrintEcho(s,b)+1;
620  //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
621  s[rc]='\0';
622  // handel \\ :
623  rc-=3; if (rc<0) rc=0;
624  if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
625  {
626  s[rc]='\0';
627  offset+=rc;
628  if (offset<currentVoice->buff_size) goto NewRead;
629  }
630  goto NewBuff;
631  }
632  /* else if (s==NULL) */
633  {
634  const char *err;
635  switch(yy_noeof)
636  {
637  case noeof_brace:
638  case noeof_block:
639  err="{...}";
640  break;
641  case noeof_asstring:
642  err="till `.`";
643  break;
644  case noeof_string:
645  err="string";
646  break;
647  case noeof_bracket:
648  err="(...)";
649  break;
650  case noeof_procname:
651  err="proc";
652  break;
653  case noeof_comment:
654  err="/*...*/";
655  break;
656  default:
657  return 0;
658  }
659  Werror("premature end of file while reading %s",err);
660  return 0;
661  }
662 }
663 
664 /*2
665 * init all data structures
666 */
667 #ifndef STDIN_FILENO
668 #define STDIN_FILENO 0
669 #endif
671 {
672  Voice *p = new Voice;
673  p->files = stdin;
674  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
675  if ((pp!=NULL) && (pp->sw==BI_stdin) && (pp->files==stdin))
676  {
677  p->files=freopen("/dev/tty","r",stdin);
678  //stdin=p->files;
679  if (p->files==NULL)
680  {
681  p->files = stdin;
682  p->sw = BI_file;
683  }
684  else
685  p->sw = BI_stdin;
686  }
687  p->filename = omStrDup("STDIN");
688  p->start_lineno = 1;
690  omMarkAsStaticAddr(p->filename);
691  return p;
692 }
693 #endif
694 
int BOOLEAN
Definition: auxiliary.h:87
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
void * ADDRESS
Definition: auxiliary.h:119
static int si_min(const int a, const int b)
Definition: auxiliary.h:125
CanonicalForm FACTORY_PUBLIC pp(const CanonicalForm &)
CanonicalForm pp ( const CanonicalForm & f )
Definition: cf_gcd.cc:676
int l
Definition: cfEzgcd.cc:100
int i
Definition: cfEzgcd.cc:132
int p
Definition: cfModGcd.cc:4078
CanonicalForm b
Definition: cfModGcd.cc:4103
Definition: fevoices.h:59
int curr_lineno
Definition: fevoices.h:76
Voice * next
Definition: fevoices.h:61
FILE * files
Definition: fevoices.h:67
Voice()
Definition: fevoices.h:87
char * buffer
Definition: fevoices.h:69
void Next()
Definition: fevoices.cc:92
feBufferTypes Typ()
Definition: fevoices.cc:109
long ftellptr
Definition: fevoices.h:71
char ifsw
Definition: fevoices.h:80
int start_lineno
Definition: fevoices.h:75
procinfo * pi
Definition: fevoices.h:64
int buff_size
Definition: fevoices.h:73
char * filename
Definition: fevoices.h:63
feBufferInputs sw
Definition: fevoices.h:77
void * oldb
Definition: fevoices.h:65
Voice * prev
Definition: fevoices.h:62
feBufferTypes typ
Definition: fevoices.h:85
long fptr
Definition: fevoices.h:70
#define Print
Definition: emacs.cc:80
const CanonicalForm int s
Definition: facAbsFact.cc:51
FILE * feFopen(const char *path, const char *mode, char *where, short useWerror, short path_only)
Definition: feFopen.cc:47
VAR int yylineno
Definition: febase.cc:40
VAR char my_yylinebuf[80]
Definition: febase.cc:44
VAR int si_echo
Definition: febase.cc:35
VAR int myynest
Definition: febase.cc:41
char *(* fe_fgets_stdin)(const char *pr, char *s, int size)
Definition: feread.cc:32
EXTERN_VAR char prompt_char
Definition: feread.h:10
#define MAX_FILE_BUFFER
Definition: fevoices.cc:37
VAR FILE * File_Profiling
Definition: fevoices.cc:32
EXTERN_VAR int blocknest
Definition: fevoices.cc:43
VAR char fe_promptstr[]
Definition: fevoices.cc:31
BOOLEAN exitBuffer(feBufferTypes typ)
Definition: fevoices.cc:234
void newBuffer(char *s, feBufferTypes t, procinfo *pi, int lineno)
Definition: fevoices.cc:164
BOOLEAN contBuffer(feBufferTypes typ)
Definition: fevoices.cc:302
int feReadLine(char *b, int l)
Definition: fevoices.cc:498
VAR Voice * currentVoice
Definition: fevoices.cc:47
const char * VoiceName()
Definition: fevoices.cc:56
VAR int yy_blocklineno
Definition: fevoices.cc:46
const char sNoName_fe[]
Definition: fevoices.cc:55
void VoiceBackTrack()
Definition: fevoices.cc:75
static int fePrintEcho(char *anf, char *)
Definition: fevoices.cc:416
BOOLEAN newFile(char *fname)
Definition: fevoices.cc:127
VAR int yy_noeof
Definition: fevoices.cc:45
Voice * feInitStdin(Voice *pp)
Definition: fevoices.cc:670
static void feShowPrompt(void)
Definition: fevoices.cc:408
int VoiceLine()
Definition: fevoices.cc:64
BOOLEAN exitVoice()
Definition: fevoices.cc:339
#define STDIN_FILENO
Definition: fevoices.cc:668
@ BI_file
Definition: fevoices.h:32
@ BI_buffer
Definition: fevoices.h:31
@ BI_stdin
Definition: fevoices.h:30
void myyoldbuffer(void *oldb)
Definition: scanner.cc:2304
@ noeof_string
Definition: fevoices.h:42
@ noeof_brace
Definition: fevoices.h:36
@ noeof_comment
Definition: fevoices.h:40
@ noeof_asstring
Definition: fevoices.h:37
@ noeof_block
Definition: fevoices.h:38
@ noeof_procname
Definition: fevoices.h:41
@ noeof_bracket
Definition: fevoices.h:39
feBufferTypes
Definition: fevoices.h:17
@ BT_none
Definition: fevoices.h:18
@ BT_else
Definition: fevoices.h:25
@ BT_if
Definition: fevoices.h:24
@ BT_break
Definition: fevoices.h:19
@ BT_example
Definition: fevoices.h:21
@ BT_execute
Definition: fevoices.h:23
@ BT_proc
Definition: fevoices.h:20
@ BT_file
Definition: fevoices.h:22
void * myynewbuffer()
Definition: scanner.cc:2297
#define EXTERN_VAR
Definition: globaldefs.h:6
#define VAR
Definition: globaldefs.h:5
STATIC_VAR int offset
Definition: janet.cc:29
#define pi
Definition: libparse.cc:1145
#define SEEK_SET
Definition: mod2.h:113
#define omStrDup(s)
Definition: omAllocDecl.h:263
#define omAlloc(size)
Definition: omAllocDecl.h:210
#define omFree(addr)
Definition: omAllocDecl.h:261
void omMarkAsStaticAddr(void *addr)
#define NULL
Definition: omList.c:12
#define REGISTER
Definition: omalloc.h:27
void PrintS(const char *s)
Definition: reporter.cc:284
VAR int feProt
Definition: reporter.cc:56
VAR FILE * feProtFile
Definition: reporter.cc:57
void Werror(const char *fmt,...)
Definition: reporter.cc:189
#define TRACE_SHOW_LINENO
Definition: reporter.h:31
#define TRACE_SHOW_LINE
Definition: reporter.h:33
EXTERN_VAR int traceit
Definition: reporter.h:24
EXTERN_VAR int traceit_stop
Definition: reporter.h:25
#define TRACE_SHOW_LINE1
Definition: reporter.h:38
#define SI_PROT_I
Definition: reporter.h:53
#define TRACE_PROFILING
Definition: reporter.h:50
#define mflush()
Definition: reporter.h:58
void sdb(Voice *currentVoice, const char *currLine, int len)
Definition: sdb.cc:200
#define loop
Definition: structs.h:75
char trace_flag
Definition: subexpr.h:62