source: git/kernel/febase.cc @ e7c6b22

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