source: git/kernel/febase.cc @ 9c83f2

spielwiese
Last change on this file since 9c83f2 was 9c83f2, checked in by Hans Schoenemann <hannes@…>, 13 years ago
eati -> repoter intvec.* -> misc
  • Property mode set to 100644
File size: 22.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: i/o system
7*/
8
9/* I need myfread in standalone_parser */
10#ifndef STANDALONE_PARSER
11#include <kernel/mod2.h>
12
13#include <stdlib.h>
14#include <stdio.h>
15#include <omalloc/mylimits.h>
16#include <stdarg.h>
17#include <sys/stat.h>
18#include <ctype.h>
19#include <unistd.h>
20
21#ifdef HAVE_PWD_H
22#include <pwd.h>
23#endif
24
25#include <kernel/febase.h>
26#include <omalloc/omalloc.h>
27#include <kernel/dError.h>
28#include <kernel/options.h>
29
30#define fePutChar(c) fputc((unsigned char)(c),stdout)
31/*0 implementation */
32
33char fe_promptstr[] ="  ";
34
35// output/print buffer:
36#define INITIAL_PRINT_BUFFER 24*1024L
37// line buffer for reading:
38// minimal value for MAX_FILE_BUFFER: 4*4096 - see Tst/Long/gcd0_l.tst
39// this is an upper limit for the size of monomials/numbers read via the interpreter
40#define MAX_FILE_BUFFER 4*4096
41static long feBufferLength=INITIAL_PRINT_BUFFER;
42static char * feBuffer=(char *)omAlloc(INITIAL_PRINT_BUFFER);
43
44int     si_echo = 0;
45int     printlevel = 0;
46int     colmax = 80;
47char    prompt_char = '>'; /*1 either '>' or '.'*/
48extern "C" {
49BITSET  test=(BITSET)0;
50BITSET  verbose = Sy_bit(V_QUIET)
51                  //| Sy_bit(V_QRING) // not default, as speed drops by 10 %
52                  | Sy_bit(V_REDEFINE)
53                  | Sy_bit(V_LOAD_LIB)
54                  | Sy_bit(V_SHOW_USE)
55                  | Sy_bit(V_PROMPT)
56/*                  | Sy_bit(V_DEBUG_MEM) */
57;}
58BOOLEAN errorreported = FALSE;
59char *  feErrors=NULL;
60int     feErrorsLen=0;
61BOOLEAN feWarn = TRUE;
62BOOLEAN feOut = TRUE;
63
64const char feNotImplemented[]="not implemented";
65
66void (*WerrorS_callback)(const char *s) = NULL;
67
68int feProt = FALSE;
69FILE*   feProtFile;
70
71
72/**************************************************************************
73* handling of 'voices'
74**************************************************************************/
75
76extern int blocknest; /* scaner.l internal */
77
78int    yy_noeof=0;     // the scanner "state"
79int    yy_blocklineno; // to get the lineno of the block start from scanner
80Voice  *currentVoice = NULL;
81FILE   *feFilePending; /*temp. storage for grammar.y */
82
83//static const char * BT_name[]={"BT_none","BT_break","BT_proc","BT_example",
84//                               "BT_file","BT_execute","BT_if","BT_else"};
85/*2
86* the name of the current 'Voice': the procname (or filename)
87*/
88const char * sNoName_fe="_";
89const char * VoiceName()
90{
91  if ((currentVoice!=NULL)
92  && (currentVoice->filename!=NULL))
93    return currentVoice->filename;
94  return sNoName_fe;
95}
96
97/*2
98* the calling chain of Voices
99*/
100void VoiceBackTrack()
101{
102  Voice *p=currentVoice;
103  while (p->prev!=NULL)
104  {
105    p=p->prev;
106    char *s=p->filename;
107    if (s==NULL)
108      PrintS("-- called from ? --\n");
109    else
110      Print("-- called from %s --\n",s);
111  }
112}
113
114/*2
115* init a new voice similiar to the current
116*/
117void Voice::Next()
118{
119  Voice *p=new Voice;
120  // OB: ???
121  // Hmm... when Singular is used as batch file
122  // then this voice is never freed
123  omMarkAsStaticAddr(p);
124  if (currentVoice != NULL)
125  {
126    currentVoice->curr_lineno=yylineno;
127    currentVoice->next=p;
128  }
129  p->prev=currentVoice;
130  currentVoice=p;
131  //Print("Next:");
132}
133
134feBufferTypes Voice::Typ()
135{
136  switch(typ)
137  {
138    case BT_proc:
139    case BT_example:
140    case BT_file:
141      return typ;
142    default:
143      if (prev==NULL) return (feBufferTypes)0;
144      return prev->Typ();
145  }
146}
147
148/*2
149* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
150* return FALSE on success, TRUE if an error occurs (file cannot be opened)
151*/
152BOOLEAN newFile(char *fname,FILE* f)
153{
154  currentVoice->Next();
155  //Print(":File%d(%s):%s(%x)\n",
156  //  currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
157  currentVoice->filename   = omStrDup(fname);
158  omMarkAsStaticAddr(currentVoice->filename);
159  if (strcmp(fname,"STDIN") == 0)
160  {
161    currentVoice->files = stdin;
162    currentVoice->sw = BI_stdin;
163    currentVoice->start_lineno = 1;
164  }
165  else
166  {
167    currentVoice->sw = BI_file; /* needed by exitVoice below */
168    if (f!=NULL)
169      currentVoice->files = f;
170    else
171    {
172      currentVoice->files = feFopen(fname,"r",NULL,TRUE);
173      if (currentVoice->files==NULL)
174      {
175        exitVoice();
176        return TRUE;
177      }
178    }
179    currentVoice->start_lineno = 0;
180  }
181  yylineno=currentVoice->start_lineno;
182  //Voice *p=currentVoice;
183  //Print("-----------------\ncurr:");
184  //do
185  //{
186  //Print("voice fn:%s\n",p->filename);
187  //p=p->prev;
188  //}
189  //while (p!=NULL);
190  //Print("----------------\n");
191  return FALSE;
192}
193
194void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
195{
196  currentVoice->Next();
197  //Print(":Buffer%d(%s):%s(%x)\n",
198  //  t,BT_name[t],pname,currentVoice);
199  if (pi!=NULL)
200  {
201    long l=strlen(pi->procname);
202    if (pi->libname!=NULL) l+=strlen(pi->libname);
203    currentVoice->filename = (char *)omAlloc(l+3);
204    *currentVoice->filename='\0';
205    if (pi->libname!=NULL) strcat(currentVoice->filename,pi->libname);
206    strcat(currentVoice->filename,"::");
207    strcat(currentVoice->filename,pi->procname);
208    currentVoice->pi       = pi;
209  }
210  else
211  {
212    currentVoice->filename = omStrDup(currentVoice->prev->filename);
213    currentVoice->pi       = currentVoice->prev->pi;
214  }
215  currentVoice->buffer   = s;
216  currentVoice->sw       = BI_buffer;
217  currentVoice->typ      = t;
218  switch (t)
219  {
220    case BT_execute:
221                     yylineno-=2;
222                     break;
223    case BT_proc:
224    case BT_example:
225                     currentVoice->oldb=myynewbuffer();
226                     yylineno = lineno+1;
227                     break;
228    case BT_if:
229    case BT_else:
230    case BT_break:
231                     yylineno = yy_blocklineno-1;
232                     break;
233    //case BT_file:
234    default:
235                     yylineno = 1;
236                     break;
237  }
238  //Print("start body (%s) at line %d\n",BT_name[t],yylineno);
239  currentVoice->start_lineno = yylineno;
240  //printf("start buffer typ %d\n",t);
241  //Voice *p=currentVoice;
242  //Print("-----------------\ncurr:");
243  //do
244  //{
245  //Print("voice fn:%s\n",p->filename);
246  //p=p->prev;
247  //}
248  //while (p!=NULL);
249  //Print("----------------\n");
250}
251
252/*2
253* exit Buffer of type 'typ':
254* returns 1 if buffer type could not be found
255*/
256BOOLEAN exitBuffer(feBufferTypes typ)
257{
258  //printf("exitBuffer: %d(%s),(%x)\n",
259  //  typ,BT_name[typ], currentVoice);
260  //Voice *p=currentVoice;
261  //Print("-----------------\ncurr:");
262  //do
263  //{
264  //Print("voice fn:%s\n",p->filename);
265  //p=p->prev;
266  //}
267  //while (p!=NULL);
268  //Print("----------------\n");
269  if (typ == BT_break)  // valid inside for, while. may skip if, else
270  {
271    /*4 first check for valid buffer type, skip if/else*/
272    Voice *p=currentVoice;
273    loop
274    {
275      if ((p->typ != BT_if)
276      &&(p->typ != BT_else))
277      {
278        if (p->typ == BT_break /*typ*/)
279        {
280          while (p != currentVoice)
281          {
282            exitVoice();
283          }
284          exitVoice();
285          return FALSE;
286        }
287        else return TRUE;
288      }
289      if (p->prev==NULL) break;
290      p=p->prev;
291    }
292    /*4 break not inside a for/while: return an error*/
293    if (/*typ*/ BT_break != currentVoice->typ) return 1;
294    return exitVoice();
295  }
296
297  if ((typ == BT_proc)
298  || (typ == BT_example))
299  {
300    Voice *p=currentVoice;
301    loop
302    {
303      if ((p->typ == BT_proc)
304      || (p->typ == BT_example))
305      {
306        while (p != currentVoice)
307        {
308          exitVoice();
309        }
310        exitVoice();
311        return FALSE;
312      }
313      if (p->prev==NULL) break;
314      p=p->prev;
315    }
316  }
317  /*4 return not inside a proc: return an error*/
318  return TRUE;
319}
320
321/*2
322* jump to the beginning of a buffer
323*/
324BOOLEAN contBuffer(feBufferTypes typ)
325{
326  //printf("contBuffer: %d(%s),(%x)\n",
327  //  typ,BT_name[typ], currentVoice);
328  if (typ == BT_break)  // valid inside for, while. may skip if, else
329  {
330    // first check for valid buffer type
331    Voice *p=currentVoice;
332    loop
333    {
334      if ((p->typ != BT_if)
335        &&(p->typ != BT_else))
336      {
337        if (p->typ == BT_break /*typ*/)
338        {
339          while (p != currentVoice)
340          {
341            exitVoice();
342          }
343          yylineno = currentVoice->start_lineno;
344          currentVoice->fptr=0;
345          return FALSE;
346        }
347        else return TRUE;
348      }
349      if (p->prev==NULL) break;
350      p=p->prev;
351    }
352  }
353  return TRUE;
354}
355
356/*2
357* leave a voice: kill local variables
358* setup everything from the previous level
359* return 1 if leaving the top level, 0 otherwise
360*/
361BOOLEAN exitVoice()
362{
363  //printf("exitVoice: %d(%s),(%x)\n",
364  //  currentVoice->typ,BT_name[currentVoice->typ], currentVoice);
365  //{
366  //Voice *p=currentVoice;
367  //Print("-----------------\ncurr:");
368  //do
369  //{
370  //Print("voice fn:%s\n",p->filename);
371  //p=p->prev;
372  //}
373  //while (p!=NULL);
374  //Print("----------------\n");
375  //}
376  if (currentVoice!=NULL)
377  {
378    if (currentVoice->oldb!=NULL)
379    {
380      myyoldbuffer(currentVoice->oldb);
381      currentVoice->oldb=NULL;
382    }
383    if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
384    {
385      currentVoice->prev=feInitStdin(currentVoice);
386    }
387    if (currentVoice->prev!=NULL)
388    {
389      //printf("exitVoice typ %d(%s)\n",
390      //  currentVoice->typ,BT_name[currentVoice->typ]);
391      if (currentVoice->typ==BT_if)
392      {
393        currentVoice->prev->ifsw=2;
394      }
395      else
396      {
397        currentVoice->prev->ifsw=0;
398      }
399      if ((currentVoice->sw == BI_file)
400      && (currentVoice->files!=NULL))
401      {
402        fclose(currentVoice->files);
403      }
404      if (currentVoice->filename!=NULL)
405      {
406        omFree((ADDRESS)currentVoice->filename);
407        currentVoice->filename=NULL;
408      }
409      if (currentVoice->buffer!=NULL)
410      {
411        omFree((ADDRESS)currentVoice->buffer);
412        currentVoice->buffer=NULL;
413      }
414      yylineno=currentVoice->prev->curr_lineno;
415      currentVoice->prev->next=NULL;
416    }
417    Voice *p=currentVoice->prev;
418    delete currentVoice;
419    currentVoice=p;
420  }
421  return currentVoice==NULL;
422}
423
424/*2
425* set prompt_char
426* only called with currentVoice->sw == BI_stdin
427*/
428static void feShowPrompt(void)
429{
430  fe_promptstr[0]=prompt_char;
431}
432
433/*2
434* print echo (si_echo or TRACE), set my_yylinebuf
435*/
436static int fePrintEcho(char *anf, char *b)
437{
438  char *ss=strrchr(anf,'\n');
439  int len_s;
440  if (ss==NULL)
441  {
442    len_s=strlen(anf);
443  }
444  else
445  {
446    len_s=ss-anf+1;
447  }
448  // my_yylinebuf:
449  int mrc=si_min(len_s,79)-1;
450  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
451  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
452  mrc--;
453  // handle echo:
454  if (((si_echo>myynest)
455    && ((currentVoice->typ==BT_proc)
456      || (currentVoice->typ==BT_example)
457      || (currentVoice->typ==BT_file)
458      || (currentVoice->typ==BT_none)
459    )
460    && (strncmp(anf,";return();",10)!=0)
461   )
462  || (traceit&TRACE_SHOW_LINE)
463  || (traceit&TRACE_SHOW_LINE1))
464  {
465    if (currentVoice->typ!=BT_example)
466    {
467      if (currentVoice->filename==NULL)
468        Print("(none) %3d%c ",yylineno,prompt_char);
469      else
470        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
471     }
472    {
473      fwrite(anf,1,len_s,stdout);
474      mflush();
475    }
476    if (traceit&TRACE_SHOW_LINE)
477    {
478      while(fgetc(stdin)!='\n');
479    }
480  }
481  else if (traceit&TRACE_SHOW_LINENO)
482  {
483    Print("{%d}",yylineno);
484    mflush();
485  }
486#ifdef HAVE_SDB
487  if ((blocknest==0)
488  && (currentVoice->pi!=NULL)
489  && (currentVoice->pi->trace_flag!=0))
490  {
491    sdb(currentVoice, anf, len_s);
492  }
493#endif
494  prompt_char = '.';
495  return len_s;
496}
497
498int feReadLine(char* b, int l)
499{
500  char *s=NULL;
501  int offset = 0; /* will not be used if s==NULL*/
502  // try to read from the buffer into b, max l chars
503  if (currentVoice!=NULL)
504  {
505    if((currentVoice->buffer!=NULL)
506    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
507    {
508  NewBuff:
509      register int i=0;
510      long startfptr=currentVoice->fptr;
511      long tmp_ptr=currentVoice->fptr;
512      l--;
513      loop
514      {
515        register char c=
516        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
517        i++;
518        if (yy_noeof==noeof_block)
519        {
520          if (c<' ')  yylineno++;
521          else if (c=='}') break;
522        }
523        else
524        {
525          if ((c<' ') ||
526          (c==';') ||
527          (c==')')
528          )
529            break;
530        }
531        if (i>=l) break;
532        tmp_ptr++;/*currentVoice->fptr++;*/
533        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
534      }
535      currentVoice->fptr=tmp_ptr;
536      b[i]='\0';
537      if (currentVoice->sw==BI_buffer)
538      {
539        if (startfptr==0)
540        {
541          char *anf=currentVoice->buffer;
542          const char *ss=strchr(anf,'\n');
543          long len;
544          if (ss==NULL) len=strlen(anf);
545          else          len=ss-anf;
546          char *s=(char *)omAlloc(len+2);
547          strncpy(s,anf,len+2);
548          s[len+1]='\0';
549          fePrintEcho(s,b);
550          omFree((ADDRESS)s);
551        }
552        else if (/*(startfptr>0) &&*/
553        (currentVoice->buffer[startfptr-1]=='\n'))
554        {
555          char *anf=currentVoice->buffer+startfptr;
556          const char *ss=strchr(anf,'\n');
557          long len;
558          if (ss==NULL) len=strlen(anf);
559          else          len=ss-anf;
560          char *s=(char *)omAlloc(len+2);
561          strncpy(s,anf,len+2);
562          s[len+1]='\0';
563          yylineno++;
564          fePrintEcho(s,b);
565          omFree((ADDRESS)s);
566        }
567      }
568      currentVoice->fptr++;
569      return i;
570    }
571    // no buffer there or e-o-buffer or eoln:
572    if (currentVoice->sw!=BI_buffer)
573    {
574      currentVoice->fptr=0;
575      if (currentVoice->buffer==NULL)
576      {
577        currentVoice->buffer=(char *)omAlloc(MAX_FILE_BUFFER-sizeof(ADDRESS));
578        omMarkAsStaticAddr(currentVoice->buffer);
579      }
580    }
581    offset=0;
582  NewRead:
583    yylineno++;
584    if (currentVoice->sw==BI_stdin)
585    {
586      feShowPrompt();
587      s=fe_fgets_stdin(fe_promptstr,
588                       &(currentVoice->buffer[offset]),
589                       omSizeOfAddr(currentVoice->buffer)-1-offset);
590      //int i=0;
591      //if (s!=NULL)
592      //  while((s[i]!='\0') /*&& (i<MAX_FILE_BUFFER)*/) {s[i] &= (char)127;i++;}
593    }
594    else if (currentVoice->sw==BI_file)
595    {
596      s=fgets(currentVoice->buffer+offset,(MAX_FILE_BUFFER-1-sizeof(ADDRESS))-offset,
597              currentVoice->files);
598    }
599    //else /* BI_buffer */ s==NULL  => return 0
600    // done by the default return
601  }
602  if (s!=NULL)
603  {
604    // handle prot:
605    if (feProt&PROT_I)
606    {
607      fputs(s,feProtFile);
608    }
609    int rc=fePrintEcho(s,b)+1;
610    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
611    s[rc]='\0';
612    // handel \\ :
613    rc-=3;
614    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
615    {
616      s[rc]='\0';
617      offset+=rc;
618      if (offset<(int)omSizeOfAddr(currentVoice->buffer)) goto NewRead;
619    }
620    goto NewBuff;
621  }
622  /* else if (s==NULL) */
623  {
624    const char *err;
625    switch(yy_noeof)
626    {
627      case noeof_brace:
628      case noeof_block:
629        err="{...}";
630        break;
631      case noeof_asstring:
632        err="till `.`";
633        break;
634      case noeof_string:
635        err="string";
636        break;
637      case noeof_bracket:
638        err="(...)";
639        break;
640      case noeof_procname:
641        err="proc";
642        break;
643      case noeof_comment:
644        err="/*...*/";
645        break;
646      default:
647        return 0;
648    }
649    Werror("premature end of file while reading %s",err);
650    return 0;
651  }
652}
653
654/*2
655* init all data structures
656*/
657#ifndef STDIN_FILENO
658#define STDIN_FILENO 0
659#endif
660Voice * feInitStdin(Voice *pp)
661{
662  Voice *p = new Voice;
663  p->files = stdin;
664  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
665  if ((pp!=NULL) && (pp->files==stdin))
666  {
667    p->files=freopen("/dev/tty","r",stdin);
668    //stdin=p->files;
669    p->sw = BI_stdin;
670  }
671  p->filename   = omStrDup("STDIN");
672  p->start_lineno   = 1;
673  omMarkAsStaticAddr(p);
674  omMarkAsStaticAddr(p->filename);
675  return p;
676}
677
678static char * feBufferStart;
679  /* only used in StringSet(S)/StringAppend(S)*/
680char * StringAppend(const char *fmt, ...)
681{
682  va_list ap;
683  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
684  int vs;
685  long more;
686  va_start(ap, fmt);
687  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
688  {
689    more = ((more + (8*1024-1))/(8*1024))*(8*1024);
690    int l=s-feBuffer;
691    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
692                                                     more);
693    omMarkAsStaticAddr(feBuffer);
694    feBufferLength=more;
695    s=feBuffer+l;
696#ifndef BSD_SPRINTF
697    feBufferStart=s;
698#endif
699  }
700#ifdef BSD_SPRINTF
701  vsprintf(s, fmt, ap);
702  while (*s!='\0') s++;
703  feBufferStart =s;
704#else
705#ifdef HAVE_VSNPRINTF
706  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
707  if (vs == -1)
708  {
709    assume(0);
710    feBufferStart = feBuffer + feBufferLength -1;
711  }
712  else
713  {
714    feBufferStart += vs;
715  }
716#else
717  feBufferStart += vsprintf(s, fmt, ap);
718#endif
719#endif
720  omCheckAddrSize(feBuffer, feBufferLength);
721  va_end(ap);
722  return feBuffer;
723}
724
725char * StringAppendS(const char *st)
726{
727  if (*st!='\0')
728  {
729    /* feBufferStart is feBuffer + strlen(feBuffer);*/
730    int l;
731    long more;
732    int ll=feBufferStart-feBuffer;
733    if ((more=ll+2+(l=strlen(st)))>feBufferLength)
734    {
735      more = ((more + (8*1024-1))/(8*1024))*(8*1024);
736      feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
737                                                       more);
738      feBufferLength=more;
739      feBufferStart=feBuffer+ll;
740    }
741    strcat(feBufferStart, st);
742    feBufferStart +=l;
743  }
744  return feBuffer;
745}
746
747char * StringSetS(const char *st)
748{
749  int l;
750  long more;
751  if ((l=strlen(st))>feBufferLength)
752  {
753    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
754    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
755                                                     more);
756    feBufferLength=more;
757  }
758  strcpy(feBuffer,st);
759  feBufferStart=feBuffer+l;
760  return feBuffer;
761}
762
763extern "C" {
764void WerrorS(const char *s)
765{
766#ifdef HAVE_MPSR
767  if (fe_fgets_stdin==fe_fgets_dummy)
768  {
769    if (feErrors==NULL)
770    {
771      feErrors=(char *)omAlloc(256);
772      feErrorsLen=256;
773      *feErrors = '\0';
774    }
775    else
776    {
777      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
778      {
779        feErrors=(char *)omReallocSize(feErrors,feErrorsLen,feErrorsLen+256);
780        feErrorsLen+=256;
781      }
782    }
783    strcat(feErrors, "Singular error: ");
784    strcat(feErrors, (char *)s);
785  }
786  else
787#endif
788  {
789    {
790      if (WerrorS_callback == NULL)
791      {
792        fwrite("   ? ",1,5,stderr);
793        fwrite((char *)s,1,strlen((char *)s),stderr);
794        fwrite("\n",1,1,stderr);
795        fflush(stderr);
796      }
797      else
798      {
799        WerrorS_callback(s);
800      }
801      if (feProt&PROT_O)
802      {
803        fwrite("   ? ",1,5,feProtFile);
804        fwrite((char *)s,1,strlen((char *)s),feProtFile);
805        fwrite("\n",1,1,feProtFile);
806      }
807    }
808  }
809  errorreported = TRUE;
810#ifdef HAVE_FACTORY
811  // libfac:
812  extern int libfac_interruptflag;
813  libfac_interruptflag=1;
814#endif
815}
816
817void Werror(const char *fmt, ...)
818{
819  va_list ap;
820  va_start(ap, fmt);
821  char *s=(char *)omAlloc(256);
822  vsprintf(s, fmt, ap);
823  WerrorS(s);
824  omFreeSize(s,256);
825  va_end(ap);
826}
827
828void WarnS(const char *s)
829{
830  #define warn_str "// ** "
831  if (feWarn) /* ignore warnings if option --no-warn was given */
832  {
833    fwrite(warn_str,1,6,stdout);
834    fwrite(s,1,strlen(s),stdout);
835    fwrite("\n",1,1,stdout);
836    fflush(stdout);
837    if (feProt&PROT_O)
838    {
839      fwrite(warn_str,1,6,feProtFile);
840      fwrite(s,1,strlen(s),feProtFile);
841      fwrite("\n",1,1,feProtFile);
842    }
843  }
844}
845} /* end extern "C" */
846
847void Warn(const char *fmt, ...)
848{
849  va_list ap;
850  va_start(ap, fmt);
851  char *s=(char *)omAlloc(256);
852  vsprintf(s, fmt, ap);
853  WarnS(s);
854  omFreeSize(s,256);
855  va_end(ap);
856}
857
858
859// some routines which redirect the output of print to a string
860static char* sprint = NULL;
861static char* sprint_backup = NULL;
862void SPrintStart()
863{
864  if (sprint!=NULL)
865  {
866    if (sprint_backup!=NULL) WerrorS("internal error: SPrintStart");
867    else sprint_backup=sprint;
868  }
869  sprint = omStrDup("");
870}
871
872static void SPrintS(const char* s)
873{
874  omCheckAddr(sprint);
875  if ((s == NULL)||(*s == '\0')) return;
876  int ls = strlen(s);
877
878  char* ns;
879  int l = strlen(sprint);
880  ns = (char*) omAlloc((l + ls + 1)*sizeof(char));
881  if (l > 0) strcpy(ns, sprint);
882
883  strcpy(&(ns[l]), s);
884  omFree(sprint);
885  sprint = ns;
886  omCheckAddr(sprint);
887}
888
889char* SPrintEnd()
890{
891  char* ns = sprint;
892  sprint = sprint_backup;
893  sprint_backup=NULL;
894  omCheckAddr(ns);
895  return ns;
896}
897
898// Print routines
899extern "C" {
900void PrintS(const char *s)
901{
902  if (sprint != NULL)
903  {
904    SPrintS(s);
905    return;
906  }
907  else if (feOut) /* do not print when option --no-out was given */
908  {
909    {
910      fwrite(s,1,strlen(s),stdout);
911      fflush(stdout);
912      if (feProt&PROT_O)
913      {
914        fwrite(s,1,strlen(s),feProtFile);
915      }
916    }
917  }
918}
919
920void PrintLn()
921{
922  PrintS("\n");
923}
924
925void Print(const char *fmt, ...)
926{
927  if (sprint != NULL)
928  {
929    va_list ap;
930    va_start(ap, fmt);
931    omCheckAddr(sprint);
932    int ls = strlen(fmt);
933    if (fmt != NULL && ls > 0)
934    {
935      char* ns;
936      int l = strlen(sprint);
937      ns = (char*) omAlloc(sizeof(char)*(ls + l + 512));
938      if (l > 0)  strcpy(ns, sprint);
939
940#ifdef HAVE_VSNPRINTF
941      l = vsnprintf(&(ns[l]), ls+511, fmt, ap);
942      assume(l != -1);
943#else
944      vsprintf(&(ns[l]), fmt, ap);
945#endif
946      omCheckAddr(ns);
947      omFree(sprint);
948      sprint = ns;
949    }
950    va_end(ap);
951    return;
952  }
953  else if (feOut)
954  {
955    va_list ap;
956    va_start(ap, fmt);
957    int l;
958    long ls=strlen(fmt);
959    char *s=(char *)omAlloc(ls+512);
960#ifdef HAVE_VSNPRINTF
961    l = vsnprintf(s, ls+511, fmt, ap);
962    if ((l==-1)||(s[l]!='\0')||(l!=(int)strlen(s)))
963    {
964      printf("Print problem: l=%d, fmt=>>%s<<\n",l,fmt);
965      s[l]='\0';
966    }
967#else
968    vsprintf(s, fmt, ap);
969#endif
970    PrintS(s);
971    omFree(s);
972    va_end(ap);
973  }
974}
975void PrintNSpaces(const int n)
976{
977  int l=n-1;
978  while(l>=0) { PrintS(" "); l--; }
979}
980
981/* end extern "C" */
982}
983
984#if 0
985void monitor(char* s, int mode)
986{
987  if (feProt)
988  {
989    fclose(feProtFile);
990    feProt = 0;
991  }
992  if ((s!=NULL) && (*s!='\0'))
993  {
994    feProtFile = myfopen(s,"w");
995    if (feProtFile==NULL)
996    {
997      Werror("cannot open %s",s);
998      feProt=0;
999    }
1000    else
1001      feProt = mode;
1002  }
1003}
1004#else
1005void monitor(void *F, int mode)
1006{
1007  if (feProt)
1008  {
1009    fclose(feProtFile);
1010    feProt = 0;
1011  }
1012  if (F!=NULL)
1013  {
1014    feProtFile = (FILE *)F;
1015    feProt = mode;
1016  }
1017}
1018#endif
1019
1020
1021#else /* ! STANDALONE_PARSER */
1022#include <stdio.h>
1023
1024#endif
1025
Note: See TracBrowser for help on using the repository browser.