source: git/Singular/febase.inc @ 50cbdc

spielwiese
Last change on this file since 50cbdc was 50cbdc, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merge-2-0-2 git-svn-id: file:///usr/local/Singular/svn/trunk@5619 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.3 KB
Line 
1/* -*-c++-*- */
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5/* $Id: febase.inc,v 1.33 2001-08-27 14:46:58 Singular 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#ifdef HAVE_SDB 
436  if ((blocknest==0)
437  && (currentVoice->pi!=NULL)
438  && (currentVoice->pi->trace_flag!=0))
439  {
440    sdb(currentVoice, anf, len_s);
441  }
442#endif 
443  prompt_char = '.';
444  return len_s;
445}
446
447int feReadLine(char* b, int l)
448{
449  char *s=NULL;
450  int offset = 0; /* will not be used if s==NULL*/
451  // try to read from the buffer into b, max l chars
452  if (currentVoice!=NULL)
453  {
454    if((currentVoice->buffer!=NULL)
455    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
456    {
457  NewBuff:
458      register int i=0;
459      long startfptr=currentVoice->fptr;
460      long tmp_ptr=currentVoice->fptr;
461      l--;
462      loop
463      {
464        register char c=
465        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
466        i++;
467        if (yy_noeof==noeof_block)
468        {
469          if (c<' ')  yylineno++;
470          else if (c=='}') break;
471        }
472        else
473        {
474          if ((c<' ') ||
475          (c==';') ||
476          (c==')')
477          )
478            break;
479        }
480        if (i>=l) break;
481        tmp_ptr++;/*currentVoice->fptr++;*/
482        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
483      }
484      currentVoice->fptr=tmp_ptr;
485      b[i]='\0';
486      if (currentVoice->sw==BI_buffer)
487      {
488        if (startfptr==0)
489        {
490          char *anf=currentVoice->buffer;
491          char *ss=strchr(anf,'\n');
492          int len;
493          if (ss==NULL) len=strlen(anf);
494          else          len=ss-anf;
495          char *s=(char *)omAlloc(len+2);
496          strncpy(s,anf,len+2);
497          s[len+1]='\0';
498          fePrintEcho(s,b);
499          omFree((ADDRESS)s);
500        }
501        else if (/*(startfptr>0) &&*/
502        (currentVoice->buffer[startfptr-1]=='\n'))
503        {
504          char *anf=currentVoice->buffer+startfptr;
505          char *ss=strchr(anf,'\n');
506          int len;
507          if (ss==NULL) len=strlen(anf);
508          else          len=ss-anf;
509          char *s=(char *)omAlloc(len+2);
510          strncpy(s,anf,len+2);
511          s[len+1]='\0';
512          yylineno++;
513          fePrintEcho(s,b);
514          omFree((ADDRESS)s);
515        }
516      }
517      currentVoice->fptr++;
518      return i;
519    }
520    // no buffer there or e-o-buffer or eoln:
521    if (currentVoice->sw!=BI_buffer)
522    {
523      currentVoice->fptr=0;
524      if (currentVoice->buffer==NULL)
525      {
526        currentVoice->buffer=(char *)omAlloc(4096-sizeof(ADDRESS));
527        omMarkAsStaticAddr(currentVoice->buffer);
528      }
529    }
530    offset=0;
531  NewRead:
532    yylineno++;
533    if (currentVoice->sw==BI_stdin)
534    {
535      feShowPrompt();
536      s=fe_fgets_stdin(fe_promptstr,
537                       &(currentVoice->buffer[offset]),
538                       (4096-1-sizeof(ADDRESS))-offset);
539      int i=0;
540      if (s!=NULL)
541        while((s[i]!='\0') && (i<4096)) {s[i] &= (char)127;i++;}
542    }
543    else if (currentVoice->sw==BI_file)
544    {
545      s=fgets(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset,
546              currentVoice->files);
547    }
548    //else /* BI_buffer */ s==NULL  => return 0
549    // done by the default return
550  }
551  if (s!=NULL)
552  {
553    // handle prot:
554    if (feProt&PROT_I)
555    {
556      fputs(s,feProtFile);
557    }
558    int rc=fePrintEcho(s,b)+1;
559    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
560    s[rc]='\0';
561    // handel \\ :
562    rc-=3;
563    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
564    {
565      s[rc]='\0';
566      offset+=rc;
567      if (offset<(int)omSizeOfAddr(currentVoice->buffer)) goto NewRead;
568    }
569    goto NewBuff;
570  }
571  /* else if (s==NULL) */
572  {
573    char *err;
574    switch(yy_noeof)
575    {
576      case noeof_brace:
577      case noeof_block:
578        err="{...}";
579        break;
580      case noeof_asstring:
581        err="till `.`";
582        break;
583      case noeof_string:
584        err="string";
585        break;
586      case noeof_bracket:
587        err="(...)";
588        break;
589      case noeof_procname:
590        err="proc";
591        break;
592      case noeof_comment:
593        err="/*...*/";
594        break;
595      default:
596        return 0;
597    }
598    Werror("premature end of file while reading %s",err);
599    return 0;
600  }
601}
602
603#ifdef __MWERKS__
604#ifdef __cplusplus
605extern "C" {
606#endif
607#ifdef macintosh
608int    isatty(int filedes);
609#else
610int    _isatty(int filedes);
611#define isatty  _isatty
612#endif /* macintosh */
613#ifdef __cplusplus
614}
615#endif
616#endif
617/*2
618* init all data structures
619*/
620#ifndef STDIN_FILENO
621#define STDIN_FILENO 0
622#endif
623Voice * feInitStdin()
624{
625  Voice *p = new Voice;
626  p->files = stdin;
627  #ifdef HAVE_TCL
628  p->sw = (tclmode || isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
629  #else
630  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
631  #endif
632  p->filename   = omStrDup("STDIN");
633  p->start_lineno   = 1;
634  omMarkAsStaticAddr(p);
635  omMarkAsStaticAddr(p->filename);
636  return p;
637}
Note: See TracBrowser for help on using the repository browser.