source: git/Singular/febase.inc @ 2f7502

spielwiese
Last change on this file since 2f7502 was 2f7502, checked in by Hans Schönemann <hannes@…>, 24 years ago
*hannes: multiple line input git-svn-id: file:///usr/local/Singular/svn/trunk@4145 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.inc,v 1.29 2000-02-14 17:00:10 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      currentVoice->prev->next=NULL;
345    }
346    Voice *p=currentVoice->prev;
347    delete currentVoice;
348    currentVoice=p;
349  }
350  return currentVoice==NULL;
351}
352
353/*2
354* set prompt_char
355* only called with currentVoice->sw == BI_stdin
356*/
357static void feShowPrompt(void)
358{
359  fe_promptstr[0]=prompt_char;
360#ifdef macintosh
361  cols = 0;
362  printf(fe_promptstr);mflush();
363#endif
364}
365
366/*2
367* print echo (si_echo or TRACE), set my_yylinebuf
368*/
369static int fePrintEcho(char *anf, char *b)
370{
371  char *ss=strrchr(anf,'\n');
372  int len_s;
373  if (ss==NULL)
374  {
375    len_s=strlen(anf);
376  }
377  else
378  {
379    len_s=ss-anf+1;
380  }
381  // my_yylinebuf:
382  int mrc=min(len_s,79)-1;
383  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
384  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
385  mrc--;
386  // handle echo:
387  if (((si_echo>myynest)
388    && ((currentVoice->typ==BT_proc)
389      || (currentVoice->typ==BT_example)
390      || (currentVoice->typ==BT_file)
391      || (currentVoice->typ==BT_none)
392    )
393    && (strncmp(anf,";return();",10)!=0)
394   )
395  || (traceit&TRACE_SHOW_LINE)
396  || (traceit&TRACE_SHOW_LINE1))
397  {
398    if (currentVoice->typ!=BT_example)
399    {
400      if (currentVoice->filename==NULL)
401        Print("(none) %3d%c ",yylineno,prompt_char);
402      else
403        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
404     }
405    #ifdef HAVE_TCL
406    if(tclmode)
407    {
408      PrintTCL('N',len_s,anf);
409    }
410    else
411    #endif
412    {
413      fwrite(anf,1,len_s,stdout);
414      mflush();
415    }
416    if (traceit&TRACE_SHOW_LINE)
417    {
418      #ifdef HAVE_TCL
419      if(!tclmode)
420      #endif
421      while(fgetc(stdin)!='\n');
422    }
423  }
424  else if (traceit&TRACE_SHOW_LINENO)
425  {
426    Print("{%d}",yylineno);
427    mflush();
428  }
429  if ((blocknest==0)
430  && (currentVoice->pi!=NULL)
431  && (currentVoice->pi->trace_flag!=0))
432  {
433    sdb(currentVoice, anf, len_s);
434  }
435  prompt_char = '.';
436  return len_s;
437}
438
439int feReadLine(char* b, int l)
440{
441  char *s=NULL;
442  int offset; /* will not be used if s==NULL*/
443  // try to read from the buffer into b, max l chars
444  if (currentVoice!=NULL)
445  {
446    if((currentVoice->buffer!=NULL)
447    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
448    {
449  NewBuff:
450      register int i=0;
451      long startfptr=currentVoice->fptr;
452      long tmp_ptr=currentVoice->fptr;
453      l--;
454      loop
455      {
456        register char c=
457        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
458        i++;
459        if (yy_noeof==noeof_block)
460        {
461          if (c<' ')  yylineno++;
462          else if (c=='}') break;
463        }
464        else
465        {
466          if ((c<' ') ||
467          (c==';') ||
468          (c==')')
469          )
470            break;
471        }
472        if (i>=l) break;
473        tmp_ptr++;/*currentVoice->fptr++;*/
474        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
475      }
476      currentVoice->fptr=tmp_ptr;
477      b[i]='\0';
478      if (currentVoice->sw==BI_buffer)
479      {
480        if (startfptr==0)
481        {
482          char *anf=currentVoice->buffer;
483          char *ss=strchr(anf,'\n');
484          int len;
485          if (ss==NULL) len=strlen(anf);
486          else          len=ss-anf;
487          char *s=(char *)AllocL(len+2);
488          strncpy(s,anf,len+2);
489          s[len+1]='\0';
490          fePrintEcho(s,b);
491          FreeL((ADDRESS)s);
492        }
493        else if (/*(startfptr>0) &&*/
494        (currentVoice->buffer[startfptr-1]=='\n'))
495        {
496          char *anf=currentVoice->buffer+startfptr;
497          char *ss=strchr(anf,'\n');
498          int len;
499          if (ss==NULL) len=strlen(anf);
500          else          len=ss-anf;
501          char *s=(char *)AllocL(len+2);
502          strncpy(s,anf,len+2);
503          s[len+1]='\0';
504          yylineno++;
505          fePrintEcho(s,b);
506          FreeL((ADDRESS)s);
507        }
508      }
509      currentVoice->fptr++;
510      return i;
511    }
512    // no buffer there or e-o-buffer or eoln:
513    if (currentVoice->sw!=BI_buffer)
514    {
515      currentVoice->fptr=0;
516      if (currentVoice->buffer==NULL)
517        currentVoice->buffer=(char *)AllocL(4096-sizeof(ADDRESS));
518    }
519    offset=0;
520  NewRead:
521    yylineno++;
522    if (currentVoice->sw==BI_stdin)
523    {
524      feShowPrompt();
525      s=fe_fgets_stdin(fe_promptstr,
526                       &(currentVoice->buffer[offset]),
527                       (4096-1-sizeof(ADDRESS))-offset);
528    }
529    else if (currentVoice->sw==BI_file)
530    {
531      s=fgets(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset,
532              currentVoice->files);
533    }
534    //else /* BI_buffer */ s==NULL  => return 0
535    // done by the default return
536  }
537  if (s!=NULL)
538  {
539    // handle prot:
540    if (feProt&PROT_I)
541    {
542      fputs(s,feProtFile);
543    }
544    int rc=fePrintEcho(s,b)+1;
545    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
546    s[rc]='\0';
547    // handel \\ :
548    rc-=3;
549    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
550    {
551      s[rc]='\0';
552      offset+=rc;
553      if (offset<(int)mmSizeL(currentVoice->buffer)) goto NewRead;
554    }
555    goto NewBuff;
556  }
557  /* else if (s==NULL) */
558  {
559    char *err;
560    switch(yy_noeof)
561    {
562      case noeof_brace:
563      case noeof_block:
564        err="{...}";
565        break;
566      case noeof_asstring:
567        err="till `.`";
568        break;
569      case noeof_string:
570        err="string";
571        break;
572      case noeof_bracket:
573        err="(...)";
574        break;
575      case noeof_procname:
576        err="proc";
577        break;
578      case noeof_comment:
579        err="/*...*/";
580        break;
581      default:
582        return 0;
583    }
584    Werror("premature end of file while reading %s",err);
585    return 0;
586  }
587}
588
589#ifdef __MWERKS__
590#ifdef __cplusplus
591extern "C" {
592#endif
593#ifdef macintosh
594int    isatty(int filedes);
595#else
596int    _isatty(int filedes);
597#define isatty  _isatty
598#endif /* macintosh */
599#ifdef __cplusplus
600}
601#endif
602#endif
603/*2
604* init all data structures
605*/
606#ifndef STDIN_FILENO
607#define STDIN_FILENO 0
608#endif
609Voice * feInitStdin()
610{
611  Voice *p = new Voice;
612  p->files = stdin;
613  #ifdef HAVE_TCL
614  p->sw = (tclmode || isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
615  #else
616  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
617  #endif
618  p->filename   = mstrdup("STDIN");
619  p->start_lineno   = 1;
620  return p;
621}
Note: See TracBrowser for help on using the repository browser.