source: git/kernel/febase.cc @ 528f5b7

spielwiese
Last change on this file since 528f5b7 was a57ef5, checked in by Hans Schoenemann <hannes@…>, 13 years ago
error handling for Print git-svn-id: file:///usr/local/Singular/svn/trunk@13933 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 25.6 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
83static 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/*****************************************************************
678 *
679 * File handling
680 *
681 *****************************************************************/
682
683FILE * feFopen(const char *path, const char *mode, char *where,
684               int useWerror, int path_only)
685{
686  char longpath[MAXPATHLEN];
687  if (path[0]=='~')
688  {
689    if (path[1] == DIR_SEP)
690    {
691      const char* home = getenv("HOME");
692#ifdef ix86_Win
693      if ((home==NULL)||(!access(home,X_OK)))
694        home = getenv("SINGHOME");
695#endif
696      if (home != NULL)
697      {
698        strcpy(longpath, home);
699        strcat(longpath, &(path[1]));
700        path = longpath;
701      }
702    }
703#if defined(HAVE_PWD_H) && defined(HAVE_GETPWNAM)
704    else
705    {
706      char* dir_sep;
707      struct passwd *pw_entry;
708      strcpy (longpath, path);
709      dir_sep = strchr(longpath, DIR_SEP);
710      *dir_sep = '\0';
711      pw_entry = getpwnam(&longpath[1]);
712      if (pw_entry != NULL)
713      {
714        strcpy(longpath, pw_entry->pw_dir);
715        dir_sep = strchr((char *)path, DIR_SEP);
716        strcat(longpath, dir_sep);
717        path = longpath;
718      }
719    }
720#endif
721  }
722  FILE * f=NULL;
723  if (! path_only)
724  {
725    struct stat statbuf;
726    if ((stat(path,&statbuf)==0)
727    && (S_ISREG(statbuf.st_mode)))
728      f = myfopen(path,mode);
729  }
730  if (where!=NULL) strcpy(where,path);
731  if ((*mode=='r') &&
732      (path[0]!=DIR_SEP) &&
733      ! (path[0] == '.' && path[1] == DIR_SEP) &&
734      (f==NULL))
735  {
736    char found = 0;
737    char* spath = feResource('s');
738    char *s;
739
740    if (where==NULL) s=(char *)omAlloc(250);
741    else             s=where;
742
743    if (spath!=NULL)
744    {
745      char *p,*q;
746      p = spath;
747      while( (q=strchr(p, fePathSep)) != NULL)
748      {
749        *q = '\0';
750        strcpy(s,p);
751        *q = fePathSep;
752        strcat(s, DIR_SEPP);
753        strcat(s, path);
754        if(!access(s, R_OK)) { found++; break; }
755        p = q+1;
756      }
757      if(!found)
758      {
759        strcpy(s,p);
760        strcat(s, DIR_SEPP);
761        strcat(s, path);
762      }
763      f=myfopen(s,mode);
764      if (f!=NULL)
765      {
766        if (where==NULL) omFree((ADDRESS)s);
767        return f;
768      }
769    }
770    else
771    {
772      if (where!=NULL) strcpy(s/*where*/,path);
773      f=myfopen(path,mode);
774    }
775    if (where==NULL) omFree((ADDRESS)s);
776  }
777  if ((f==NULL)&&(useWerror))
778    Werror("cannot open `%s`",path);
779  return f;
780}
781
782static char * feBufferStart;
783  /* only used in StringSet(S)/StringAppend(S)*/
784char * StringAppend(const char *fmt, ...)
785{
786  va_list ap;
787  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
788  int vs;
789  long more;
790  va_start(ap, fmt);
791  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
792  {
793    more = ((more + (8*1024-1))/(8*1024))*(8*1024);
794    int l=s-feBuffer;
795    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
796                                                     more);
797    omMarkAsStaticAddr(feBuffer);
798    feBufferLength=more;
799    s=feBuffer+l;
800#ifndef BSD_SPRINTF
801    feBufferStart=s;
802#endif
803  }
804#ifdef BSD_SPRINTF
805  vsprintf(s, fmt, ap);
806  while (*s!='\0') s++;
807  feBufferStart =s;
808#else
809#ifdef HAVE_VSNPRINTF
810  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
811  if (vs == -1)
812  {
813    assume(0);
814    feBufferStart = feBuffer + feBufferLength -1;
815  }
816  else
817  {
818    feBufferStart += vs;
819  }
820#else
821  feBufferStart += vsprintf(s, fmt, ap);
822#endif
823#endif
824  omCheckAddrSize(feBuffer, feBufferLength);
825  va_end(ap);
826  return feBuffer;
827}
828
829char * StringAppendS(const char *st)
830{
831  if (*st!='\0')
832  {
833    /* feBufferStart is feBuffer + strlen(feBuffer);*/
834    int l;
835    long more;
836    int ll=feBufferStart-feBuffer;
837    if ((more=ll+2+(l=strlen(st)))>feBufferLength)
838    {
839      more = ((more + (8*1024-1))/(8*1024))*(8*1024);
840      feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
841                                                       more);
842      feBufferLength=more;
843      feBufferStart=feBuffer+ll;
844    }
845    strcat(feBufferStart, st);
846    feBufferStart +=l;
847  }
848  return feBuffer;
849}
850
851char * StringSetS(const char *st)
852{
853  int l;
854  long more;
855  if ((l=strlen(st))>feBufferLength)
856  {
857    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
858    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
859                                                     more);
860    feBufferLength=more;
861  }
862  strcpy(feBuffer,st);
863  feBufferStart=feBuffer+l;
864  return feBuffer;
865}
866
867extern "C" {
868void WerrorS(const char *s)
869{
870#ifdef HAVE_MPSR
871  if (fe_fgets_stdin==fe_fgets_dummy)
872  {
873    if (feErrors==NULL)
874    {
875      feErrors=(char *)omAlloc(256);
876      feErrorsLen=256;
877      *feErrors = '\0';
878    }
879    else
880    {
881      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
882      {
883        feErrors=(char *)omReallocSize(feErrors,feErrorsLen,feErrorsLen+256);
884        feErrorsLen+=256;
885      }
886    }
887    strcat(feErrors, "Singular error: ");
888    strcat(feErrors, (char *)s);
889  }
890  else
891#endif
892  {
893    {
894      if (WerrorS_callback == NULL)
895      {
896        fwrite("   ? ",1,5,stderr);
897        fwrite((char *)s,1,strlen((char *)s),stderr);
898        fwrite("\n",1,1,stderr);
899        fflush(stderr);
900      }
901      else
902      {
903        WerrorS_callback(s);
904      }
905      if (feProt&PROT_O)
906      {
907        fwrite("   ? ",1,5,feProtFile);
908        fwrite((char *)s,1,strlen((char *)s),feProtFile);
909        fwrite("\n",1,1,feProtFile);
910      }
911    }
912  }
913  errorreported = TRUE;
914#ifdef HAVE_FACTORY
915  // libfac:
916  extern int libfac_interruptflag;
917  libfac_interruptflag=1;
918#endif
919}
920
921void Werror(const char *fmt, ...)
922{
923  va_list ap;
924  va_start(ap, fmt);
925  char *s=(char *)omAlloc(256);
926  vsprintf(s, fmt, ap);
927  WerrorS(s);
928  omFreeSize(s,256);
929  va_end(ap);
930}
931
932void WarnS(const char *s)
933{
934  #define warn_str "// ** "
935  if (feWarn) /* ignore warnings if option --no-warn was given */
936  {
937    fwrite(warn_str,1,6,stdout);
938    fwrite(s,1,strlen(s),stdout);
939    fwrite("\n",1,1,stdout);
940    fflush(stdout);
941    if (feProt&PROT_O)
942    {
943      fwrite(warn_str,1,6,feProtFile);
944      fwrite(s,1,strlen(s),feProtFile);
945      fwrite("\n",1,1,feProtFile);
946    }
947  }
948}
949} /* end extern "C" */
950
951void Warn(const char *fmt, ...)
952{
953  va_list ap;
954  va_start(ap, fmt);
955  char *s=(char *)omAlloc(256);
956  vsprintf(s, fmt, ap);
957  WarnS(s);
958  omFreeSize(s,256);
959  va_end(ap);
960}
961
962
963// some routines which redirect the output of print to a string
964static char* sprint = NULL;
965void SPrintStart()
966{
967  sprint = omStrDup("");
968}
969
970static void SPrintS(const char* s)
971{
972  omCheckAddr(sprint);
973  if ((s == NULL)||(*s == '\0')) return;
974  int ls = strlen(s);
975
976  char* ns;
977  int l = strlen(sprint);
978  ns = (char*) omAlloc((l + ls + 1)*sizeof(char));
979  if (l > 0) strcpy(ns, sprint);
980
981  strcpy(&(ns[l]), s);
982  omFree(sprint);
983  sprint = ns;
984  omCheckAddr(sprint);
985}
986
987char* SPrintEnd()
988{
989  char* ns = sprint;
990  sprint = NULL;
991  omCheckAddr(ns);
992  return ns;
993}
994
995// Print routines
996extern "C" {
997void PrintS(const char *s)
998{
999  if (sprint != NULL)
1000  {
1001    SPrintS(s);
1002    return;
1003  }
1004  else if (feOut) /* do not print when option --no-out was given */
1005  {
1006    {
1007      fwrite(s,1,strlen(s),stdout);
1008      fflush(stdout);
1009      if (feProt&PROT_O)
1010      {
1011        fwrite(s,1,strlen(s),feProtFile);
1012      }
1013    }
1014  }
1015}
1016
1017void PrintLn()
1018{
1019  PrintS("\n");
1020}
1021
1022void Print(const char *fmt, ...)
1023{
1024  if (sprint != NULL)
1025  {
1026    va_list ap;
1027    va_start(ap, fmt);
1028    omCheckAddr(sprint);
1029    int ls = strlen(fmt);
1030    if (fmt != NULL && ls > 0)
1031    {
1032      char* ns;
1033      int l = strlen(sprint);
1034      ns = (char*) omAlloc(sizeof(char)*(ls + l + 512));
1035      if (l > 0)  strcpy(ns, sprint);
1036
1037#ifdef HAVE_VSNPRINTF
1038      l = vsnprintf(&(ns[l]), ls+511, fmt, ap);
1039      assume(l != -1);
1040#else
1041      vsprintf(&(ns[l]), fmt, ap);
1042#endif
1043      omCheckAddr(ns);
1044      omFree(sprint);
1045      sprint = ns;
1046    }
1047    va_end(ap);
1048    return;
1049  }
1050  else if (feOut)
1051  {
1052    va_list ap;
1053    va_start(ap, fmt);
1054    int l;
1055    long ls=strlen(fmt);
1056    char *s=(char *)omAlloc(ls+512);
1057#ifdef HAVE_VSNPRINTF
1058    l = vsnprintf(s, ls+511, fmt, ap);
1059    if ((l==-1)||(s[l]!='\0')||(l!=strlen(s)))
1060    {
1061      printf("Print problem: l=%d, fmt=>>%s<<\n",l,fmt);
1062      s[l]='\0';
1063    }
1064#else
1065    vsprintf(s, fmt, ap);
1066#endif
1067    PrintS(s);
1068    omFree(s);
1069    va_end(ap);
1070  }
1071}
1072void PrintNSpaces(const int n)
1073{
1074  int l=n-1;
1075  while(l>=0) { PrintS(" "); l--; }
1076}
1077
1078/* end extern "C" */
1079}
1080
1081#if 0
1082void monitor(char* s, int mode)
1083{
1084  if (feProt)
1085  {
1086    fclose(feProtFile);
1087    feProt = 0;
1088  }
1089  if ((s!=NULL) && (*s!='\0'))
1090  {
1091    feProtFile = myfopen(s,"w");
1092    if (feProtFile==NULL)
1093    {
1094      Werror("cannot open %s",s);
1095      feProt=0;
1096    }
1097    else
1098      feProt = mode;
1099  }
1100}
1101#else
1102void monitor(void *F, int mode)
1103{
1104  if (feProt)
1105  {
1106    fclose(feProtFile);
1107    feProt = 0;
1108  }
1109  if (F!=NULL)
1110  {
1111    feProtFile = (FILE *)F;
1112    feProt = mode;
1113  }
1114}
1115#endif
1116
1117
1118const char* eati(const char *s, int *i)
1119{
1120  int l=0;
1121
1122  if    (*s >= '0' && *s <= '9')
1123  {
1124    *i = 0;
1125    while (*s >= '0' && *s <= '9')
1126    {
1127      *i *= 10;
1128      *i += *s++ - '0';
1129      l++;
1130      if ((l>=MAX_INT_LEN)||((*i) <0))
1131      {
1132        s-=l;
1133        Werror("`%s` greater than %d(max. integer representation)",
1134                s,MAX_INT_VAL);
1135        return s;
1136      }
1137    }
1138  }
1139  else *i = 1;
1140  return s;
1141}
1142#else /* ! STANDALONE_PARSER */
1143#include <stdio.h>
1144
1145#endif
1146
1147#ifdef ix86_Win
1148// Make sure that mode contains binary option
1149FILE* myfopen(const char *path, const char *mode)
1150{
1151  char mmode[4];
1152  int i;
1153  int done = 0;
1154
1155  for (i=0;;i++)
1156  {
1157    mmode[i] = mode[i];
1158    if (mode[i] == '\0') break;
1159    if (mode[i] == 'w') done = 1;
1160    if (mode[i] == 'a') done = 1;
1161    if (mode[i] == 'b') done = 1;
1162  }
1163
1164  if (! done)
1165  {
1166    mmode[i] = 'b';
1167    mmode[i+1] = '\0';
1168  }
1169  return fopen(path, mmode);
1170}
1171#endif
1172// replace "\r\n" by " \n" and "\r" by "\n"
1173
1174size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
1175{
1176  size_t got = fread(ptr, size, nmemb, stream) * size;
1177  size_t i;
1178
1179  for (i=0; i<got; i++)
1180  {
1181    if ( ((char*) ptr)[i] == '\r')
1182    {
1183      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
1184        ((char*) ptr)[i] = ' ';
1185      else
1186        ((char*) ptr)[i] = '\n';
1187    }
1188  }
1189  return got;
1190}
Note: See TracBrowser for help on using the repository browser.