source: git/kernel/febase.cc @ 5046ce

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