source: git/Singular/febase.cc @ b97e94

spielwiese
Last change on this file since b97e94 was b97e94, checked in by Hans Schönemann <hannes@…>, 27 years ago
* hannes: fixed strlen bud in febase.cc: StringAppendS git-svn-id: file:///usr/local/Singular/svn/trunk@75 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 19.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4static char rcsid[] = "$Id: febase.cc,v 1.4 1997-03-25 12:40:45 Singular Exp $";
5/*
6* ABSTRACT: i/o system, handling of 'voices'
7*/
8
9#include <stdlib.h>
10#include <string.h>
11#include <stdio.h>
12#include <limits.h>
13#include <stdarg.h>
14#ifndef macintosh
15#include <unistd.h>
16#endif
17#ifdef NeXT
18#include <sys/file.h>
19#endif
20#include "mod2.h"
21#include "tok.h"
22#include "febase.h"
23#include "mmemory.h"
24#include "subexpr.h"
25#include "ipshell.h"
26
27#define fePutChar(c) fputc((uchar)(c),stdout)
28/*0 implementation */
29
30char fe_promptstr[]
31#ifdef macintosh
32                   =" \n";
33#else
34                   ="  ";
35#endif
36
37class Voices
38{
39  private:
40    void Init()
41    {
42      memset(this,0,sizeof(*this));
43      v_lineno = 1;
44    }
45  public:
46    int    v_lineno;        // lineno, to restore in recursion
47    int    v_oldlineno;     // lineno, to restore at exit
48    int    typ;             // buffer type: see BT_..
49    int    v_echo;          // echo, to restore in recursion
50    int    v_fileVoice;     // to be restored in recursion
51    int    v_inputswitch;   // ??
52    FILE * files;           // file handle
53    long   fptr;            // file | buffer seek
54    char*  filename;        // file name
55    char * buffer;          // buffer pointer
56
57  void Next();
58  Voices() { Init(); }
59  Voices * VFile(char* fname);
60  Voices * Buffer(char* buf, int t);
61  int Exit();
62} ;
63
64
65extern FILE* yyin;
66
67#define INITIAL_PRINT_BUFFER 24*1024
68static int feBufferLength=INITIAL_PRINT_BUFFER;
69static char * feBuffer;
70
71#define START_LEVMAX 32
72int     levmax       = START_LEVMAX;
73Voices *currentVoice = NULL;
74Voices *FileAttribs  =(Voices *)Alloc(START_LEVMAX*sizeof(Voices));
75short  *ifswitch     =(short *)Alloc0(START_LEVMAX*sizeof(short));
76        /*1 ifswitch==0: no if statement, else is invalid
77        *           ==1: if (0) processed, execute else
78        *           ==2: if (1) processed, else allowed but not executed
79        */
80int     si_echo = 0;
81int     printlevel = 0;
82int     fileVoice = 0;
83#ifndef macintosh
84int     pagelength = 24;
85#else
86int     pagelength = -1;
87#endif
88int     colmax = 80;
89int     voice = 0;
90int     inputswitch = 0;
91int     blocklineno = 0;
92char    prompt_char = '>'; /*1 either '>' or '.'*/
93BITSET  verbose = 1
94                  | Sy_bit(V_REDEFINE)
95                  | Sy_bit(V_LOAD_LIB)
96                  | Sy_bit(V_SHOW_USE)
97                  | Sy_bit(V_PROMPT)
98//                  | Sy_bit(V_DEBUG_MEM)
99                  ;
100BOOLEAN errorreported = FALSE;
101BOOLEAN feBatch;
102char *  feErrors=NULL;
103int     feErrorsLen=0;
104
105BOOLEAN feProt = FALSE;
106FILE*   feProtFile;
107BOOLEAN tclmode=FALSE;
108/* TCL-Protocoll (Singular -x): <char type>:<int length>:<string> \n
109*  E:l:s  error - not implemented yet (use N)
110*  W:l:s  warning
111*  N:l:s  stdout
112*  Q:0:   quit
113*  P:0:   prompt >
114*  P:1:   prompt .
115*  R:l:<ring-name> ring change
116* plan:
117*  O:l:<option/no-option> option change (option)
118*  V:l:<option/no-option> option change (verbose)
119*/
120
121/*2
122* fopen, but use 'SingularPath' from environment and '/usr/local/Singular'
123*/
124#ifdef macintosh
125#  define  FS_SEP ','
126#  define  DIR_SEP ':'
127#  define  DIR_SEPP ":"
128#else
129#ifdef MSDOS
130#  define  FS_SEP ';'
131#  define  DIR_SEP '\\'
132#  define  DIR_SEPP "\\"
133#else
134#ifdef atarist
135#  define  FS_SEP ';'
136#  define  DIR_SEP '\\'
137#  define  DIR_SEPP "\\"
138#else  /* unix */
139#  define  FS_SEP ':'
140#  define  DIR_SEP '/'
141#  define  DIR_SEPP "/"
142#endif  /* atarist */
143#endif  /* MSDOS */
144#endif  /* macintosh */
145
146FILE * feFopen(char *path, char *mode, char *where,int useWerror)
147{
148  if (where!=NULL) strcpy(where,path);
149  if ((*mode=='a') ||(*mode=='w') || (path[0]==DIR_SEP)||(path[0]=='.'))
150    return fopen(path,mode);
151  char found = 0;
152  FILE * f=NULL;
153#ifdef MSDOS
154  char *env=getenv("SPATH");
155#else
156  char *env=getenv("SingularPath");
157#endif
158  char *s;
159  if (where==NULL) s=(char *)AllocL(250);
160  else             s=where;
161  if (env!=NULL)
162  {
163    char *p,*q;
164    p = env;
165    while( (q=strchr(p, FS_SEP)) != NULL)
166    {
167      *q = '\0';
168      strcpy(s,p);
169      *q = FS_SEP;
170      strcat(s, DIR_SEPP);
171      strcat(s, path);
172#ifndef macintosh
173      if(!access(s, R_OK)) { found++; break; }
174#else
175      f=fopen(s,mode);
176      if (f!=NULL)  { found++; fclose(f); break; }
177#endif
178      p = q+1;
179    }
180    if(!found)
181    {
182      strcpy(s,p);
183      strcat(s, DIR_SEPP);
184      strcat(s, path);
185    }
186    f=fopen(s,mode);
187    if (f!=NULL)
188    {
189      if (where==NULL) FreeL((ADDRESS)s);
190      return f;
191    }
192  }
193  if (where!=NULL) strcpy(s/*where*/,path);
194  f=fopen(path,mode);
195#ifndef macintosh
196  if (f==NULL)
197  {
198    strcpy(s,"/usr/local/Singular/");
199    strcat(s,path);
200    f=fopen(s,mode);
201  }
202#endif
203  if (where==NULL) FreeL((ADDRESS)s);
204  if ((f==NULL)&&(useWerror))
205    Werror("cannot open `%s`",path);
206  return f;
207}
208
209/*2
210* the name of the current 'voice': the procname (or filename)
211*/
212const char * VoiceName()
213{
214  if (FileAttribs[fileVoice].filename!=NULL)
215    return FileAttribs[fileVoice].filename;
216  return sNoName;
217}
218
219/*2
220* the name of the 'voice' number 'i': the procname (or filename)
221*/
222const char * VoiceName(int i)
223{
224  if (FileAttribs[i].filename!=NULL)
225    return FileAttribs[i].filename;
226  return sNoName;
227}
228
229/*2
230* the type of the current voice:BT_proc, BT_example, BT_file
231*/
232int VoiceType()
233{
234  int i=fileVoice;
235  while ((FileAttribs[i].typ!=BT_proc)
236  &&(FileAttribs[i].typ!=BT_example)
237  &&(FileAttribs[i].typ!=BT_file)
238  &&(i>0))
239    i--;
240  return FileAttribs[i].typ;
241}
242/*2
243* start the file 'fname' (STDIN is stdin) in the current voice (cf.newVoice)
244*/
245Voices * Voices::VFile(char* fname)
246{
247  if (strcmp(fname,"STDIN") == 0)
248  {
249    yyin = stdin;
250    v_inputswitch = 0;
251  }
252  else
253  {
254    yyin = feFopen(fname,"r",NULL,TRUE);
255    v_inputswitch = -1;
256  }
257  files      = yyin;
258  filename   = mstrdup(fname);
259  v_echo     = si_echo;
260  fileVoice  = voice;
261  yylineno   = 1;
262  if (files==NULL)
263  {
264    inputswitch = 0;
265    exitVoice();
266    return NULL;
267  }
268  inputswitch= v_inputswitch;
269  return this;
270}
271
272/*3
273* increment voice counter, allocate new memory
274*/
275static inline void inc_voice()
276{
277  voice++;
278  if (voice >= levmax)
279  {
280    FileAttribs=(Voices *)ReAlloc(FileAttribs,
281                          levmax*sizeof(Voices),
282                          (levmax+16)*sizeof(Voices));
283    ifswitch=(short *)ReAlloc(ifswitch,
284                          levmax*sizeof(short),
285                          (levmax+16)*sizeof(short));
286    memset(&ifswitch[levmax],0,16*sizeof(short));
287    levmax+=16;
288  }
289}
290
291/*2
292* init a new voice similiar to the current
293*/
294void Voices::Next()
295{
296  v_oldlineno = yylineno;
297  v_echo      = si_echo;
298  v_fileVoice = fileVoice;
299  inc_voice();
300
301  currentVoice = &FileAttribs[voice];
302  currentVoice->Init();
303}
304
305/*2
306* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
307*/
308int newVoice(char* s)
309{
310  currentVoice->Next();
311  return (int)currentVoice->VFile((char *)s);
312}
313
314void newBuffer(char* s, int t, char* pname)
315{
316  currentVoice->Next();
317  currentVoice->Buffer(s,t);
318  if (pname) currentVoice->filename = mstrdup(pname);
319  //printf("start buffer %d typ %d\n",voice,t);
320}
321
322Voices * Voices::Buffer(char* buf, int t)
323{
324  inputswitch = v_inputswitch = t;
325  buffer      = buf;
326  typ         = t;
327  //si_echo        = 0;
328  switch (t)
329  {
330    case BT_example:
331    case BT_proc:    v_lineno = yylineno; ::yylineno = 3;     break;
332    case BT_file:    v_lineno = yylineno; ::yylineno = 1;     break;
333    case BT_if:
334    case BT_else:    ::yylineno = v_lineno = blocklineno - 1; break;
335    case BT_break:   ::yylineno = v_lineno = blocklineno - 2; break;
336  }
337  return this;
338}
339
340/*2
341* after leaving a voice:
342* setup everything from the this level
343*/
344int Voices::Exit()
345{
346  if (voice >= 0)
347  {
348    si_echo          = v_echo;
349    fileVoice     = v_fileVoice;
350    yyin          = files;
351    yylineno      = v_oldlineno;
352    inputswitch   = v_inputswitch;
353    return 0;
354  }
355  //Print("Exit:%d\n",voice);
356  return 1;
357}
358
359/*2
360* exit Buffer of type 'typ':
361* returns 1 if buffer type could not be found
362*/
363int exitBuffer(int typ)
364{
365  //printf("exitBuffer: %d\n",typ);
366  if (typ == BT_break)  // valid inside for, while. may skip if, else
367  {
368    /*4 first check for valid buffer type, skip if/else*/
369    for (int i=voice; i>0; i--)
370    {
371      if ((FileAttribs[i].typ == BT_if)
372        ||(FileAttribs[i].typ == BT_else)) continue;
373      if (FileAttribs[i].typ == BT_break /*typ*/)
374      {
375        while ((/*typ*/ BT_break != currentVoice->typ)
376        && (voice > 0))
377        {
378          exitVoice();
379        }
380        return exitVoice();
381      }
382      else return 1;
383    }
384    /*4 break not inside a for/while: return an error*/
385    if (/*typ*/ BT_break != currentVoice->typ) return 1;
386    return exitVoice();
387  }
388
389  if ((typ == BT_proc)
390  || (typ == BT_example))
391  {
392    for (int i=voice; i>0; i--)
393    {
394      if (FileAttribs[i].typ == 0) break;
395      if ((FileAttribs[i].typ == BT_proc)
396      || (FileAttribs[i].typ == BT_example))
397      {
398        while ((BT_proc != currentVoice->typ)
399          && (BT_example != currentVoice->typ)
400        && (voice > 0))
401        {
402          exitVoice();
403        }
404        return exitVoice();
405      }
406    }
407  }
408  /*4 return not inside a proc: return an error*/
409  return 1;
410}
411
412/*2
413* jump to the beginning of a buffer
414*/
415int contBuffer(int typ)
416{
417  if (typ == BT_break)  // valid inside for, while. may skip if, else
418  {
419    // first check for valid buffer type
420    for (int i=voice; i>0; i--)
421    {
422      if ((FileAttribs[i].typ == BT_if)
423        ||(FileAttribs[i].typ == BT_else)) continue;
424      if (FileAttribs[i].typ == BT_break /*typ*/)
425      {
426        while (/*typ*/ BT_break != currentVoice->typ && (voice > i))
427        {
428          exitVoice();
429        }
430        currentVoice->fptr = 0L;
431        yylineno = currentVoice->v_lineno;
432        return 0;
433      }
434      else return 1;
435    }
436  }
437  return 1;
438}
439
440/*2
441* leave a file voice
442*/
443int exitFile()
444{
445  int oldswitch;
446
447  while ((voice > 0) && (inputswitch > 0))
448  {
449    exitVoice();
450  }
451  // now we have left all if-, else-, while-, for-, proc-levels
452  // inside this file;
453  // if the file is the terminal (inputswitch == 0) and
454  // voice >0, so return 1 else return 0
455  // (used for EXIT_CMD in CNTRLC-C-handling)
456  oldswitch = inputswitch;
457  exitVoice();
458  #ifdef SIC
459  return 1;
460  #else
461  if ((oldswitch)||(myynest<0)) return 0;
462  else return 1;
463  #endif
464}
465
466/*2
467* leave a voice: kill local variables
468* setup everything from the previous level (via Exit)
469*/
470int exitVoice()
471{
472  if (voice <= 0)   m2_end(0);
473  //printf("exitVoice %d, typ %d\n",voice,FileAttribs[voice].typ);
474  if (FileAttribs[voice].typ==BT_if)
475  {
476    ifswitch[voice-1]=2;
477  }
478  else
479  {
480    ifswitch[voice-1]=0;
481    //if ((FileAttribs[voice].typ==BT_proc)
482    //||(FileAttribs[voice].typ==BT_example)
483    //||(FileAttribs[voice].typ==0))
484    //{
485    //  killlocals(myynest);
486    //  printf("killlocals %d\n",myynest);
487    //}
488  }
489  if (inputswitch == -1)
490  {
491    fclose(yyin);
492  }
493  else if (inputswitch > 0)
494  {
495    if (FileAttribs[voice].filename!=NULL)
496    {
497      FreeL((ADDRESS)FileAttribs[voice].filename);
498      FileAttribs[voice].filename=NULL;
499    }
500    if (FileAttribs[voice].buffer!=NULL)
501    {
502      FreeL((ADDRESS)FileAttribs[voice].buffer);
503      FileAttribs[voice].buffer=NULL;
504    }
505  }
506  currentVoice = &FileAttribs[--voice];
507  return currentVoice->Exit();
508}
509
510int readbuf(char* buf, int l)
511{
512  char *s;
513  char * t = buf;
514  int i = 0;
515  long fl = currentVoice->fptr;
516  if (fl == -1L)
517  {
518    t[0] = '\0';
519    exitVoice();
520    return 0;
521  }
522
523  s = currentVoice->buffer + fl;
524  while (l > 0)
525  {
526    fl++;
527    i++;
528    l--;
529    *t++ = *s;
530    if (*s == '\n')
531    {
532      *t = '\0';
533      if ((si_echo > voice) || (inputswitch == 0) || (traceit&TRACE_SHOW_LINE)
534      || (traceit&TRACE_SHOW_LINE1))
535      {
536        if (currentVoice->filename==NULL)
537          Print("(none) %3d%c ",yylineno,prompt_char);
538        else if (VoiceType()!=BT_example)
539          Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
540        prompt_char = '.';
541      }
542      if (*(s+1) == '\0')
543      {
544        currentVoice->fptr = -1;
545        FreeL((ADDRESS)(currentVoice->buffer));
546        currentVoice->buffer=NULL;
547        FileAttribs[voice].buffer = NULL;
548        exitVoice();
549      }
550      else
551        currentVoice->fptr = fl;
552      return i;
553    }
554    else if (*s == '\0')
555    {
556      if ((si_echo > voice) || (inputswitch == 0) || (traceit&TRACE_SHOW_LINE)
557      || (traceit&TRACE_SHOW_LINE1))
558      {
559        if (currentVoice->filename==NULL)
560          Print("(none) %3d%c ",yylineno,prompt_char);
561        else
562          Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
563        prompt_char = '.';
564      }
565      currentVoice->fptr = -1;
566      FreeL((ADDRESS)(currentVoice->buffer));
567      currentVoice->buffer = NULL;
568      exitVoice();
569      return i-1;
570    }
571    s++;
572  }
573  currentVoice->fptr = fl;
574  return i;
575}
576
577/*2
578* init all data structures
579*/
580void I_FEbase(void)
581{
582  FileAttribs[0].files       = yyin = stdin;
583  FileAttribs[0].filename    = mstrdup("STDIN");
584  yylineno = 1;
585  currentVoice = &FileAttribs[0];
586  feBuffer = (char *)Alloc(INITIAL_PRINT_BUFFER);
587}
588
589char * feBufferStart;
590  /* only used in StringSet(S)/StringAppend(S)*/
591char * StringAppend(char *fmt, ...)
592{
593  va_list ap;
594  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
595  int more;
596  va_start(ap, fmt);
597  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
598  {
599    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
600    int l=s-feBuffer;
601    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
602                                                     more);
603    feBufferLength=more;
604    s=feBuffer+l;
605#ifndef BSD_SPRINTF
606    feBufferStart=s;
607#endif
608  }
609#ifdef BSD_SPRINTF
610  vsprintf(s, fmt, ap);
611  while (*s!='\0') s++;
612  feBufferStart =s;
613#else
614  feBufferStart += vsprintf(s, fmt, ap);
615#endif
616  va_end(ap);
617  mmTest(feBuffer,feBufferLength);
618  return feBuffer;
619}
620
621char * StringAppendS(char *st)
622{
623  /* feBufferStart is feBuffer + strlen(feBuffer);*/
624  int more,l;
625  int ll=feBufferStart-feBuffer;
626  if ((more=ll+2+(l=strlen(st)))>feBufferLength)
627  {
628    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
629    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
630                                                     more);
631    feBufferLength=more;
632    feBufferStart=feBuffer+ll;
633  }
634  strcat(feBufferStart, st);
635  feBufferStart +=l;
636  mmTest(feBuffer,feBufferLength);
637  return feBuffer;
638}
639
640char * StringSet(char *fmt, ...)
641{
642  va_list ap;
643  char *s = feBuffer;
644  va_start(ap, fmt);
645#ifdef BSD_SPRINTF
646  vsprintf(s, fmt, ap);
647  while (*s!='\0') s++;
648  feBufferStart = s;
649#else
650  feBufferStart = feBuffer + vsprintf(s, fmt, ap);
651#endif
652  va_end(ap);
653  return feBuffer;
654}
655
656char * StringSetS(char *st)
657{
658  int more,l;
659  if ((l=strlen(st))>feBufferLength)
660  {
661    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
662    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
663                                                     more);
664    feBufferLength=more;
665  }
666  strcpy(feBuffer,st);
667  feBufferStart=feBuffer+l;
668  return feBuffer;
669}
670
671void PrintTCLS(char c, char *s)
672{
673#ifndef macintosh
674  int l=strlen(s);
675  if (l>0) PrintTCL(c,l,s);
676#endif
677}
678
679void WerrorS(char *s)
680{
681#ifdef HAVE_MPSR
682  if (feBatch)
683  {
684    if (feErrors==NULL)
685    {
686      feErrors=(char *)Alloc(256);
687      feErrorsLen=256;
688      strcpy(feErrors,s);
689    }
690    else
691    {
692      if (((int)(strlen(s)+strlen(feErrors)))>=feErrorsLen)
693      {
694        feErrors=(char *)ReAlloc(feErrors,feErrorsLen,feErrorsLen+256);
695        feErrorsLen+=256;
696      }
697      strcat(feErrors,s);
698    }
699    strcat(feErrors,"\n");
700  }
701  else
702#endif
703  {
704#ifdef HAVE_TCL
705    if (tclmode)
706    {
707      //PrintTCLS('E',s);
708      //PrintTCLS('E',"\n");
709      PrintTCLS('N',s);
710      PrintTCLS('N',"\n");
711    }
712    else
713#endif
714    {
715      fwrite("   ? ",1,5,stderr);
716      fwrite(s,1,strlen(s),stderr);
717      fwrite("\n",1,1,stderr);
718      fflush(stderr);
719      if (feProt&PROT_O)
720      {
721        fwrite("   ? ",1,5,feProtFile);
722        fwrite(s,1,strlen(s),feProtFile);
723        fwrite("\n",1,1,feProtFile);
724      }
725    }
726  }
727  errorreported = TRUE;
728}
729
730extern "C" {
731void Werror(char *fmt, ...)
732{
733  va_list ap;
734  va_start(ap, fmt);
735  char *s=(char *)Alloc(256);
736  vsprintf(s, fmt, ap);
737  WerrorS(s);
738  Free(s,256);
739  va_end(ap);
740}
741}
742
743void WarnS(char *s)
744{
745#ifdef HAVE_TCL
746  if (tclmode)
747  {
748    PrintTCLS('W',s);
749  }
750  else
751#endif
752  {
753    fwrite("// ** ",1,6,stdout);
754    fwrite(s,1,strlen(s),stdout);
755    fwrite("\n",1,1,stdout);
756    fflush(stdout);
757    if (feProt&PROT_O)
758    {
759      fwrite("// ** ",1,6,feProtFile);
760      fwrite(s,1,strlen(s),feProtFile);
761      fwrite("\n",1,1,feProtFile);
762    }
763  }
764}
765
766void Warn(char *fmt, ...)
767{
768  va_list ap;
769  va_start(ap, fmt);
770  char *s=(char *)Alloc(256);
771  vsprintf(s, fmt, ap);
772  WarnS(s);
773  Free(s,256);
774  va_end(ap);
775}
776
777#ifdef macintosh
778static  int lines = 0;
779static  int cols = 0;
780void mwrite(uchar c)
781{
782  if (c == '\n')
783  {
784    cols = 0;
785    if (lines == pagelength)
786    {
787      lines = 0;
788      fePause();
789    }
790    else
791    {
792      lines++;
793      fePutChar(c);
794    }
795  }
796  else
797  {
798    fePutChar(c);
799    cols++;
800    if (cols == colmax)
801    {
802//      cols = 0;   //will be done by mwrite('\n');
803      mwrite('\n');
804    }
805  }
806}
807#endif
808
809void PrintS(char *s)
810{
811#ifdef macintosh
812  char c;
813  while ('\0' != (c = *s++))
814  {
815    mwrite(c);
816  }
817#else
818#ifdef HAVE_TCL
819  if (tclmode)
820  {
821    PrintTCLS('N',s);
822  }
823  else
824#endif
825  {
826    fwrite(s,1,strlen(s),stdout);
827    fflush(stdout);
828    if (feProt&PROT_O)
829    {
830      fwrite(s,1,strlen(s),feProtFile);
831    }
832  }
833#endif
834}
835
836void Print(char *fmt, ...)
837{
838  va_list ap;
839  va_start(ap, fmt);
840#ifdef HAVE_TCL
841  if(tclmode)
842#endif
843#if (defined(HAVE_TCL) || defined(macintosh))
844  {
845    char *s=(char *)Alloc(strlen(fmt)+256);
846    vsprintf(s,fmt, ap);
847#ifdef HAVE_TCL
848    PrintTCLS('N',s);
849#endif
850#ifdef macintosh
851  char c;
852  while ('\0' != (c = *s++))
853  {
854    mwrite(c);
855  }
856  if (feProt&PROT_O)
857  {
858    vfprintf(feProrFile,fmt,ap);
859  }
860#endif
861  }
862#endif
863#if !defined(macintosh) || defined(HAVE_TCL)
864#ifdef HAVE_TCL
865  else
866#endif
867  {
868    vfprintf(stdout, fmt, ap);
869    fflush(stdout);
870    if (feProt&PROT_O)
871    {
872      vfprintf(feProtFile,fmt,ap);
873    }
874  }
875#endif
876  va_end(ap);
877}
878
879void PrintLn()
880{
881  PrintS("\n");
882}
883
884void fePause()
885{
886  uchar c;
887  mflush();
888#ifndef macintosh
889  fputs("pause>",stderr);
890#else
891  fputs("pause>\n",stderr);
892#endif
893  c = fgetc(stdin);
894  if (((c == '\003') || (c == 'C')) || (c == 'c'))
895  {
896    m2_end(1);
897  }
898}
899
900/*2
901* print input lines (si_echo or TRACE), set prompt_char
902*/
903void showInput(void)
904{
905  if ((inputswitch <= 0) || (traceit&TRACE_SHOW_LINE)
906  || (traceit&TRACE_SHOW_LINE1))
907  {
908    if ((si_echo > voice) || (inputswitch == 0) || (traceit&TRACE_SHOW_LINE)
909    || (traceit&TRACE_SHOW_LINE1))
910    {
911#ifdef HAVE_TCL
912      if (tclmode)
913      {
914         PrintTCL('P',(prompt_char=='>')? 0 : 1,NULL);
915      }
916      else
917#endif
918      if (BVERBOSE(V_PROMPT))
919      {
920        if (inputswitch == 0)
921        {
922          fe_promptstr[0]=prompt_char;
923#ifndef HAVE_READLINE
924          PrintS(fe_promptstr);
925#endif
926        }
927        else
928        {
929          if (currentVoice->filename==NULL)
930            Print("(none) %3d%c ",yylineno,prompt_char);
931          else
932            Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
933        }
934        prompt_char = '.';
935        mflush();
936      }
937#ifdef macintosh
938      cols = 0;
939#endif
940    }
941  }
942}
943
944void monitor(char* s, int mode)
945{
946  if (feProt)
947  {
948    fclose(feProtFile);
949  }
950  if ((s!=NULL) && (*s!='\0'))
951  {
952    feProtFile = fopen(s,"w");
953    if (feProtFile==NULL)
954    {
955      Werror("cannot open %s",s);
956    }
957    else
958      feProt = (BOOLEAN)mode;
959  }
960}
961
962
963char* eati(char *s, int *i)
964{
965  int l=0;
966
967  if    (*s >= '0' && *s <= '9')
968  {
969    *i = 0;
970    while (*s >= '0' && *s <= '9')
971    {
972      *i *= 10;
973      *i += *s++ - '0';
974      l++;
975      if ((l>MAX_INT_LEN)||((*i) <0))
976      {
977        s-=l;
978        Werror("`%s` greater than %d(max. integer representation)",
979                s,INT_MAX);
980        return s;
981      }
982    }
983  }
984  else *i = 1;
985  return s;
986}
987
Note: See TracBrowser for help on using the repository browser.