source: git/kernel/febase.cc @ 6eccc9

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