source: git/kernel/febase.cc @ 5e600b

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