source: git/Singular/febase.inc @ 82716e

spielwiese
Last change on this file since 82716e was a7fc7dd, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: added syntax rule "proc <name> <arglist> <string> <body>" git-svn-id: file:///usr/local/Singular/svn/trunk@1654 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.inc,v 1.10 1998-05-07 17:53:25 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->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 into b, max l chars
435  if ((currentVoice->buffer!=NULL)
436  && (currentVoice->buffer[currentVoice->fptr]!='\0'))
437  {
438NewBuff:
439    int i=0;
440    int startfptr=currentVoice->fptr;
441    l--;
442    loop
443    {
444      char c=
445      b[i]=currentVoice->buffer[currentVoice->fptr];
446      i++;
447      if (yy_noeof==noeof_block)
448      {
449        if (c<' ')  yylineno++;
450        else if (c=='}') break;
451      }
452      else
453      {
454        if ((c<' ') ||
455        (c==';') ||
456        (c==')')
457        )
458          break;
459      }         
460      if (i>=l) break;
461      currentVoice->fptr++;
462      if(currentVoice->buffer[currentVoice->fptr]=='\0') break;
463    }
464    b[i]='\0';
465    if (currentVoice->sw==BI_buffer)
466    {
467      if (startfptr==0)
468      {
469        char *anf=currentVoice->buffer;
470        char *ss=strchr(anf,'\n');
471        int len;
472        if (ss==NULL) len=strlen(anf);
473        else          len=ss-anf;
474        char *s=(char *)AllocL(len+2);
475        strncpy(s,anf,len+2);
476        s[len+1]='\0';
477        fePrintEcho(s);
478        FreeL((ADDRESS)s);
479      }
480      else if (/*(startfptr>0) &&*/
481      (currentVoice->buffer[startfptr-1]=='\n'))
482      {
483        char *anf=currentVoice->buffer+startfptr;
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        yylineno++;
492        fePrintEcho(s);
493        FreeL((ADDRESS)s);
494      }
495    }
496    currentVoice->fptr++;
497    return i;
498  }
499  // no buffer there or e-o-buffer or eoln:
500  if (currentVoice->sw!=BI_buffer)
501  {
502    currentVoice->fptr=0;
503    if (currentVoice->buffer==NULL)
504      currentVoice->buffer=(char *)AllocL(4096-sizeof(ADDRESS));
505  }
506  char *s;
507  int offset=0;
508NewRead:
509  yylineno++;
510  if (currentVoice->sw==BI_stdin)
511  {
512    feShowPrompt();
513    s=fe_fgets_stdin(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset);
514  }
515  else if (currentVoice->sw==BI_file)
516  {
517    s=fgets(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset,
518            currentVoice->files);
519  }
520  else /* BI_buffer */
521  {
522    return 0;
523  }
524  if (s!=NULL)
525  {
526    // handle prot:
527    if (feProt&PROT_I)
528    {
529      fputs(s,feProtFile);
530    }
531    int rc=fePrintEcho(s)+1;
532    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
533    s[rc]='\0';
534    // handel \\ :
535    rc-=3;
536    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
537    {
538      s[rc]='\0';
539      offset+=rc;
540      if (offset<(int)mmSizeL(currentVoice->buffer)) goto NewRead;
541    }
542    goto NewBuff;
543  }
544  /* else if (s==NULL) */
545  {
546    switch(yy_noeof)
547    {
548      case 0:
549        return 0;
550      case noeof_brace:
551      case noeof_block:
552        WerrorS("premature end of file while reading {...}");
553        break;
554      case noeof_asstring:
555        WerrorS("premature end of file while reading till `.`");
556        break;
557      case noeof_string:
558        WerrorS("premature end of file while reading string");
559        break;
560      case noeof_bracket:
561        WerrorS("premature end of file while reading (...)");
562        break;
563      case noeof_procname:
564        WerrorS("premature end of file while reading proc");
565        break;
566    }
567    return 0;
568  }
569}
570
571#ifdef __MWERKS__
572#ifdef __cplusplus
573extern "C" {
574#endif
575#ifdef macintosh
576int    isatty(int filedes);
577#else
578int    _isatty(int filedes);
579#define isatty  _isatty
580#endif /* macintosh */
581#ifdef __cplusplus
582}
583#endif
584#endif
585/*2
586* init all data structures
587*/
588#ifndef STDIN_FILENO
589#define STDIN_FILENO 0
590#endif
591Voice * feInitStdin()
592{
593  Voice *p = new Voice;
594  p->files = stdin;
595  p->sw = isatty(STDIN_FILENO) ? BI_stdin : BI_file;
596  p->filename   = mstrdup("STDIN");
597  p->start_lineno   = 1;
598  return p;
599}
Note: See TracBrowser for help on using the repository browser.