source: git/kernel/febase.cc @ f3a8c2e

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