source: git/kernel/febase.cc @ 0f401f

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