source: git/kernel/febase.cc @ 111cfe

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