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