source: git/kernel/febase.cc @ e53182

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