source: git/Singular/febase.inc @ 48aa42

spielwiese
Last change on this file since 48aa42 was ec7aac, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* replaced prProcs by fast poly procs * fixed various memory leaks * added dError stuff git-svn-id: file:///usr/local/Singular/svn/trunk@4565 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.2 KB
Line 
1/* -*-c++-*- */
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5/* $Id: febase.inc,v 1.32 2000-09-04 13:38:57 obachman Exp $ */
6/*
7* ABSTRACT: handling of 'voices'
8*/
9#include <ctype.h>
10#include "sdb.h"
11
12extern int blocknest; /* scaner.l internal */
13
14int    yy_noeof=0;     // the scanner "state"
15int    yy_blocklineno; // to get the lineno of the block start from scanner
16Voice  *currentVoice = NULL;
17FILE   *feFilePending; /*temp. storage for grammar.y */
18
19static char * BT_name[]={"BT_none","BT_break","BT_proc","BT_example",
20                       "BT_file","BT_execute","BT_if","BT_else"};
21/*2
22* the name of the current 'Voice': the procname (or filename)
23*/
24const char * VoiceName()
25{
26  if ((currentVoice!=NULL)
27  && (currentVoice->filename!=NULL))
28    return currentVoice->filename;
29  return sNoName;
30}
31
32/*2
33* the calling chain of Voices
34*/
35void VoiceBackTrack()
36{
37  Voice *p=currentVoice;
38  while (p->prev!=NULL)
39  {
40    p=p->prev;
41    char *s=p->filename;
42    if (s==NULL)
43      PrintS("-- called from ? --\n");
44    else
45      Print("-- called from %s --\n",s);
46  }
47}
48
49/*2
50* init a new voice similiar to the current
51*/
52void Voice::Next()
53{
54  Voice *p=new Voice;
55  // OB: ???
56  // Hmm... when Singular is used as batch file
57  // then this voice is never freed
58  omMarkAsStaticAddr(p);
59  if (currentVoice != NULL)
60  {
61    currentVoice->curr_lineno=yylineno;
62    currentVoice->next=p;
63  }
64  p->prev=currentVoice;
65  currentVoice=p;
66  //Print("Next:");
67}
68
69feBufferTypes Voice::Typ()
70{
71  switch(typ)
72  {
73    case BT_proc:
74    case BT_example:
75    case BT_file:
76      return typ;
77    default:
78      if (prev==NULL) return (feBufferTypes)0;
79      return prev->Typ();
80  }
81}
82
83/*2
84* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
85* return FALSE on success, TRUE if an error occurs (file cannot be opened)
86*/
87BOOLEAN newFile(char *fname,FILE* f)
88{
89  currentVoice->Next();
90  //Print(":File%d(%s):%s(%x)\n",
91  //  currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
92  currentVoice->filename   = omStrDup(fname);
93  omMarkAsStaticAddr(currentVoice->filename);
94  if (strcmp(fname,"STDIN") == 0)
95  {
96    currentVoice->files = stdin;
97    currentVoice->sw = BI_stdin;
98    currentVoice->start_lineno = 1;
99  }
100  else
101  {
102    currentVoice->sw = BI_file; /* needed by exitVoice below */
103    if (f!=NULL)
104      currentVoice->files = f;
105    else
106    {
107      currentVoice->files = feFopen(fname,"r",NULL,TRUE);
108      if (currentVoice->files==NULL)
109      {
110        exitVoice();
111        return TRUE;
112      }
113    }
114    currentVoice->start_lineno = 0;
115  }
116  yylineno=currentVoice->start_lineno;
117  //Voice *p=currentVoice;
118  //Print("-----------------\ncurr:");
119  //do
120  //{
121  //Print("voice fn:%s\n",p->filename);
122  //p=p->prev;
123  //}
124  //while (p!=NULL);
125  //Print("----------------\n");
126  return FALSE;
127}
128
129void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
130{
131  currentVoice->Next();
132  //Print(":Buffer%d(%s):%s(%x)\n",
133  //  t,BT_name[t],pname,currentVoice);
134  if (pi!=NULL)
135  {
136    int l=strlen(pi->procname);
137    if (pi->libname!=NULL) l+=strlen(pi->libname);
138    currentVoice->filename = (char *)omAlloc(l+3);
139    *currentVoice->filename='\0';
140    if (pi->libname!=NULL) strcat(currentVoice->filename,pi->libname);
141    strcat(currentVoice->filename,"::");
142    strcat(currentVoice->filename,pi->procname);
143    currentVoice->pi       = pi;
144  }
145  else
146  {
147    currentVoice->filename = omStrDup(currentVoice->prev->filename);
148    currentVoice->pi       = currentVoice->prev->pi;
149  }
150  currentVoice->buffer   = s;
151  currentVoice->sw       = BI_buffer;
152  currentVoice->typ      = t;
153  switch (t)
154  {
155    case BT_execute:
156                     yylineno-=2;
157                     break;
158    case BT_proc:
159    case BT_example:
160                     currentVoice->oldb=myynewbuffer();
161                     yylineno = lineno+1;
162                     break;
163    case BT_if:
164    case BT_else:
165    case BT_break:
166                     yylineno = yy_blocklineno-1;
167                     break;
168    //case BT_file:
169    default:
170                     yylineno = 1;
171                     break;
172  }
173  //Print("start body (%s) at line %d\n",BT_name[t],yylineno);
174  currentVoice->start_lineno = yylineno;
175  //printf("start buffer typ %d\n",t);
176  //Voice *p=currentVoice;
177  //Print("-----------------\ncurr:");
178  //do
179  //{
180  //Print("voice fn:%s\n",p->filename);
181  //p=p->prev;
182  //}
183  //while (p!=NULL);
184  //Print("----------------\n");
185}
186
187/*2
188* exit Buffer of type 'typ':
189* returns 1 if buffer type could not be found
190*/
191BOOLEAN exitBuffer(feBufferTypes typ)
192{
193  //printf("exitBuffer: %d(%s),(%x)\n",
194  //  typ,BT_name[typ], currentVoice);
195  //Voice *p=currentVoice;
196  //Print("-----------------\ncurr:");
197  //do
198  //{
199  //Print("voice fn:%s\n",p->filename);
200  //p=p->prev;
201  //}
202  //while (p!=NULL);
203  //Print("----------------\n");
204  if (typ == BT_break)  // valid inside for, while. may skip if, else
205  {
206    /*4 first check for valid buffer type, skip if/else*/
207    Voice *p=currentVoice;
208    loop
209    {
210      if ((p->typ != BT_if)
211      &&(p->typ != BT_else))
212      {
213        if (p->typ == BT_break /*typ*/)
214        {
215          while (p != currentVoice)
216          {
217            exitVoice();
218          }
219          exitVoice();
220          return FALSE;
221        }
222        else return TRUE;
223      }
224      if (p->prev==NULL) break;
225      p=p->prev;
226    }
227    /*4 break not inside a for/while: return an error*/
228    if (/*typ*/ BT_break != currentVoice->typ) return 1;
229    return exitVoice();
230  }
231
232  if ((typ == BT_proc)
233  || (typ == BT_example))
234  {
235    Voice *p=currentVoice;
236    loop
237    {
238      if ((p->typ == BT_proc)
239      || (p->typ == BT_example))
240      {
241        while (p != currentVoice)
242        {
243          exitVoice();
244        }
245        exitVoice();
246        return FALSE;
247      }
248      if (p->prev==NULL) break;
249      p=p->prev;
250    }
251  }
252  /*4 return not inside a proc: return an error*/
253  return TRUE;
254}
255
256/*2
257* jump to the beginning of a buffer
258*/
259BOOLEAN contBuffer(feBufferTypes typ)
260{
261  //printf("contBuffer: %d(%s),(%x)\n",
262  //  typ,BT_name[typ], currentVoice);
263  if (typ == BT_break)  // valid inside for, while. may skip if, else
264  {
265    // first check for valid buffer type
266    Voice *p=currentVoice;
267    loop
268    {
269      if ((p->typ != BT_if)
270        &&(p->typ != BT_else))
271      {
272        if (p->typ == BT_break /*typ*/)
273        {
274          while (p != currentVoice)
275          {
276            exitVoice();
277          }
278          yylineno = currentVoice->start_lineno;
279          currentVoice->fptr=0;
280          return FALSE;
281        }
282        else return TRUE;
283      }
284      if (p->prev==NULL) break;
285      p=p->prev;
286    }
287  }
288  return TRUE;
289}
290
291/*2
292* leave a voice: kill local variables
293* setup everything from the previous level
294* return 1 if leaving the top level, 0 otherwise
295*/
296BOOLEAN exitVoice()
297{
298  //printf("exitVoice: %d(%s),(%x)\n",
299  //  currentVoice->typ,BT_name[currentVoice->typ], currentVoice);
300  //{
301  //Voice *p=currentVoice;
302  //Print("-----------------\ncurr:");
303  //do
304  //{
305  //Print("voice fn:%s\n",p->filename);
306  //p=p->prev;
307  //}
308  //while (p!=NULL);
309  //Print("----------------\n");
310  //}
311  if (currentVoice!=NULL)
312  {
313    if (currentVoice->oldb!=NULL)
314    {
315      myyoldbuffer(currentVoice->oldb);
316      currentVoice->oldb=NULL;
317    }
318    if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
319    {
320      currentVoice->prev=feInitStdin();
321    }
322    if (currentVoice->prev!=NULL)
323    {
324      //printf("exitVoice typ %d(%s)\n",
325      //  currentVoice->typ,BT_name[currentVoice->typ]);
326      if (currentVoice->typ==BT_if)
327      {
328        currentVoice->prev->ifsw=2;
329      }
330      else
331      {
332        currentVoice->prev->ifsw=0;
333      }
334      if ((currentVoice->sw == BI_file)
335      && (currentVoice->files!=NULL))
336      {
337        fclose(currentVoice->files);
338      }
339      if (currentVoice->filename!=NULL)
340      {
341        omFree((ADDRESS)currentVoice->filename);
342        currentVoice->filename=NULL;
343      }
344      if (currentVoice->buffer!=NULL)
345      {
346        omFree((ADDRESS)currentVoice->buffer);
347        currentVoice->buffer=NULL;
348      }
349      yylineno=currentVoice->prev->curr_lineno;
350      currentVoice->prev->next=NULL;
351    }
352    Voice *p=currentVoice->prev;
353    delete currentVoice;
354    currentVoice=p;
355  }
356  return currentVoice==NULL;
357}
358
359/*2
360* set prompt_char
361* only called with currentVoice->sw == BI_stdin
362*/
363static void feShowPrompt(void)
364{
365  fe_promptstr[0]=prompt_char;
366#ifdef macintosh
367  cols = 0;
368  printf(fe_promptstr);mflush();
369#endif
370}
371
372/*2
373* print echo (si_echo or TRACE), set my_yylinebuf
374*/
375static int fePrintEcho(char *anf, char *b)
376{
377  char *ss=strrchr(anf,'\n');
378  int len_s;
379  if (ss==NULL)
380  {
381    len_s=strlen(anf);
382  }
383  else
384  {
385    len_s=ss-anf+1;
386  }
387  // my_yylinebuf:
388  int mrc=min(len_s,79)-1;
389  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
390  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
391  mrc--;
392  // handle echo:
393  if (((si_echo>myynest)
394    && ((currentVoice->typ==BT_proc)
395      || (currentVoice->typ==BT_example)
396      || (currentVoice->typ==BT_file)
397      || (currentVoice->typ==BT_none)
398    )
399    && (strncmp(anf,";return();",10)!=0)
400   )
401  || (traceit&TRACE_SHOW_LINE)
402  || (traceit&TRACE_SHOW_LINE1))
403  {
404    if (currentVoice->typ!=BT_example)
405    {
406      if (currentVoice->filename==NULL)
407        Print("(none) %3d%c ",yylineno,prompt_char);
408      else
409        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
410     }
411    #ifdef HAVE_TCL
412    if(tclmode)
413    {
414      PrintTCL('N',len_s,anf);
415    }
416    else
417    #endif
418    {
419      fwrite(anf,1,len_s,stdout);
420      mflush();
421    }
422    if (traceit&TRACE_SHOW_LINE)
423    {
424      #ifdef HAVE_TCL
425      if(!tclmode)
426      #endif
427      while(fgetc(stdin)!='\n');
428    }
429  }
430  else if (traceit&TRACE_SHOW_LINENO)
431  {
432    Print("{%d}",yylineno);
433    mflush();
434  }
435  if ((blocknest==0)
436  && (currentVoice->pi!=NULL)
437  && (currentVoice->pi->trace_flag!=0))
438  {
439    sdb(currentVoice, anf, len_s);
440  }
441  prompt_char = '.';
442  return len_s;
443}
444
445int feReadLine(char* b, int l)
446{
447  char *s=NULL;
448  int offset = 0; /* will not be used if s==NULL*/
449  // try to read from the buffer into b, max l chars
450  if (currentVoice!=NULL)
451  {
452    if((currentVoice->buffer!=NULL)
453    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
454    {
455  NewBuff:
456      register int i=0;
457      long startfptr=currentVoice->fptr;
458      long tmp_ptr=currentVoice->fptr;
459      l--;
460      loop
461      {
462        register char c=
463        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
464        i++;
465        if (yy_noeof==noeof_block)
466        {
467          if (c<' ')  yylineno++;
468          else if (c=='}') break;
469        }
470        else
471        {
472          if ((c<' ') ||
473          (c==';') ||
474          (c==')')
475          )
476            break;
477        }
478        if (i>=l) break;
479        tmp_ptr++;/*currentVoice->fptr++;*/
480        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
481      }
482      currentVoice->fptr=tmp_ptr;
483      b[i]='\0';
484      if (currentVoice->sw==BI_buffer)
485      {
486        if (startfptr==0)
487        {
488          char *anf=currentVoice->buffer;
489          char *ss=strchr(anf,'\n');
490          int len;
491          if (ss==NULL) len=strlen(anf);
492          else          len=ss-anf;
493          char *s=(char *)omAlloc(len+2);
494          strncpy(s,anf,len+2);
495          s[len+1]='\0';
496          fePrintEcho(s,b);
497          omFree((ADDRESS)s);
498        }
499        else if (/*(startfptr>0) &&*/
500        (currentVoice->buffer[startfptr-1]=='\n'))
501        {
502          char *anf=currentVoice->buffer+startfptr;
503          char *ss=strchr(anf,'\n');
504          int len;
505          if (ss==NULL) len=strlen(anf);
506          else          len=ss-anf;
507          char *s=(char *)omAlloc(len+2);
508          strncpy(s,anf,len+2);
509          s[len+1]='\0';
510          yylineno++;
511          fePrintEcho(s,b);
512          omFree((ADDRESS)s);
513        }
514      }
515      currentVoice->fptr++;
516      return i;
517    }
518    // no buffer there or e-o-buffer or eoln:
519    if (currentVoice->sw!=BI_buffer)
520    {
521      currentVoice->fptr=0;
522      if (currentVoice->buffer==NULL)
523      {
524        currentVoice->buffer=(char *)omAlloc(4096-sizeof(ADDRESS));
525        omMarkAsStaticAddr(currentVoice->buffer);
526      }
527    }
528    offset=0;
529  NewRead:
530    yylineno++;
531    if (currentVoice->sw==BI_stdin)
532    {
533      feShowPrompt();
534      s=fe_fgets_stdin(fe_promptstr,
535                       &(currentVoice->buffer[offset]),
536                       (4096-1-sizeof(ADDRESS))-offset);
537    }
538    else if (currentVoice->sw==BI_file)
539    {
540      s=fgets(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset,
541              currentVoice->files);
542    }
543    //else /* BI_buffer */ s==NULL  => return 0
544    // done by the default return
545  }
546  if (s!=NULL)
547  {
548    // handle prot:
549    if (feProt&PROT_I)
550    {
551      fputs(s,feProtFile);
552    }
553    int rc=fePrintEcho(s,b)+1;
554    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
555    s[rc]='\0';
556    // handel \\ :
557    rc-=3;
558    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
559    {
560      s[rc]='\0';
561      offset+=rc;
562      if (offset<(int)omSizeOfAddr(currentVoice->buffer)) goto NewRead;
563    }
564    goto NewBuff;
565  }
566  /* else if (s==NULL) */
567  {
568    char *err;
569    switch(yy_noeof)
570    {
571      case noeof_brace:
572      case noeof_block:
573        err="{...}";
574        break;
575      case noeof_asstring:
576        err="till `.`";
577        break;
578      case noeof_string:
579        err="string";
580        break;
581      case noeof_bracket:
582        err="(...)";
583        break;
584      case noeof_procname:
585        err="proc";
586        break;
587      case noeof_comment:
588        err="/*...*/";
589        break;
590      default:
591        return 0;
592    }
593    Werror("premature end of file while reading %s",err);
594    return 0;
595  }
596}
597
598#ifdef __MWERKS__
599#ifdef __cplusplus
600extern "C" {
601#endif
602#ifdef macintosh
603int    isatty(int filedes);
604#else
605int    _isatty(int filedes);
606#define isatty  _isatty
607#endif /* macintosh */
608#ifdef __cplusplus
609}
610#endif
611#endif
612/*2
613* init all data structures
614*/
615#ifndef STDIN_FILENO
616#define STDIN_FILENO 0
617#endif
618Voice * feInitStdin()
619{
620  Voice *p = new Voice;
621  p->files = stdin;
622  #ifdef HAVE_TCL
623  p->sw = (tclmode || isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
624  #else
625  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
626  #endif
627  p->filename   = omStrDup("STDIN");
628  p->start_lineno   = 1;
629  omMarkAsStaticAddr(p);
630  omMarkAsStaticAddr(p->filename);
631  return p;
632}
Note: See TracBrowser for help on using the repository browser.