source: git/Singular/febase.inc @ b719a3

spielwiese
Last change on this file since b719a3 was ad4bc9, checked in by Hans Schönemann <hannes@…>, 25 years ago
* hannes: Debugger-changes, typo fixes git-svn-id: file:///usr/local/Singular/svn/trunk@3028 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.inc,v 1.24 1999-05-06 16:53:22 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);
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      register int i=0;
450      long startfptr=currentVoice->fptr;
451      long tmp_ptr=currentVoice->fptr;
452      l--;
453      loop
454      {
455        register char c=
456        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
457        i++;
458        if (yy_noeof==noeof_block)
459        {
460          if (c<' ')  yylineno++;
461          else if (c=='}') break;
462        }
463        else
464        {
465          if ((c<' ') ||
466          (c==';') ||
467          (c==')')
468          )
469            break;
470        }
471        if (i>=l) break;
472        tmp_ptr++;/*currentVoice->fptr++;*/
473        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
474      }
475      currentVoice->fptr=tmp_ptr;
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,b);
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,b);
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    // done by the default return
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;
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        return 0;
582    }
583    Werror("premature end of file while reading %s",err);
584    return 0;
585  }
586}
587
588#ifdef __MWERKS__
589#ifdef __cplusplus
590extern "C" {
591#endif
592#ifdef macintosh
593int    isatty(int filedes);
594#else
595int    _isatty(int filedes);
596#define isatty  _isatty
597#endif /* macintosh */
598#ifdef __cplusplus
599}
600#endif
601#endif
602/*2
603* init all data structures
604*/
605#ifndef STDIN_FILENO
606#define STDIN_FILENO 0
607#endif
608Voice * feInitStdin()
609{
610  Voice *p = new Voice;
611  p->files = stdin;
612  #ifdef HAVE_TCL
613  p->sw = (tclmode || isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
614  #else
615  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
616  #endif
617  p->filename   = mstrdup("STDIN");
618  p->start_lineno   = 1;
619  return p;
620}
Note: See TracBrowser for help on using the repository browser.