source: git/kernel/febase.cc @ 57bfa2

spielwiese
Last change on this file since 57bfa2 was 888bfe6, checked in by Hans Schönemann <hannes@…>, 15 years ago
*hannes: StringAppend opt. again git-svn-id: file:///usr/local/Singular/svn/trunk@11137 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 26.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.cc,v 1.22 2008-10-14 07:56:47 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 ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
825  {
826    more = ((more + (8*1024-1))/(8*1024))*(8*1024);
827    int l=s-feBuffer;
828    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
829                                                     more);
830    omMarkAsStaticAddr(feBuffer);
831    feBufferLength=more;
832    s=feBuffer+l;
833#ifndef BSD_SPRINTF
834    feBufferStart=s;
835#endif
836  }
837#ifdef BSD_SPRINTF
838  vsprintf(s, fmt, ap);
839  while (*s!='\0') s++;
840  feBufferStart =s;
841#else
842#ifdef HAVE_VSNPRINTF
843  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
844  if (vs == -1)
845  {
846    assume(0);
847    feBufferStart = feBuffer + feBufferLength -1;
848  }
849  else
850  {
851    feBufferStart += vs;
852  }
853#else
854  feBufferStart += vsprintf(s, fmt, ap);
855#endif
856#endif
857  omCheckAddrSize(feBuffer, feBufferLength);
858  va_end(ap);
859  return feBuffer;
860}
861
862char * StringAppendS(const char *st)
863{
864  if (*st!='\0')
865  {
866    /* feBufferStart is feBuffer + strlen(feBuffer);*/
867    int l;
868    long more;
869    int ll=feBufferStart-feBuffer;
870    if ((more=ll+2+(l=strlen(st)))>feBufferLength)
871    {
872      more = ((more + (8*1024-1))/(8*1024))*(8*1024);
873      feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
874                                                       more);
875      feBufferLength=more;
876      feBufferStart=feBuffer+ll;
877    }
878    strcat(feBufferStart, st);
879    feBufferStart +=l;
880  }
881  return feBuffer;
882}
883
884char * StringSetS(const char *st)
885{
886  int l;
887  long more;
888  if ((l=strlen(st))>feBufferLength)
889  {
890    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
891    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
892                                                     more);
893    feBufferLength=more;
894  }
895  strcpy(feBuffer,st);
896  feBufferStart=feBuffer+l;
897  return feBuffer;
898}
899
900#ifdef HAVE_TCL
901extern "C" {
902void PrintTCLS(const char c, const char *s)
903{
904  int l=strlen(s);
905  if (l>0) PrintTCL(c,l,s);
906}
907}
908#endif
909
910extern "C" {
911void WerrorS(const char *s)
912{
913#ifdef HAVE_MPSR
914  if (fe_fgets_stdin==fe_fgets_dummy)
915  {
916    if (feErrors==NULL)
917    {
918      feErrors=(char *)omAlloc(256);
919      feErrorsLen=256;
920      *feErrors = '\0';
921    }
922    else
923    {
924      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
925      {
926        feErrors=(char *)omReallocSize(feErrors,feErrorsLen,feErrorsLen+256);
927        feErrorsLen+=256;
928      }
929    }
930    strcat(feErrors, "Singular error: ");
931    strcat(feErrors, (char *)s);
932  }
933  else
934#endif
935  {
936#ifdef HAVE_TCL
937    if (tclmode)
938    {
939      PrintTCLS('E',(char *)s);
940      PrintTCLS('E',"\n");
941    }
942    else
943#endif
944    {
945      fwrite("   ? ",1,5,stderr);
946      fwrite((char *)s,1,strlen((char *)s),stderr);
947      fwrite("\n",1,1,stderr);
948      fflush(stderr);
949      if (feProt&PROT_O)
950      {
951        fwrite("   ? ",1,5,feProtFile);
952        fwrite((char *)s,1,strlen((char *)s),feProtFile);
953        fwrite("\n",1,1,feProtFile);
954      }
955    }
956  }
957  errorreported = TRUE;
958#ifdef HAVE_LIBFAC_P
959  extern int libfac_interruptflag;
960  libfac_interruptflag=1;
961#endif
962}
963
964void Werror(const char *fmt, ...)
965{
966  va_list ap;
967  va_start(ap, fmt);
968  char *s=(char *)omAlloc(256);
969  vsprintf(s, fmt, ap);
970  WerrorS(s);
971  omFreeSize(s,256);
972  va_end(ap);
973}
974
975void WarnS(const char *s)
976{
977  #define warn_str "// ** "
978#ifdef HAVE_TCL
979  if (tclmode)
980  {
981    PrintTCLS('W',warn_str);
982    PrintTCLS('W',s);
983    PrintTCLS('W',"\n");
984  }
985  else
986#endif
987  if (feWarn) /* ignore warnings if option --no-warn was given */
988  {
989    fwrite(warn_str,1,6,stdout);
990    fwrite(s,1,strlen(s),stdout);
991    fwrite("\n",1,1,stdout);
992    fflush(stdout);
993    if (feProt&PROT_O)
994    {
995      fwrite(warn_str,1,6,feProtFile);
996      fwrite(s,1,strlen(s),feProtFile);
997      fwrite("\n",1,1,feProtFile);
998    }
999  }
1000}
1001} /* end extern "C" */
1002
1003void Warn(const char *fmt, ...)
1004{
1005  va_list ap;
1006  va_start(ap, fmt);
1007  char *s=(char *)omAlloc(256);
1008  vsprintf(s, fmt, ap);
1009  WarnS(s);
1010  omFreeSize(s,256);
1011  va_end(ap);
1012}
1013
1014
1015// some routines which redirect the output of print to a string
1016static char* sprint = NULL;
1017void SPrintStart()
1018{
1019  sprint = omStrDup("");
1020}
1021
1022static void SPrintS(const char* s)
1023{
1024  omCheckAddr(sprint);
1025  if ((s == NULL)||(*s == '\0')) return;
1026  int ls = strlen(s);
1027
1028  char* ns;
1029  int l = strlen(sprint);
1030  ns = (char*) omAlloc((l + ls + 1)*sizeof(char));
1031  if (l > 0) strcpy(ns, sprint);
1032
1033  strcpy(&(ns[l]), s);
1034  omFree(sprint);
1035  sprint = ns;
1036  omCheckAddr(sprint);
1037}
1038
1039char* SPrintEnd()
1040{
1041  char* ns = sprint;
1042  sprint = NULL;
1043  omCheckAddr(ns);
1044  return ns;
1045}
1046
1047// Print routines
1048extern "C" {
1049void PrintS(const char *s)
1050{
1051  if (sprint != NULL)
1052  {
1053    SPrintS(s);
1054    return;
1055  }
1056  else if (feOut) /* do not print when option --no-out was given */
1057  {
1058
1059#ifdef HAVE_TCL
1060    if (tclmode)
1061    {
1062      PrintTCLS('N',s);
1063    }
1064    else
1065#endif
1066    {
1067      fwrite(s,1,strlen(s),stdout);
1068      fflush(stdout);
1069      if (feProt&PROT_O)
1070      {
1071        fwrite(s,1,strlen(s),feProtFile);
1072      }
1073    }
1074  }
1075}
1076
1077void PrintLn()
1078{
1079  PrintS("\n");
1080}
1081
1082void Print(const char *fmt, ...)
1083{
1084  if (sprint != NULL)
1085  {
1086    va_list ap;
1087    va_start(ap, fmt);
1088    omCheckAddr(sprint);
1089    int ls = strlen(fmt);
1090    if (fmt != NULL && ls > 0)
1091    {
1092      char* ns;
1093      int l = strlen(sprint);
1094      ns = (char*) omAlloc(sizeof(char)*(ls + l + 512));
1095      if (l > 0)  strcpy(ns, sprint);
1096
1097#ifdef HAVE_VSNPRINTF
1098      l = vsnprintf(&(ns[l]), ls+511, fmt, ap);
1099      assume(l != -1);
1100#else
1101      vsprintf(&(ns[l]), fmt, ap);
1102#endif
1103      omCheckAddr(ns);
1104      omFree(sprint);
1105      sprint = ns;
1106    }
1107    va_end(ap);
1108    return;
1109  }
1110  else if (feOut)
1111  {
1112    va_list ap;
1113    va_start(ap, fmt);
1114    int l;
1115    long ls=strlen(fmt);
1116    char *s=(char *)omAlloc(ls+512);
1117#ifdef HAVE_VSNPRINTF
1118    l = vsnprintf(s, ls+511, fmt, ap);
1119    if ((l==-1)||(s[l]!='\0')||(l!=strlen(s)))
1120    {
1121      printf("Print problem: l=%d, fmt=>>%s<<\n",l,fmt);
1122    }
1123#else
1124    vsprintf(s, fmt, ap);
1125#endif
1126    PrintS(s);
1127    omFree(s);
1128    va_end(ap);
1129  }
1130}
1131void PrintNSpaces(const int n)
1132{
1133  int l=n-1;
1134  while(l>=0) { PrintS(" "); l--; }
1135}
1136
1137/* end extern "C" */
1138}
1139
1140#if 0
1141void monitor(char* s, int mode)
1142{
1143  if (feProt)
1144  {
1145    fclose(feProtFile);
1146    feProt = 0;
1147  }
1148  if ((s!=NULL) && (*s!='\0'))
1149  {
1150    feProtFile = myfopen(s,"w");
1151    if (feProtFile==NULL)
1152    {
1153      Werror("cannot open %s",s);
1154      feProt=0;
1155    }
1156    else
1157      feProt = mode;
1158  }
1159}
1160#else
1161void monitor(void *F, int mode)
1162{
1163  if (feProt)
1164  {
1165    fclose(feProtFile);
1166    feProt = 0;
1167  }
1168  if (F!=NULL)
1169  {
1170    feProtFile = (FILE *)F;
1171    feProt = mode;
1172  }
1173}
1174#endif
1175
1176
1177const char* eati(const char *s, int *i)
1178{
1179  int l=0;
1180
1181  if    (*s >= '0' && *s <= '9')
1182  {
1183    *i = 0;
1184    while (*s >= '0' && *s <= '9')
1185    {
1186      *i *= 10;
1187      *i += *s++ - '0';
1188      l++;
1189      if ((l>=MAX_INT_LEN)||((*i) <0))
1190      {
1191        s-=l;
1192        Werror("`%s` greater than %d(max. integer representation)",
1193                s,MAX_INT_VAL);
1194        return s;
1195      }
1196    }
1197  }
1198  else *i = 1;
1199  return s;
1200}
1201#else /* ! STANDALONE_PARSER */
1202#include <stdio.h>
1203
1204#endif
1205
1206#ifdef ix86_Win
1207// Make sure that mode contains binary option
1208FILE* myfopen(const char *path, const char *mode)
1209{
1210  char mmode[4];
1211  int i;
1212  int done = 0;
1213
1214  for (i=0;;i++)
1215  {
1216    mmode[i] = mode[i];
1217    if (mode[i] == '\0') break;
1218    if (mode[i] == 'w') done = 1;
1219    if (mode[i] == 'a') done = 1;
1220    if (mode[i] == 'b') done = 1;
1221  }
1222
1223  if (! done)
1224  {
1225    mmode[i] = 'b';
1226    mmode[i+1] = '\0';
1227  }
1228  return fopen(path, mmode);
1229}
1230#endif
1231// replace "\r\n" by " \n" and "\r" by "\n"
1232
1233size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
1234{
1235  size_t got = fread(ptr, size, nmemb, stream) * size;
1236  size_t i;
1237
1238  for (i=0; i<got; i++)
1239  {
1240    if ( ((char*) ptr)[i] == '\r')
1241    {
1242      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
1243        ((char*) ptr)[i] = ' ';
1244      else
1245        ((char*) ptr)[i] = '\n';
1246    }
1247  }
1248  return got;
1249}
Note: See TracBrowser for help on using the repository browser.