source: git/Singular/febase.cc @ 9b1e4c

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