source: git/kernel/febase.cc @ b10eee

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