source: git/Singular/febase.inc @ 743c32

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