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

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