source: git/kernel/febase.cc @ 460c65f

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