source: git/Singular/febase.inc @ 457d8d6

fieker-DuValspielwiese
Last change on this file since 457d8d6 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
RevLine 
[a70441f]1/* -*-c++-*- */
[d931f8]2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
[ec7aac]5/* $Id: febase.inc,v 1.32 2000-09-04 13:38:57 obachman Exp $ */
[d931f8]6/*
7* ABSTRACT: handling of 'voices'
8*/
[cc94b0a]9#include <ctype.h>
[64d729]10#include "sdb.h"
11
12extern int blocknest; /* scaner.l internal */
[d931f8]13
[cc94b0a]14int    yy_noeof=0;     // the scanner "state"
15int    yy_blocklineno; // to get the lineno of the block start from scanner
[057e93c]16Voice  *currentVoice = NULL;
[cc94b0a]17FILE   *feFilePending; /*temp. storage for grammar.y */
[d931f8]18
[057e93c]19static char * BT_name[]={"BT_none","BT_break","BT_proc","BT_example",
20                       "BT_file","BT_execute","BT_if","BT_else"};
[d931f8]21/*2
[057e93c]22* the name of the current 'Voice': the procname (or filename)
[d931f8]23*/
24const char * VoiceName()
25{
[057e93c]26  if ((currentVoice!=NULL)
27  && (currentVoice->filename!=NULL))
28    return currentVoice->filename;
[d931f8]29  return sNoName;
30}
31
32/*2
[057e93c]33* the calling chain of Voices
[d931f8]34*/
[057e93c]35void VoiceBackTrack()
[d931f8]36{
[057e93c]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  }
[d931f8]47}
48
49/*2
[057e93c]50* init a new voice similiar to the current
[d931f8]51*/
[057e93c]52void Voice::Next()
[d931f8]53{
[057e93c]54  Voice *p=new Voice;
[ec7aac]55  // OB: ???
56  // Hmm... when Singular is used as batch file
57  // then this voice is never freed
58  omMarkAsStaticAddr(p);
[057e93c]59  if (currentVoice != NULL)
[d931f8]60  {
[057e93c]61    currentVoice->curr_lineno=yylineno;
62    currentVoice->next=p;
[d931f8]63  }
[057e93c]64  p->prev=currentVoice;
65  currentVoice=p;
66  //Print("Next:");
[d931f8]67}
68
[057e93c]69feBufferTypes Voice::Typ()
[d931f8]70{
[057e93c]71  switch(typ)
[d931f8]72  {
[057e93c]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();
[d931f8]80  }
81}
82
83/*2
84* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
[057e93c]85* return FALSE on success, TRUE if an error occurs (file cannot be opened)
[d931f8]86*/
[057e93c]87BOOLEAN newFile(char *fname,FILE* f)
[d931f8]88{
89  currentVoice->Next();
[057e93c]90  //Print(":File%d(%s):%s(%x)\n",
91  //  currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
[c232af]92  currentVoice->filename   = omStrDup(fname);
[ec7aac]93  omMarkAsStaticAddr(currentVoice->filename);
[057e93c]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;
[d931f8]127}
128
[057e93c]129void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
[d931f8]130{
131  currentVoice->Next();
[057e93c]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);
[c232af]138    currentVoice->filename = (char *)omAlloc(l+3);
[057e93c]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  {
[c232af]147    currentVoice->filename = omStrDup(currentVoice->prev->filename);
[057e93c]148    currentVoice->pi       = currentVoice->prev->pi;
149  }
150  currentVoice->buffer   = s;
151  currentVoice->sw       = BI_buffer;
152  currentVoice->typ      = t;
[d931f8]153  switch (t)
154  {
[057e93c]155    case BT_execute:
156                     yylineno-=2;
157                     break;
158    case BT_proc:
[d931f8]159    case BT_example:
[057e93c]160                     currentVoice->oldb=myynewbuffer();
161                     yylineno = lineno+1;
162                     break;
[d931f8]163    case BT_if:
[057e93c]164    case BT_else:
165    case BT_break:
[cc94b0a]166                     yylineno = yy_blocklineno-1;
[057e93c]167                     break;
[8520b7]168    //case BT_file:
169    default:
170                     yylineno = 1;
171                     break;
[d931f8]172  }
[057e93c]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");
[d931f8]185}
186
187/*2
188* exit Buffer of type 'typ':
189* returns 1 if buffer type could not be found
190*/
[057e93c]191BOOLEAN exitBuffer(feBufferTypes typ)
[d931f8]192{
[057e93c]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");
[d931f8]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*/
[057e93c]207    Voice *p=currentVoice;
208    loop
[d931f8]209    {
[057e93c]210      if ((p->typ != BT_if)
211      &&(p->typ != BT_else))
[d931f8]212      {
[057e93c]213        if (p->typ == BT_break /*typ*/)
[d931f8]214        {
[057e93c]215          while (p != currentVoice)
216          {
217            exitVoice();
218          }
[d931f8]219          exitVoice();
[057e93c]220          return FALSE;
[d931f8]221        }
[057e93c]222        else return TRUE;
[d931f8]223      }
[057e93c]224      if (p->prev==NULL) break;
225      p=p->prev;
[d931f8]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  {
[057e93c]235    Voice *p=currentVoice;
236    loop
[d931f8]237    {
[057e93c]238      if ((p->typ == BT_proc)
239      || (p->typ == BT_example))
[d931f8]240      {
[057e93c]241        while (p != currentVoice)
[d931f8]242        {
243          exitVoice();
244        }
[057e93c]245        exitVoice();
246        return FALSE;
[d931f8]247      }
[057e93c]248      if (p->prev==NULL) break;
249      p=p->prev;
[d931f8]250    }
251  }
252  /*4 return not inside a proc: return an error*/
[057e93c]253  return TRUE;
[d931f8]254}
255
256/*2
257* jump to the beginning of a buffer
258*/
[057e93c]259BOOLEAN contBuffer(feBufferTypes typ)
[d931f8]260{
[057e93c]261  //printf("contBuffer: %d(%s),(%x)\n",
262  //  typ,BT_name[typ], currentVoice);
[d931f8]263  if (typ == BT_break)  // valid inside for, while. may skip if, else
264  {
265    // first check for valid buffer type
[057e93c]266    Voice *p=currentVoice;
267    loop
[d931f8]268    {
[057e93c]269      if ((p->typ != BT_if)
270        &&(p->typ != BT_else))
[d931f8]271      {
[057e93c]272        if (p->typ == BT_break /*typ*/)
[d931f8]273        {
[057e93c]274          while (p != currentVoice)
275          {
276            exitVoice();
277          }
278          yylineno = currentVoice->start_lineno;
279          currentVoice->fptr=0;
280          return FALSE;
[d931f8]281        }
[057e93c]282        else return TRUE;
[d931f8]283      }
[057e93c]284      if (p->prev==NULL) break;
285      p=p->prev;
[d931f8]286    }
287  }
[057e93c]288  return TRUE;
[d931f8]289}
290
291/*2
292* leave a voice: kill local variables
[057e93c]293* setup everything from the previous level
294* return 1 if leaving the top level, 0 otherwise
[d931f8]295*/
[057e93c]296BOOLEAN exitVoice()
[d931f8]297{
[057e93c]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  //}
[e9ad8a6]311  if (currentVoice!=NULL)
[d931f8]312  {
[e9ad8a6]313    if (currentVoice->oldb!=NULL)
[d931f8]314    {
[e9ad8a6]315      myyoldbuffer(currentVoice->oldb);
316      currentVoice->oldb=NULL;
[d931f8]317    }
[e9ad8a6]318    if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
[057e93c]319    {
[e9ad8a6]320      currentVoice->prev=feInitStdin();
[057e93c]321    }
[e9ad8a6]322    if (currentVoice->prev!=NULL)
[057e93c]323    {
[e9ad8a6]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      {
[c232af]341        omFree((ADDRESS)currentVoice->filename);
[e9ad8a6]342        currentVoice->filename=NULL;
343      }
344      if (currentVoice->buffer!=NULL)
345      {
[c232af]346        omFree((ADDRESS)currentVoice->buffer);
[e9ad8a6]347        currentVoice->buffer=NULL;
348      }
349      yylineno=currentVoice->prev->curr_lineno;
[0d3f08]350      currentVoice->prev->next=NULL;
[057e93c]351    }
[e9ad8a6]352    Voice *p=currentVoice->prev;
353    delete currentVoice;
354    currentVoice=p;
[d931f8]355  }
[e9ad8a6]356  return currentVoice==NULL;
[d931f8]357}
358
[057e93c]359/*2
[19fbf0]360* set prompt_char
[a18fae]361* only called with currentVoice->sw == BI_stdin
[057e93c]362*/
363static void feShowPrompt(void)
[d931f8]364{
[90c67b]365  fe_promptstr[0]=prompt_char;
[057e93c]366#ifdef macintosh
[90c67b]367  cols = 0;
[b5e952]368  printf(fe_promptstr);mflush();
[057e93c]369#endif
370}
371
372/*2
373* print echo (si_echo or TRACE), set my_yylinebuf
374*/
[743c32]375static int fePrintEcho(char *anf, char *b)
[057e93c]376{
[2f7502]377  char *ss=strrchr(anf,'\n');
[057e93c]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:
[824241]388  int mrc=min(len_s,79)-1;
[057e93c]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)
[8520b7]394    && ((currentVoice->typ==BT_proc)
[a18fae]395      || (currentVoice->typ==BT_example)
396      || (currentVoice->typ==BT_file)
397      || (currentVoice->typ==BT_none)
[8520b7]398    )
399    && (strncmp(anf,";return();",10)!=0)
400   )
[057e93c]401  || (traceit&TRACE_SHOW_LINE)
[8dd3ac]402  || (traceit&TRACE_SHOW_LINE1))
[057e93c]403  {
[8520b7]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);
[64d729]410     }
[eb0698]411    #ifdef HAVE_TCL
412    if(tclmode)
413    {
414      PrintTCL('N',len_s,anf);
415    }
416    else
[a1c623b]417    #endif
[eb0698]418    {
419      fwrite(anf,1,len_s,stdout);
420      mflush();
421    }
[057e93c]422    if (traceit&TRACE_SHOW_LINE)
423    {
[eb0698]424      #ifdef HAVE_TCL
425      if(!tclmode)
426      #endif
[057e93c]427      while(fgetc(stdin)!='\n');
428    }
429  }
[8dd3ac]430  else if (traceit&TRACE_SHOW_LINENO)
[057e93c]431  {
[eb0698]432    Print("{%d}",yylineno);
[057e93c]433    mflush();
[d931f8]434  }
[64d729]435  if ((blocknest==0)
436  && (currentVoice->pi!=NULL)
[8dd3ac]437  && (currentVoice->pi->trace_flag!=0))
[64d729]438  {
[ad4bc9]439    sdb(currentVoice, anf, len_s);
[64d729]440  }
[8520b7]441  prompt_char = '.';
[057e93c]442  return len_s;
443}
[d931f8]444
[057e93c]445int feReadLine(char* b, int l)
446{
[e9ad8a6]447  char *s=NULL;
[a70441f]448  int offset = 0; /* will not be used if s==NULL*/
[4fc4d1]449  // try to read from the buffer into b, max l chars
[e9ad8a6]450  if (currentVoice!=NULL)
[d931f8]451  {
[e9ad8a6]452    if((currentVoice->buffer!=NULL)
453    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
[cc94b0a]454    {
[e9ad8a6]455  NewBuff:
[ad4bc9]456      register int i=0;
457      long startfptr=currentVoice->fptr;
458      long tmp_ptr=currentVoice->fptr;
[e9ad8a6]459      l--;
460      loop
[4fc4d1]461      {
[ad4bc9]462        register char c=
463        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
[e9ad8a6]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;
[19fbf0]477        }
[e9ad8a6]478        if (i>=l) break;
[ad4bc9]479        tmp_ptr++;/*currentVoice->fptr++;*/
480        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
[4fc4d1]481      }
[ad4bc9]482      currentVoice->fptr=tmp_ptr;
[e9ad8a6]483      b[i]='\0';
484      if (currentVoice->sw==BI_buffer)
[4fc4d1]485      {
[e9ad8a6]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;
[c232af]493          char *s=(char *)omAlloc(len+2);
[e9ad8a6]494          strncpy(s,anf,len+2);
495          s[len+1]='\0';
[743c32]496          fePrintEcho(s,b);
[c232af]497          omFree((ADDRESS)s);
[e9ad8a6]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;
[c232af]507          char *s=(char *)omAlloc(len+2);
[e9ad8a6]508          strncpy(s,anf,len+2);
509          s[len+1]='\0';
510          yylineno++;
[743c32]511          fePrintEcho(s,b);
[c232af]512          omFree((ADDRESS)s);
[e9ad8a6]513        }
514      }
[cc94b0a]515      currentVoice->fptr++;
[e9ad8a6]516      return i;
[cc94b0a]517    }
[e9ad8a6]518    // no buffer there or e-o-buffer or eoln:
519    if (currentVoice->sw!=BI_buffer)
[d931f8]520    {
[e9ad8a6]521      currentVoice->fptr=0;
522      if (currentVoice->buffer==NULL)
[c232af]523      {
524        currentVoice->buffer=(char *)omAlloc(4096-sizeof(ADDRESS));
525        omMarkAsStaticAddr(currentVoice->buffer);
526      }
[d931f8]527    }
[e9ad8a6]528    offset=0;
529  NewRead:
530    yylineno++;
531    if (currentVoice->sw==BI_stdin)
532    {
533      feShowPrompt();
[42aacda]534      s=fe_fgets_stdin(fe_promptstr,
[f413ec5]535                       &(currentVoice->buffer[offset]),
[ad4bc9]536                       (4096-1-sizeof(ADDRESS))-offset);
[e9ad8a6]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
[ad4bc9]544    // done by the default return
[057e93c]545  }
546  if (s!=NULL)
547  {
548    // handle prot:
549    if (feProt&PROT_I)
550    {
551      fputs(s,feProtFile);
552    }
[743c32]553    int rc=fePrintEcho(s,b)+1;
[a05f0e]554    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
555    s[rc]='\0';
[057e93c]556    // handel \\ :
[a05f0e]557    rc-=3;
[057e93c]558    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
[d931f8]559    {
[057e93c]560      s[rc]='\0';
561      offset+=rc;
[c232af]562      if (offset<(int)omSizeOfAddr(currentVoice->buffer)) goto NewRead;
[057e93c]563    }
564    goto NewBuff;
565  }
566  /* else if (s==NULL) */
567  {
[ad4bc9]568    char *err;
[cc94b0a]569    switch(yy_noeof)
[057e93c]570    {
571      case noeof_brace:
572      case noeof_block:
[e9ad8a6]573        err="{...}";
[057e93c]574        break;
575      case noeof_asstring:
[e9ad8a6]576        err="till `.`";
[057e93c]577        break;
578      case noeof_string:
[e9ad8a6]579        err="string";
[057e93c]580        break;
581      case noeof_bracket:
[e9ad8a6]582        err="(...)";
[057e93c]583        break;
584      case noeof_procname:
[e9ad8a6]585        err="proc";
586        break;
587      case noeof_comment:
588        err="/*...*/";
589        break;
590      default:
[ad4bc9]591        return 0;
[d931f8]592    }
[ad4bc9]593    Werror("premature end of file while reading %s",err);
[057e93c]594    return 0;
[d931f8]595  }
596}
597
[647b6d9]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
[d931f8]612/*2
613* init all data structures
614*/
[057e93c]615#ifndef STDIN_FILENO
616#define STDIN_FILENO 0
617#endif
618Voice * feInitStdin()
[d931f8]619{
[057e93c]620  Voice *p = new Voice;
621  p->files = stdin;
[19fbf0]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
[c232af]627  p->filename   = omStrDup("STDIN");
[057e93c]628  p->start_lineno   = 1;
[c232af]629  omMarkAsStaticAddr(p);
630  omMarkAsStaticAddr(p->filename);
[057e93c]631  return p;
[d931f8]632}
Note: See TracBrowser for help on using the repository browser.