source: git/kernel/febase.cc @ cea6f3

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