source: git/Singular/febase.cc @ d9ddf53

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