source: git/Singular/febase.inc @ b5e952

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