source: git/Singular/febase.inc @ 64d729

spielwiese
Last change on this file since 64d729 was 64d729, checked in by Hans Schönemann <hannes@…>, 25 years ago
* hannes: introduced debugger (hook and first implementation) git-svn-id: file:///usr/local/Singular/svn/trunk@2983 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.inc,v 1.21 1999-04-15 17:28:02 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)
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  || ((currentVoice->pi!=NULL)&&(currentVoice->pi->trace_flag&TRACE_SHOW_LINE)))
397  {
398    if (currentVoice->typ!=BT_example)
399    {
400      if (currentVoice->filename==NULL)
401        Print("(none) %3d%c ",yylineno,prompt_char);
402      else
403        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
404     }
405    #ifdef HAVE_TCL
406    if(tclmode)
407    {
408      PrintTCL('N',len_s,anf);
409    }
410    else
411    #endif
412    {
413      fwrite(anf,1,len_s,stdout);
414      mflush();
415    }
416    if (traceit&TRACE_SHOW_LINE)
417    {
418      #ifdef HAVE_TCL
419      if(!tclmode)
420      #endif
421      while(fgetc(stdin)!='\n');
422    }
423  }
424  else if ((traceit&TRACE_SHOW_LINENO)
425  || ((currentVoice->pi!=NULL)&&(currentVoice->pi->trace_flag&TRACE_SHOW_LINENO)))
426  {
427    Print("{%d}",yylineno);
428    mflush();
429  }
430  if ((blocknest==0)
431  && (currentVoice->pi!=NULL)
432  && (currentVoice->pi->trace_flag&TRACE_BREAKPOINT))
433  {
434    sdb(currentVoice, anf, len_s);
435  }
436  prompt_char = '.';
437  return len_s;
438}
439
440int feReadLine(char* b, int l)
441{
442  char *s=NULL;
443  int offset; /* will not be used if s==NULL*/
444  // try to read from the buffer into b, max l chars
445  if (currentVoice!=NULL)
446  {
447    if((currentVoice->buffer!=NULL)
448    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
449    {
450  NewBuff:
451      int i=0;
452      int startfptr=currentVoice->fptr;
453      l--;
454      loop
455      {
456        char c=
457        b[i]=currentVoice->buffer[currentVoice->fptr];
458        i++;
459        if (yy_noeof==noeof_block)
460        {
461          if (c<' ')  yylineno++;
462          else if (c=='}') break;
463        }
464        else
465        {
466          if ((c<' ') ||
467          (c==';') ||
468          (c==')')
469          )
470            break;
471        }
472        if (i>=l) break;
473        currentVoice->fptr++;
474        if(currentVoice->buffer[currentVoice->fptr]=='\0') break;
475      }
476      b[i]='\0';
477      if (currentVoice->sw==BI_buffer)
478      {
479        if (startfptr==0)
480        {
481          char *anf=currentVoice->buffer;
482          char *ss=strchr(anf,'\n');
483          int len;
484          if (ss==NULL) len=strlen(anf);
485          else          len=ss-anf;
486          char *s=(char *)AllocL(len+2);
487          strncpy(s,anf,len+2);
488          s[len+1]='\0';
489          fePrintEcho(s);
490          FreeL((ADDRESS)s);
491        }
492        else if (/*(startfptr>0) &&*/
493        (currentVoice->buffer[startfptr-1]=='\n'))
494        {
495          char *anf=currentVoice->buffer+startfptr;
496          char *ss=strchr(anf,'\n');
497          int len;
498          if (ss==NULL) len=strlen(anf);
499          else          len=ss-anf;
500          char *s=(char *)AllocL(len+2);
501          strncpy(s,anf,len+2);
502          s[len+1]='\0';
503          yylineno++;
504          fePrintEcho(s);
505          FreeL((ADDRESS)s);
506        }
507      }
508      currentVoice->fptr++;
509      return i;
510    }
511    // no buffer there or e-o-buffer or eoln:
512    if (currentVoice->sw!=BI_buffer)
513    {
514      currentVoice->fptr=0;
515      if (currentVoice->buffer==NULL)
516        currentVoice->buffer=(char *)AllocL(4096-sizeof(ADDRESS));
517    }
518    offset=0;
519  NewRead:
520    yylineno++;
521    if (currentVoice->sw==BI_stdin)
522    {
523      feShowPrompt();
524      s=fe_fgets_stdin(fe_promptstr,
525                       currentVoice->buffer+offset,
526                       (4096-1-sizeof(ADDRESS))-offset);
527    }
528    else if (currentVoice->sw==BI_file)
529    {
530      s=fgets(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset,
531              currentVoice->files);
532    }
533    //else /* BI_buffer */ s==NULL  => return 0
534    //{
535    //  return 0;
536    //}
537  }
538  if (s!=NULL)
539  {
540    // handle prot:
541    if (feProt&PROT_I)
542    {
543      fputs(s,feProtFile);
544    }
545    int rc=fePrintEcho(s)+1;
546    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
547    s[rc]='\0';
548    // handel \\ :
549    rc-=3;
550    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
551    {
552      s[rc]='\0';
553      offset+=rc;
554      if (offset<(int)mmSizeL(currentVoice->buffer)) goto NewRead;
555    }
556    goto NewBuff;
557  }
558  /* else if (s==NULL) */
559  {
560    char *err=NULL;
561    switch(yy_noeof)
562    {
563      case noeof_brace:
564      case noeof_block:
565        err="{...}";
566        break;
567      case noeof_asstring:
568        err="till `.`";
569        break;
570      case noeof_string:
571        err="string";
572        break;
573      case noeof_bracket:
574        err="(...)";
575        break;
576      case noeof_procname:
577        err="proc";
578        break;
579      case noeof_comment:
580        err="/*...*/";
581        break;
582      default:
583        break;
584    }
585    if (err!=NULL)
586      Werror("premature end of file while reading %s",err);
587    return 0;
588  }
589}
590
591#ifdef __MWERKS__
592#ifdef __cplusplus
593extern "C" {
594#endif
595#ifdef macintosh
596int    isatty(int filedes);
597#else
598int    _isatty(int filedes);
599#define isatty  _isatty
600#endif /* macintosh */
601#ifdef __cplusplus
602}
603#endif
604#endif
605/*2
606* init all data structures
607*/
608#ifndef STDIN_FILENO
609#define STDIN_FILENO 0
610#endif
611Voice * feInitStdin()
612{
613  Voice *p = new Voice;
614  p->files = stdin;
615  #ifdef HAVE_TCL
616  p->sw = (tclmode || isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
617  #else
618  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
619  #endif
620  p->filename   = mstrdup("STDIN");
621  p->start_lineno   = 1;
622  return p;
623}
Note: See TracBrowser for help on using the repository browser.