source: git/Singular/febase.inc @ 647b6d9

spielwiese
Last change on this file since 647b6d9 was 647b6d9, checked in by Wilfred Pohl <pohl@…>, 26 years ago
isatty for Metrowerks git-svn-id: file:///usr/local/Singular/svn/trunk@1507 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.inc,v 1.7 1998-04-28 08:57:23 pohl 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->oldb!=NULL)
305  {
306    myyoldbuffer(currentVoice->oldb);
307    currentVoice->oldb=NULL;
308  }
309  if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
310  {
311    currentVoice->prev=feInitStdin();
312  }
313  if (currentVoice->prev!=NULL)
314  {
315    //printf("exitVoice typ %d(%s)\n",
316    //  currentVoice->typ,BT_name[currentVoice->typ]);
317    if (currentVoice->typ==BT_if)
318    {
319      currentVoice->prev->ifsw=2;
320    }
321    else
322    {
323      currentVoice->prev->ifsw=0;
324    }
325    if ((currentVoice->sw == BI_file)
326    && (currentVoice->files!=NULL))
327    {
328      fclose(currentVoice->files);
329    }
330    if (currentVoice->filename!=NULL)
331    {
332      FreeL((ADDRESS)currentVoice->filename);
333      currentVoice->filename=NULL;
334    }
335    if (currentVoice->buffer!=NULL)
336    {
337      FreeL((ADDRESS)currentVoice->buffer);
338      currentVoice->buffer=NULL;
339    }
340    yylineno=currentVoice->prev->curr_lineno;
341  }
342  Voice *p=currentVoice->prev;
343  delete currentVoice;
344  currentVoice=p;
345  return currentVoice==0;
346}
347
348/*2
349* set prompt_char
350* only called with currentVoice->sw == BI_stdin
351*/
352static void feShowPrompt(void)
353{
354  //if (currentVoice->sw == BI_stdin)
355  {
356#ifdef HAVE_TCL
357    if (tclmode)
358    {
359       PrintTCL('P',(prompt_char=='>')? 0 : 1,NULL);
360    }
361    else
362#endif
363    if ((BVERBOSE(V_PROMPT))&&(!feBatch))
364    {
365      fe_promptstr[0]=prompt_char;
366#ifndef HAVE_READLINE
367      PrintS(fe_promptstr);
368#endif
369    }
370    mflush();
371#ifdef macintosh
372    cols = 0;
373#endif
374  }
375}
376
377/*2
378* print echo (si_echo or TRACE), set my_yylinebuf
379*/
380static int fePrintEcho(char *anf)
381{
382  char *ss=strchr(anf,'\n');
383  int len_s;
384  if (ss==NULL)
385  {
386    len_s=strlen(anf);
387  }
388  else
389  {
390    len_s=ss-anf+1;
391  }
392  // my_yylinebuf:
393  int mrc=min(len_s,80)-1;
394  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
395  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
396  mrc--;
397  // handle echo:
398  if (((si_echo>myynest)
399    && ((currentVoice->typ==BT_proc)
400      || (currentVoice->typ==BT_example)
401      || (currentVoice->typ==BT_file)
402      || (currentVoice->typ==BT_none)
403    )
404    && (strncmp(anf,";return();",10)!=0)
405   )
406  || (traceit&TRACE_SHOW_LINE)
407  || (traceit&TRACE_SHOW_LINE1))
408  {
409    if (currentVoice->typ!=BT_example)
410    {
411      if (currentVoice->filename==NULL)
412        Print("(none) %3d%c ",yylineno,prompt_char);
413      else
414        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
415    }
416    fwrite(anf,1,len_s,stdout);
417    mflush();
418    if (traceit&TRACE_SHOW_LINE)
419    {
420      while(fgetc(stdin)!='\n');
421    }
422  }
423  else if (traceit&TRACE_SHOW_LINENO)
424  {
425    printf("{%d}",yylineno);
426    mflush();
427  }
428  prompt_char = '.';
429  return len_s;
430}
431
432int feReadLine(char* b, int l)
433{
434  // try to read from the buffer:
435  // b[1] = '\0';
436  if ((currentVoice->buffer!=NULL)
437  && (currentVoice->buffer[currentVoice->fptr]!='\0'))
438  {
439NewBuff:
440    int i=0;
441    int startfptr=currentVoice->fptr;
442    l--;
443    loop
444    {
445      char c=
446      b[i]=currentVoice->buffer[currentVoice->fptr];
447      i++;
448      if ((c<' ')
449      || (c==';')
450      || (c==')')
451      || (c=='}')
452      || (c=='"')
453      || (c=='$')) break;
454      if (i>=l) break;
455      currentVoice->fptr++;
456      if(currentVoice->buffer[currentVoice->fptr]=='\0') break;
457    }
458    b[i]='\0';
459    if (currentVoice->sw==BI_buffer)
460    {
461      if (startfptr==0)
462      {
463        char *anf=currentVoice->buffer;
464        char *ss=strchr(anf,'\n');
465        int len;
466        if (ss==NULL) len=strlen(anf);
467        else          len=ss-anf;
468        char *s=(char *)AllocL(len+2);
469        strncpy(s,anf,len+2);
470        s[len+1]='\0';
471        fePrintEcho(s);
472        FreeL((ADDRESS)s);
473      }
474      else if (/*(startfptr>0) &&*/
475      (currentVoice->buffer[startfptr-1]=='\n'))
476      {
477        char *anf=currentVoice->buffer+startfptr;
478        char *ss=strchr(anf,'\n');
479        int len;
480        if (ss==NULL) len=strlen(anf);
481        else          len=ss-anf;
482        char *s=(char *)AllocL(len+2);
483        strncpy(s,anf,len+2);
484        s[len+1]='\0';
485        yylineno++;
486        fePrintEcho(s);
487        FreeL((ADDRESS)s);
488      }
489    }
490    currentVoice->fptr++;
491    return i;
492  }
493  // no buffer there or e-o-buffer or eoln:
494  if (currentVoice->sw!=BI_buffer)
495  {
496    currentVoice->fptr=0;
497    if (currentVoice->buffer==NULL)
498      currentVoice->buffer=(char *)AllocL(4096-sizeof(ADDRESS));
499  }
500  char *s;
501  int offset=0;
502NewRead:
503  yylineno++;
504  if (currentVoice->sw==BI_stdin)
505  {
506    feShowPrompt();
507    s=fe_fgets_stdin(currentVoice->buffer+offset,(4096-sizeof(ADDRESS))-offset);
508  }
509  else if (currentVoice->sw==BI_file)
510    s=fgets(currentVoice->buffer+offset,(4096-sizeof(ADDRESS))-offset,
511            currentVoice->files);
512  else /* BI_buffer */
513  {
514    return 0;
515  }
516  if (s!=NULL)
517  {
518    // handle prot:
519    if (feProt&PROT_I)
520    {
521      fputs(s,feProtFile);
522    }
523    int rc=fePrintEcho(s)-2;
524    // handel \\ :
525    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
526    {
527      s[rc]='\0';
528      offset+=rc;
529      if (offset<(int)mmSizeL(currentVoice->buffer)) goto NewRead;
530    }
531    goto NewBuff;
532  }
533  /* else if (s==NULL) */
534  {
535    switch(yy_noeof)
536    {
537      case 0:
538        return 0;
539      case noeof_brace:
540      case noeof_block:
541        WerrorS("premature end of file while reading {...}");
542        break;
543      case noeof_asstring:
544        WerrorS("premature end of file while reading till `.`");
545        break;
546      case noeof_string:
547        WerrorS("premature end of file while reading string");
548        break;
549      case noeof_bracket:
550        WerrorS("premature end of file while reading (...)");
551        break;
552      case noeof_procname:
553        WerrorS("premature end of file while reading proc");
554        break;
555    }
556    return 0;
557  }
558}
559
560#ifdef __MWERKS__
561#ifdef __cplusplus
562extern "C" {
563#endif
564#ifdef macintosh
565int    isatty(int filedes);
566#else
567int    _isatty(int filedes);
568#define isatty  _isatty
569#endif /* macintosh */
570#ifdef __cplusplus
571}
572#endif
573#endif
574/*2
575* init all data structures
576*/
577#ifndef STDIN_FILENO
578#define STDIN_FILENO 0
579#endif
580Voice * feInitStdin()
581{
582  Voice *p = new Voice;
583  p->files = stdin;
584  p->sw = isatty(STDIN_FILENO) ? BI_stdin : BI_file;
585  p->filename   = mstrdup("STDIN");
586  p->start_lineno   = 1;
587  return p;
588}
Note: See TracBrowser for help on using the repository browser.