source: git/Singular/febase.inc @ 8520b7

spielwiese
Last change on this file since 8520b7 was 8520b7, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: changed handling of "echo" in examples: do not report file + lineno (febase.inc,lib0lib.res, inoutlib.res, mem.res, homlib.res) git-svn-id: file:///usr/local/Singular/svn/trunk@1192 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.inc,v 1.4 1998-03-02 15:22:48 Singular Exp $ */
5/*
6* ABSTRACT: handling of 'voices'
7*/
8
9extern int noeof;
10int blocklineno;     // to get the lineno of the block start from scanner
11Voice  *currentVoice = NULL;
12FILE *feFilePending; /*temp. storage for grammar.y */
13
14static char * BT_name[]={"BT_none","BT_break","BT_proc","BT_example",
15                       "BT_file","BT_execute","BT_if","BT_else"};
16/*2
17* the name of the current 'Voice': the procname (or filename)
18*/
19const char * VoiceName()
20{
21  if ((currentVoice!=NULL)
22  && (currentVoice->filename!=NULL))
23    return currentVoice->filename;
24  return sNoName;
25}
26
27/*2
28* the calling chain of Voices
29*/
30void VoiceBackTrack()
31{
32  Voice *p=currentVoice;
33  while (p->prev!=NULL)
34  {
35    p=p->prev;
36    char *s=p->filename;
37    if (s==NULL)
38      PrintS("-- called from ? --\n");
39    else
40      Print("-- called from %s --\n",s);
41  }
42}
43
44/*2
45* init a new voice similiar to the current
46*/
47void Voice::Next()
48{
49  Voice *p=new Voice;
50  if (currentVoice != NULL)
51  {
52    currentVoice->curr_lineno=yylineno;
53    currentVoice->next=p;
54  }
55  p->prev=currentVoice;
56  currentVoice=p;
57  //Print("Next:");
58}
59
60feBufferTypes Voice::Typ()
61{
62  switch(typ)
63  {
64    case BT_proc:
65    case BT_example:
66    case BT_file:
67      return typ;
68    default:
69      if (prev==NULL) return (feBufferTypes)0;
70      return prev->Typ();
71  }
72}
73
74/*2
75* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
76* return FALSE on success, TRUE if an error occurs (file cannot be opened)
77*/
78BOOLEAN newFile(char *fname,FILE* f)
79{
80  currentVoice->Next();
81  //Print(":File%d(%s):%s(%x)\n",
82  //  currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
83  currentVoice->filename   = mstrdup(fname);
84  if (strcmp(fname,"STDIN") == 0)
85  {
86    currentVoice->files = stdin;
87    currentVoice->sw = BI_stdin;
88    currentVoice->start_lineno = 1;
89  }
90  else
91  {
92    currentVoice->sw = BI_file; /* needed by exitVoice below */
93    if (f!=NULL)
94      currentVoice->files = f;
95    else
96    {
97      currentVoice->files = feFopen(fname,"r",NULL,TRUE);
98      if (currentVoice->files==NULL)
99      {
100        exitVoice();
101        return TRUE;
102      }
103    }
104    currentVoice->start_lineno = 0;
105  }
106  yylineno=currentVoice->start_lineno;
107  //Voice *p=currentVoice;
108  //Print("-----------------\ncurr:");
109  //do
110  //{
111  //Print("voice fn:%s\n",p->filename);
112  //p=p->prev;
113  //}
114  //while (p!=NULL);
115  //Print("----------------\n");
116  return FALSE;
117}
118
119void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
120{
121  currentVoice->Next();
122  //Print(":Buffer%d(%s):%s(%x)\n",
123  //  t,BT_name[t],pname,currentVoice);
124  if (pi!=NULL)
125  {
126    int l=strlen(pi->procname);
127    if (pi->libname!=NULL) l+=strlen(pi->libname);
128    currentVoice->filename = (char *)AllocL(l+3);
129    *currentVoice->filename='\0';
130    if (pi->libname!=NULL) strcat(currentVoice->filename,pi->libname);
131    strcat(currentVoice->filename,"::");
132    strcat(currentVoice->filename,pi->procname);
133    currentVoice->pi       = pi;
134  }
135  else
136  {
137    currentVoice->filename = mstrdup(currentVoice->prev->filename);
138    currentVoice->pi       = currentVoice->prev->pi;
139  }
140  currentVoice->buffer   = s;
141  currentVoice->sw       = BI_buffer;
142  currentVoice->typ      = t;
143  switch (t)
144  {
145    case BT_execute:
146                     yylineno-=2;
147                     break;
148    case BT_proc:
149    case BT_example:
150                     currentVoice->oldb=myynewbuffer();
151                     yylineno = lineno+1;
152                     break;
153    case BT_if:
154    case BT_else:
155                     yylineno = blocklineno;
156                     break;
157    case BT_break:
158                     yylineno = blocklineno-1;
159                     break;
160    //case BT_file:
161    default:
162                     yylineno = 1;
163                     break;
164  }
165  //Print("start body (%s) at line %d\n",BT_name[t],yylineno);
166  currentVoice->start_lineno = yylineno;
167  //printf("start buffer typ %d\n",t);
168  //Voice *p=currentVoice;
169  //Print("-----------------\ncurr:");
170  //do
171  //{
172  //Print("voice fn:%s\n",p->filename);
173  //p=p->prev;
174  //}
175  //while (p!=NULL);
176  //Print("----------------\n");
177}
178
179/*2
180* exit Buffer of type 'typ':
181* returns 1 if buffer type could not be found
182*/
183BOOLEAN exitBuffer(feBufferTypes typ)
184{
185  //printf("exitBuffer: %d(%s),(%x)\n",
186  //  typ,BT_name[typ], currentVoice);
187  //Voice *p=currentVoice;
188  //Print("-----------------\ncurr:");
189  //do
190  //{
191  //Print("voice fn:%s\n",p->filename);
192  //p=p->prev;
193  //}
194  //while (p!=NULL);
195  //Print("----------------\n");
196  if (typ == BT_break)  // valid inside for, while. may skip if, else
197  {
198    /*4 first check for valid buffer type, skip if/else*/
199    Voice *p=currentVoice;
200    loop
201    {
202      if ((p->typ != BT_if)
203      &&(p->typ != BT_else))
204      {
205        if (p->typ == BT_break /*typ*/)
206        {
207          while (p != currentVoice)
208          {
209            exitVoice();
210          }
211          exitVoice();
212          return FALSE;
213        }
214        else return TRUE;
215      }
216      if (p->prev==NULL) break;
217      p=p->prev;
218    }
219    /*4 break not inside a for/while: return an error*/
220    if (/*typ*/ BT_break != currentVoice->typ) return 1;
221    return exitVoice();
222  }
223
224  if ((typ == BT_proc)
225  || (typ == BT_example))
226  {
227    Voice *p=currentVoice;
228    loop
229    {
230      if ((p->typ == BT_proc)
231      || (p->typ == BT_example))
232      {
233        while (p != currentVoice)
234        {
235          exitVoice();
236        }
237        exitVoice();
238        return FALSE;
239      }
240      if (p->prev==NULL) break;
241      p=p->prev;
242    }
243  }
244  /*4 return not inside a proc: return an error*/
245  return TRUE;
246}
247
248/*2
249* jump to the beginning of a buffer
250*/
251BOOLEAN contBuffer(feBufferTypes typ)
252{
253  //printf("contBuffer: %d(%s),(%x)\n",
254  //  typ,BT_name[typ], currentVoice);
255  if (typ == BT_break)  // valid inside for, while. may skip if, else
256  {
257    // first check for valid buffer type
258    Voice *p=currentVoice;
259    loop
260    {
261      if ((p->typ != BT_if)
262        &&(p->typ != BT_else))
263      {
264        if (p->typ == BT_break /*typ*/)
265        {
266          while (p != currentVoice)
267          {
268            exitVoice();
269          }
270          yylineno = currentVoice->start_lineno;
271          currentVoice->fptr=0;
272          return FALSE;
273        }
274        else return TRUE;
275      }
276      if (p->prev==NULL) break;
277      p=p->prev;
278    }
279  }
280  return TRUE;
281}
282
283/*2
284* leave a voice: kill local variables
285* setup everything from the previous level
286* return 1 if leaving the top level, 0 otherwise
287*/
288BOOLEAN exitVoice()
289{
290  //printf("exitVoice: %d(%s),(%x)\n",
291  //  currentVoice->typ,BT_name[currentVoice->typ], currentVoice);
292  //{
293  //Voice *p=currentVoice;
294  //Print("-----------------\ncurr:");
295  //do
296  //{
297  //Print("voice fn:%s\n",p->filename);
298  //p=p->prev;
299  //}
300  //while (p!=NULL);
301  //Print("----------------\n");
302  //}
303  if (currentVoice->oldb!=NULL)
304  {
305    myyoldbuffer(currentVoice->oldb);
306    currentVoice->oldb=NULL;
307  }
308  if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
309  {
310    currentVoice->prev=feInitStdin();
311  }
312  if (currentVoice->prev!=NULL)
313  {
314    //printf("exitVoice typ %d(%s)\n",
315    //  currentVoice->typ,BT_name[currentVoice->typ]);
316    if (currentVoice->typ==BT_if)
317    {
318      currentVoice->prev->ifsw=2;
319    }
320    else
321    {
322      currentVoice->prev->ifsw=BI_stdin;
323    }
324    if ((currentVoice->sw == BI_file)
325    && (currentVoice->files!=NULL))
326    {
327      fclose(currentVoice->files);
328    }
329    if (currentVoice->filename!=NULL)
330    {
331      FreeL((ADDRESS)currentVoice->filename);
332      currentVoice->filename=NULL;
333    }
334    if (currentVoice->buffer!=NULL)
335    {
336      FreeL((ADDRESS)currentVoice->buffer);
337      currentVoice->buffer=NULL;
338    }
339    yylineno=currentVoice->prev->curr_lineno;
340  }
341  Voice *p=currentVoice->prev;
342  delete currentVoice;
343  currentVoice=p;
344  return currentVoice==0;
345}
346
347/*2
348* set prompt_char
349* only called with currentVoice->sw == BI_stdin
350*/
351static void feShowPrompt(void)
352{
353  //if (currentVoice->sw == BI_stdin)
354  {
355#ifdef HAVE_TCL
356    if (tclmode)
357    {
358       PrintTCL('P',(prompt_char=='>')? 0 : 1,NULL);
359    }
360    else
361#endif
362    if ((BVERBOSE(V_PROMPT))&&(!feBatch))
363    {
364      fe_promptstr[0]=prompt_char;
365#ifndef HAVE_READLINE
366      PrintS(fe_promptstr);
367#endif
368    }
369    mflush();
370#ifdef macintosh
371    cols = 0;
372#endif
373  }
374}
375
376/*2
377* print echo (si_echo or TRACE), set my_yylinebuf
378*/
379static int fePrintEcho(char *anf)
380{
381  char *ss=strchr(anf,'\n');
382  int len_s;
383  if (ss==NULL)
384  {
385    len_s=strlen(anf);
386  }
387  else
388  {
389    len_s=ss-anf+1;
390  }
391  // my_yylinebuf:
392  int mrc=min(len_s,80)-1;
393  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
394  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
395  mrc--;
396  // handle echo:
397  if (((si_echo>myynest)
398    && ((currentVoice->typ==BT_proc)
399      || (currentVoice->typ==BT_example)
400      || (currentVoice->typ==BT_file)
401      || (currentVoice->typ==BT_none)
402    )
403    && (strncmp(anf,";return();",10)!=0)
404   )
405  || (traceit&TRACE_SHOW_LINE)
406  || (traceit&TRACE_SHOW_LINE1))
407  {
408    if (currentVoice->typ!=BT_example)
409    {
410      if (currentVoice->filename==NULL)
411        Print("(none) %3d%c ",yylineno,prompt_char);
412      else
413        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
414    }
415    fwrite(anf,1,len_s,stdout);
416    mflush();
417    if (traceit&TRACE_SHOW_LINE)
418    {
419      while(fgetc(stdin)!='\n');
420    }
421  }
422  else if (traceit&TRACE_SHOW_LINENO)
423  {
424    printf("{%d}",yylineno);
425    mflush();
426  }
427  prompt_char = '.';
428  return len_s;
429}
430
431int feReadLine(char* b, int l)
432{
433  // try to read from the buffer:
434  b[1] = '\0';
435  if ((currentVoice->buffer!=NULL)
436  && (currentVoice->buffer[currentVoice->fptr]!='\0'))
437  {
438NewBuff:
439    b[0]=currentVoice->buffer[currentVoice->fptr];
440    if (currentVoice->sw==BI_buffer)
441    {
442      if (currentVoice->fptr==0)
443      {
444        char *anf=currentVoice->buffer;
445        char *ss=strchr(anf,'\n');
446        int len;
447        if (ss==NULL) len=strlen(anf);
448        else          len=ss-anf;
449        char *s=(char *)AllocL(len+2);
450        strncpy(s,anf,len+2);
451        s[len+1]='\0';
452        fePrintEcho(s);
453        FreeL((ADDRESS)s);
454      }
455      else if (/*(currentVoice->fptr>0) &&*/
456      (currentVoice->buffer[currentVoice->fptr-1]=='\n'))
457      {
458        char *anf=currentVoice->buffer+currentVoice->fptr;
459        char *ss=strchr(anf,'\n');
460        int len;
461        if (ss==NULL) len=strlen(anf);
462        else          len=ss-anf;
463        char *s=(char *)AllocL(len+2);
464        strncpy(s,anf,len+2);
465        s[len+1]='\0';
466        yylineno++;
467        fePrintEcho(s);
468        FreeL((ADDRESS)s);
469      }
470    }
471    currentVoice->fptr++;
472    return 1;
473  }
474  // no buffer there or e-o-buffer or eoln:
475  if (currentVoice->sw!=BI_buffer)
476  {
477    currentVoice->fptr=0;
478    if (currentVoice->buffer==NULL)
479      currentVoice->buffer=(char *)AllocL(4096-sizeof(ADDRESS));
480  }
481  char *s;
482  int offset=0;
483NewRead:
484  yylineno++;
485  if (currentVoice->sw==BI_stdin)
486  {
487    feShowPrompt();
488    s=fe_fgets_stdin(currentVoice->buffer+offset,(4096-sizeof(ADDRESS))-offset);
489  }
490  else if (currentVoice->sw==BI_file)
491    s=fgets(currentVoice->buffer+offset,(4096-sizeof(ADDRESS))-offset,
492            currentVoice->files);
493  else /* BI_buffer */
494  {
495    return 0;
496  }
497  if (s!=NULL)
498  {
499    // handle prot:
500    if (feProt&PROT_I)
501    {
502      fputs(s,feProtFile);
503    }
504    int rc=fePrintEcho(s)-2;
505    // handel \\ :
506    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
507    {
508      s[rc]='\0';
509      offset+=rc;
510      if (offset<(int)mmSizeL(currentVoice->buffer)) goto NewRead;
511    }
512    goto NewBuff;
513  }
514  /* else if (s==NULL) */
515  {
516    switch(noeof)
517    {
518      case 0:
519        return 0;
520      case noeof_brace:
521      case noeof_block:
522        WerrorS("premature end of file while reading {...}");
523        break;
524      case noeof_asstring:
525        WerrorS("premature end of file while reading till `.`");
526        break;
527      case noeof_string:
528        WerrorS("premature end of file while reading string");
529        break;
530      case noeof_bracket:
531        WerrorS("premature end of file while reading (...)");
532        break;
533      case noeof_procname:
534        WerrorS("premature end of file while reading proc");
535        break;
536    }
537    return 0;
538  }
539}
540
541/*2
542* init all data structures
543*/
544#ifndef STDIN_FILENO
545#define STDIN_FILENO 0
546#endif
547Voice * feInitStdin()
548{
549  Voice *p = new Voice;
550  p->files = stdin;
551  p->sw = isatty(STDIN_FILENO) ? BI_stdin : BI_file;
552  p->filename   = mstrdup("STDIN");
553  p->start_lineno   = 1;
554  return p;
555}
Note: See TracBrowser for help on using the repository browser.