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