source: git/Singular/febase.cc @ ec47b5

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