source: git/kernel/febase.cc @ 670ad3

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