source: git/Singular/febase.inc @ a70441f

spielwiese
Last change on this file since a70441f was a70441f, checked in by Olaf Bachmann <obachman@…>, 24 years ago
Windows and gcc 2.95 porting git-svn-id: file:///usr/local/Singular/svn/trunk@4273 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.9 KB
Line 
1/* -*-c++-*- */
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5/* $Id: febase.inc,v 1.30 2000-04-27 10:07:07 obachman 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  if (currentVoice != NULL)
56  {
57    currentVoice->curr_lineno=yylineno;
58    currentVoice->next=p;
59  }
60  p->prev=currentVoice;
61  currentVoice=p;
62  //Print("Next:");
63}
64
65feBufferTypes Voice::Typ()
66{
67  switch(typ)
68  {
69    case BT_proc:
70    case BT_example:
71    case BT_file:
72      return typ;
73    default:
74      if (prev==NULL) return (feBufferTypes)0;
75      return prev->Typ();
76  }
77}
78
79/*2
80* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
81* return FALSE on success, TRUE if an error occurs (file cannot be opened)
82*/
83BOOLEAN newFile(char *fname,FILE* f)
84{
85  currentVoice->Next();
86  //Print(":File%d(%s):%s(%x)\n",
87  //  currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
88  currentVoice->filename   = mstrdup(fname);
89  if (strcmp(fname,"STDIN") == 0)
90  {
91    currentVoice->files = stdin;
92    currentVoice->sw = BI_stdin;
93    currentVoice->start_lineno = 1;
94  }
95  else
96  {
97    currentVoice->sw = BI_file; /* needed by exitVoice below */
98    if (f!=NULL)
99      currentVoice->files = f;
100    else
101    {
102      currentVoice->files = feFopen(fname,"r",NULL,TRUE);
103      if (currentVoice->files==NULL)
104      {
105        exitVoice();
106        return TRUE;
107      }
108    }
109    currentVoice->start_lineno = 0;
110  }
111  yylineno=currentVoice->start_lineno;
112  //Voice *p=currentVoice;
113  //Print("-----------------\ncurr:");
114  //do
115  //{
116  //Print("voice fn:%s\n",p->filename);
117  //p=p->prev;
118  //}
119  //while (p!=NULL);
120  //Print("----------------\n");
121  return FALSE;
122}
123
124void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
125{
126  currentVoice->Next();
127  //Print(":Buffer%d(%s):%s(%x)\n",
128  //  t,BT_name[t],pname,currentVoice);
129  if (pi!=NULL)
130  {
131    int l=strlen(pi->procname);
132    if (pi->libname!=NULL) l+=strlen(pi->libname);
133    currentVoice->filename = (char *)AllocL(l+3);
134    *currentVoice->filename='\0';
135    if (pi->libname!=NULL) strcat(currentVoice->filename,pi->libname);
136    strcat(currentVoice->filename,"::");
137    strcat(currentVoice->filename,pi->procname);
138    currentVoice->pi       = pi;
139  }
140  else
141  {
142    currentVoice->filename = mstrdup(currentVoice->prev->filename);
143    currentVoice->pi       = currentVoice->prev->pi;
144  }
145  currentVoice->buffer   = s;
146  currentVoice->sw       = BI_buffer;
147  currentVoice->typ      = t;
148  switch (t)
149  {
150    case BT_execute:
151                     yylineno-=2;
152                     break;
153    case BT_proc:
154    case BT_example:
155                     currentVoice->oldb=myynewbuffer();
156                     yylineno = lineno+1;
157                     break;
158    case BT_if:
159    case BT_else:
160    case BT_break:
161                     yylineno = yy_blocklineno-1;
162                     break;
163    //case BT_file:
164    default:
165                     yylineno = 1;
166                     break;
167  }
168  //Print("start body (%s) at line %d\n",BT_name[t],yylineno);
169  currentVoice->start_lineno = yylineno;
170  //printf("start buffer typ %d\n",t);
171  //Voice *p=currentVoice;
172  //Print("-----------------\ncurr:");
173  //do
174  //{
175  //Print("voice fn:%s\n",p->filename);
176  //p=p->prev;
177  //}
178  //while (p!=NULL);
179  //Print("----------------\n");
180}
181
182/*2
183* exit Buffer of type 'typ':
184* returns 1 if buffer type could not be found
185*/
186BOOLEAN exitBuffer(feBufferTypes typ)
187{
188  //printf("exitBuffer: %d(%s),(%x)\n",
189  //  typ,BT_name[typ], currentVoice);
190  //Voice *p=currentVoice;
191  //Print("-----------------\ncurr:");
192  //do
193  //{
194  //Print("voice fn:%s\n",p->filename);
195  //p=p->prev;
196  //}
197  //while (p!=NULL);
198  //Print("----------------\n");
199  if (typ == BT_break)  // valid inside for, while. may skip if, else
200  {
201    /*4 first check for valid buffer type, skip if/else*/
202    Voice *p=currentVoice;
203    loop
204    {
205      if ((p->typ != BT_if)
206      &&(p->typ != BT_else))
207      {
208        if (p->typ == BT_break /*typ*/)
209        {
210          while (p != currentVoice)
211          {
212            exitVoice();
213          }
214          exitVoice();
215          return FALSE;
216        }
217        else return TRUE;
218      }
219      if (p->prev==NULL) break;
220      p=p->prev;
221    }
222    /*4 break not inside a for/while: return an error*/
223    if (/*typ*/ BT_break != currentVoice->typ) return 1;
224    return exitVoice();
225  }
226
227  if ((typ == BT_proc)
228  || (typ == BT_example))
229  {
230    Voice *p=currentVoice;
231    loop
232    {
233      if ((p->typ == BT_proc)
234      || (p->typ == BT_example))
235      {
236        while (p != currentVoice)
237        {
238          exitVoice();
239        }
240        exitVoice();
241        return FALSE;
242      }
243      if (p->prev==NULL) break;
244      p=p->prev;
245    }
246  }
247  /*4 return not inside a proc: return an error*/
248  return TRUE;
249}
250
251/*2
252* jump to the beginning of a buffer
253*/
254BOOLEAN contBuffer(feBufferTypes typ)
255{
256  //printf("contBuffer: %d(%s),(%x)\n",
257  //  typ,BT_name[typ], currentVoice);
258  if (typ == BT_break)  // valid inside for, while. may skip if, else
259  {
260    // first check for valid buffer type
261    Voice *p=currentVoice;
262    loop
263    {
264      if ((p->typ != BT_if)
265        &&(p->typ != BT_else))
266      {
267        if (p->typ == BT_break /*typ*/)
268        {
269          while (p != currentVoice)
270          {
271            exitVoice();
272          }
273          yylineno = currentVoice->start_lineno;
274          currentVoice->fptr=0;
275          return FALSE;
276        }
277        else return TRUE;
278      }
279      if (p->prev==NULL) break;
280      p=p->prev;
281    }
282  }
283  return TRUE;
284}
285
286/*2
287* leave a voice: kill local variables
288* setup everything from the previous level
289* return 1 if leaving the top level, 0 otherwise
290*/
291BOOLEAN exitVoice()
292{
293  //printf("exitVoice: %d(%s),(%x)\n",
294  //  currentVoice->typ,BT_name[currentVoice->typ], currentVoice);
295  //{
296  //Voice *p=currentVoice;
297  //Print("-----------------\ncurr:");
298  //do
299  //{
300  //Print("voice fn:%s\n",p->filename);
301  //p=p->prev;
302  //}
303  //while (p!=NULL);
304  //Print("----------------\n");
305  //}
306  if (currentVoice!=NULL)
307  {
308    if (currentVoice->oldb!=NULL)
309    {
310      myyoldbuffer(currentVoice->oldb);
311      currentVoice->oldb=NULL;
312    }
313    if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
314    {
315      currentVoice->prev=feInitStdin();
316    }
317    if (currentVoice->prev!=NULL)
318    {
319      //printf("exitVoice typ %d(%s)\n",
320      //  currentVoice->typ,BT_name[currentVoice->typ]);
321      if (currentVoice->typ==BT_if)
322      {
323        currentVoice->prev->ifsw=2;
324      }
325      else
326      {
327        currentVoice->prev->ifsw=0;
328      }
329      if ((currentVoice->sw == BI_file)
330      && (currentVoice->files!=NULL))
331      {
332        fclose(currentVoice->files);
333      }
334      if (currentVoice->filename!=NULL)
335      {
336        FreeL((ADDRESS)currentVoice->filename);
337        currentVoice->filename=NULL;
338      }
339      if (currentVoice->buffer!=NULL)
340      {
341        FreeL((ADDRESS)currentVoice->buffer);
342        currentVoice->buffer=NULL;
343      }
344      yylineno=currentVoice->prev->curr_lineno;
345      currentVoice->prev->next=NULL;
346    }
347    Voice *p=currentVoice->prev;
348    delete currentVoice;
349    currentVoice=p;
350  }
351  return currentVoice==NULL;
352}
353
354/*2
355* set prompt_char
356* only called with currentVoice->sw == BI_stdin
357*/
358static void feShowPrompt(void)
359{
360  fe_promptstr[0]=prompt_char;
361#ifdef macintosh
362  cols = 0;
363  printf(fe_promptstr);mflush();
364#endif
365}
366
367/*2
368* print echo (si_echo or TRACE), set my_yylinebuf
369*/
370static int fePrintEcho(char *anf, char *b)
371{
372  char *ss=strrchr(anf,'\n');
373  int len_s;
374  if (ss==NULL)
375  {
376    len_s=strlen(anf);
377  }
378  else
379  {
380    len_s=ss-anf+1;
381  }
382  // my_yylinebuf:
383  int mrc=min(len_s,79)-1;
384  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
385  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
386  mrc--;
387  // handle echo:
388  if (((si_echo>myynest)
389    && ((currentVoice->typ==BT_proc)
390      || (currentVoice->typ==BT_example)
391      || (currentVoice->typ==BT_file)
392      || (currentVoice->typ==BT_none)
393    )
394    && (strncmp(anf,";return();",10)!=0)
395   )
396  || (traceit&TRACE_SHOW_LINE)
397  || (traceit&TRACE_SHOW_LINE1))
398  {
399    if (currentVoice->typ!=BT_example)
400    {
401      if (currentVoice->filename==NULL)
402        Print("(none) %3d%c ",yylineno,prompt_char);
403      else
404        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
405     }
406    #ifdef HAVE_TCL
407    if(tclmode)
408    {
409      PrintTCL('N',len_s,anf);
410    }
411    else
412    #endif
413    {
414      fwrite(anf,1,len_s,stdout);
415      mflush();
416    }
417    if (traceit&TRACE_SHOW_LINE)
418    {
419      #ifdef HAVE_TCL
420      if(!tclmode)
421      #endif
422      while(fgetc(stdin)!='\n');
423    }
424  }
425  else if (traceit&TRACE_SHOW_LINENO)
426  {
427    Print("{%d}",yylineno);
428    mflush();
429  }
430  if ((blocknest==0)
431  && (currentVoice->pi!=NULL)
432  && (currentVoice->pi->trace_flag!=0))
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 = 0; /* 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      register int i=0;
452      long startfptr=currentVoice->fptr;
453      long tmp_ptr=currentVoice->fptr;
454      l--;
455      loop
456      {
457        register char c=
458        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
459        i++;
460        if (yy_noeof==noeof_block)
461        {
462          if (c<' ')  yylineno++;
463          else if (c=='}') break;
464        }
465        else
466        {
467          if ((c<' ') ||
468          (c==';') ||
469          (c==')')
470          )
471            break;
472        }
473        if (i>=l) break;
474        tmp_ptr++;/*currentVoice->fptr++;*/
475        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
476      }
477      currentVoice->fptr=tmp_ptr;
478      b[i]='\0';
479      if (currentVoice->sw==BI_buffer)
480      {
481        if (startfptr==0)
482        {
483          char *anf=currentVoice->buffer;
484          char *ss=strchr(anf,'\n');
485          int len;
486          if (ss==NULL) len=strlen(anf);
487          else          len=ss-anf;
488          char *s=(char *)AllocL(len+2);
489          strncpy(s,anf,len+2);
490          s[len+1]='\0';
491          fePrintEcho(s,b);
492          FreeL((ADDRESS)s);
493        }
494        else if (/*(startfptr>0) &&*/
495        (currentVoice->buffer[startfptr-1]=='\n'))
496        {
497          char *anf=currentVoice->buffer+startfptr;
498          char *ss=strchr(anf,'\n');
499          int len;
500          if (ss==NULL) len=strlen(anf);
501          else          len=ss-anf;
502          char *s=(char *)AllocL(len+2);
503          strncpy(s,anf,len+2);
504          s[len+1]='\0';
505          yylineno++;
506          fePrintEcho(s,b);
507          FreeL((ADDRESS)s);
508        }
509      }
510      currentVoice->fptr++;
511      return i;
512    }
513    // no buffer there or e-o-buffer or eoln:
514    if (currentVoice->sw!=BI_buffer)
515    {
516      currentVoice->fptr=0;
517      if (currentVoice->buffer==NULL)
518        currentVoice->buffer=(char *)AllocL(4096-sizeof(ADDRESS));
519    }
520    offset=0;
521  NewRead:
522    yylineno++;
523    if (currentVoice->sw==BI_stdin)
524    {
525      feShowPrompt();
526      s=fe_fgets_stdin(fe_promptstr,
527                       &(currentVoice->buffer[offset]),
528                       (4096-1-sizeof(ADDRESS))-offset);
529    }
530    else if (currentVoice->sw==BI_file)
531    {
532      s=fgets(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset,
533              currentVoice->files);
534    }
535    //else /* BI_buffer */ s==NULL  => return 0
536    // done by the default return
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,b)+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;
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        return 0;
584    }
585    Werror("premature end of file while reading %s",err);
586    return 0;
587  }
588}
589
590#ifdef __MWERKS__
591#ifdef __cplusplus
592extern "C" {
593#endif
594#ifdef macintosh
595int    isatty(int filedes);
596#else
597int    _isatty(int filedes);
598#define isatty  _isatty
599#endif /* macintosh */
600#ifdef __cplusplus
601}
602#endif
603#endif
604/*2
605* init all data structures
606*/
607#ifndef STDIN_FILENO
608#define STDIN_FILENO 0
609#endif
610Voice * feInitStdin()
611{
612  Voice *p = new Voice;
613  p->files = stdin;
614  #ifdef HAVE_TCL
615  p->sw = (tclmode || isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
616  #else
617  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
618  #endif
619  p->filename   = mstrdup("STDIN");
620  p->start_lineno   = 1;
621  return p;
622}
Note: See TracBrowser for help on using the repository browser.