source: git/Singular/febase.cc @ f4edee

fieker-DuValspielwiese
Last change on this file since f4edee was f4edee, checked in by Hans Schönemann <hannes@…>, 25 years ago
* hannes: made fe_fgets_stdin an function pointer instead of a macro git-svn-id: file:///usr/local/Singular/svn/trunk@3430 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.cc,v 1.79 1999-08-13 11:21:42 Singular Exp $ */
5/*
6* ABSTRACT: i/o system
7*/
8
9#include "mod2.h"
10
11#include <stdlib.h>
12#include <stdio.h>
13#include <limits.h>
14#include <stdarg.h>
15#ifndef __MWERKS__
16#include <unistd.h>
17#endif
18#ifdef NeXT
19#include <sys/file.h>
20#endif
21
22#include "tok.h"
23#include "febase.h"
24#include "mmemory.h"
25#include "subexpr.h"
26#include "ipshell.h"
27#include "version.h"
28
29
30#define fePutChar(c) fputc((uchar)(c),stdout)
31/*0 implementation */
32
33char fe_promptstr[]
34#ifdef macintosh
35                   =" \n";
36#else
37                   ="  ";
38#endif
39
40#define INITIAL_PRINT_BUFFER 24*1024
41static int feBufferLength=INITIAL_PRINT_BUFFER;
42static char * feBuffer=(char *)Alloc(INITIAL_PRINT_BUFFER);
43
44int     si_echo = 0;
45int     printlevel = 0;
46#ifndef macintosh
47int     pagelength = 24;
48#else
49int     pagelength = -1;
50#endif
51int     colmax = 80;
52char    prompt_char = '>'; /*1 either '>' or '.'*/
53extern "C" {
54BITSET  verbose = 1
55                  | Sy_bit(V_REDEFINE)
56                  | Sy_bit(V_LOAD_LIB)
57                  | Sy_bit(V_SHOW_USE)
58                  | Sy_bit(V_PROMPT)
59/*                  | Sy_bit(V_DEBUG_MEM) */
60;}
61BOOLEAN errorreported = FALSE;
62char *  feErrors=NULL;
63int     feErrorsLen=0;
64BOOLEAN feWarn = TRUE;
65BOOLEAN feOut = TRUE;
66
67#ifdef macintosh
68static  int lines = 0;
69static  int cols = 0;
70#endif
71
72const char feNotImplemented[]="not implemented";
73
74BOOLEAN feProt = FALSE;
75FILE*   feProtFile;
76BOOLEAN tclmode=FALSE;
77/* TCL-Protocoll (Singular -x): <char type>:<int length>:<string> \n
78*  E:l:s  error
79*  W:l:s  warning
80*  N:l:s  stdout
81*  Q:0:   quit
82*  P:l:   prompt > (ring defined)
83*  U:l:   prompt > (no ring defined)
84*  P:l:   prompt .
85*  R:l:<ring-name> ring change
86*  L:l:<lib name> library loaded
87*  O:l:<list of options(space seperated)> option change
88*  M:l:<mem-usage> output from "option(mem)"
89*/
90
91#include "febase.inc"
92
93/*****************************************************************
94 *
95 * File handling
96 *
97 *****************************************************************/
98
99FILE * feFopen(char *path, char *mode, char *where,int useWerror)
100{
101  char longpath[MAXPATHLEN];
102  if (path[0]=='~')
103  {
104    char* home = getenv("HOME");
105    if (home != NULL)
106    {
107      strcpy(longpath, home);
108      strcat(longpath, &(path[1]));
109      path = longpath;
110    }
111  }
112  FILE * f=myfopen(path,mode);
113  if (where!=NULL) strcpy(where,path);
114  if ((*mode=='r') && (path[0]!=DIR_SEP)&&(path[0]!='.')
115  &&(f==NULL))
116  {
117    char found = 0;
118    char* spath = feResource('s');
119    char *s;
120
121    if (where==NULL) s=(char *)AllocL(250);
122    else             s=where;
123
124    if (spath!=NULL)
125    {
126      char *p,*q;
127      p = spath;
128      while( (q=strchr(p, fePathSep)) != NULL)
129      {
130        *q = '\0';
131        strcpy(s,p);
132        *q = fePathSep;
133        strcat(s, DIR_SEPP);
134        strcat(s, path);
135        #ifndef macintosh
136          if(!access(s, R_OK)) { found++; break; }
137        #else
138          f=fopen(s,mode); /* do not need myfopen: we test only the access */
139          if (f!=NULL)  { found++; fclose(f); break; }
140        #endif
141        p = q+1;
142      }
143      if(!found)
144      {
145        strcpy(s,p);
146        strcat(s, DIR_SEPP);
147        strcat(s, path);
148      }
149      f=myfopen(s,mode);
150      if (f!=NULL)
151      {
152        if (where==NULL) FreeL((ADDRESS)s);
153        return f;
154      }
155    }
156    else
157    {
158      if (where!=NULL) strcpy(s/*where*/,path);
159      f=myfopen(path,mode);
160    }
161    if (where==NULL) FreeL((ADDRESS)s);
162  }
163  if ((f==NULL)&&(useWerror))
164    Werror("cannot open `%s`",path);
165  return f;
166}
167
168static char * feBufferStart;
169  /* only used in StringSet(S)/StringAppend(S)*/
170char * StringAppend(char *fmt, ...)
171{
172  va_list ap;
173  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
174  int more, vs;
175  va_start(ap, fmt);
176  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
177  {
178    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
179    int l=s-feBuffer;
180    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
181                                                     more);
182    feBufferLength=more;
183    s=feBuffer+l;
184#ifndef BSD_SPRINTF
185    feBufferStart=s;
186#endif
187  }
188#ifdef BSD_SPRINTF
189  vsprintf(s, fmt, ap);
190  while (*s!='\0') s++;
191  feBufferStart =s;
192#else
193#ifdef HAVE_VSNPRINTF
194  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
195  if (vs == -1)
196  {
197    assume(0);
198    feBufferStart = feBuffer + feBufferLength -1;
199  }
200  else
201  {
202    feBufferStart += vs;
203  }
204#else
205  feBufferStart += vsprintf(s, fmt, ap);
206#endif
207#endif
208  mmTest(feBuffer, feBufferLength);
209  va_end(ap);
210  return feBuffer;
211}
212
213char * StringAppendS(char *st)
214{
215  /* feBufferStart is feBuffer + strlen(feBuffer);*/
216  int more,l;
217  int ll=feBufferStart-feBuffer;
218  if ((more=ll+2+(l=strlen(st)))>feBufferLength)
219  {
220    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
221    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
222                                                     more);
223    feBufferLength=more;
224    feBufferStart=feBuffer+ll;
225  }
226  strcat(feBufferStart, st);
227  feBufferStart +=l;
228  return feBuffer;
229}
230
231char * StringSetS(char *st)
232{
233  int more,l;
234  if ((l=strlen(st))>feBufferLength)
235  {
236    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
237    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
238                                                     more);
239    feBufferLength=more;
240  }
241  strcpy(feBuffer,st);
242  feBufferStart=feBuffer+l;
243  return feBuffer;
244}
245
246#ifndef __MWERKS__
247#ifdef HAVE_TCL
248extern "C" {
249void PrintTCLS(const char c, const char *s)
250{
251  int l=strlen(s);
252  if (l>0) PrintTCL(c,l,s);
253}
254}
255#endif
256#endif
257
258extern "C" {
259void WerrorS(const char *s)
260{
261#ifdef HAVE_MPSR
262  if (fe_fgets_stdin==fe_fgets_dummy)
263  {
264    if (feErrors==NULL)
265    {
266      feErrors=(char *)Alloc(256);
267      feErrorsLen=256;
268      *feErrors = '\0';
269    }
270    else
271    {
272      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
273      {
274        feErrors=(char *)ReAlloc(feErrors,feErrorsLen,feErrorsLen+256);
275        feErrorsLen+=256;
276      }
277    }
278    strcat(feErrors, "Singular error: ");
279    strcat(feErrors, (char *)s);
280  }
281  else
282#endif
283  {
284#ifdef HAVE_TCL
285    if (tclmode)
286    {
287      PrintTCLS('E',(char *)s);
288      PrintTCLS('E',"\n");
289    }
290    else
291#endif
292    {
293      fwrite("   ? ",1,5,stderr);
294      fwrite((char *)s,1,strlen((char *)s),stderr);
295      fwrite("\n",1,1,stderr);
296      fflush(stderr);
297      if (feProt&PROT_O)
298      {
299        fwrite("   ? ",1,5,feProtFile);
300        fwrite((char *)s,1,strlen((char *)s),feProtFile);
301        fwrite("\n",1,1,feProtFile);
302      }
303    }
304  }
305  errorreported = TRUE;
306}
307
308void Werror(char *fmt, ...)
309{
310  va_list ap;
311  va_start(ap, fmt);
312  char *s=(char *)Alloc(256);
313  vsprintf(s, fmt, ap);
314  WerrorS(s);
315  Free(s,256);
316  va_end(ap);
317}
318}
319
320void WarnS(const char *s)
321{
322  #define warn_str "// ** "
323#ifdef HAVE_TCL
324  if (tclmode)
325  {
326    PrintTCLS('W',warn_str);
327    PrintTCLS('W',s);
328    PrintTCLS('W',"\n");
329  }
330  else
331#endif
332  if (feWarn) /* ignore warnings if option --no-warn was given */
333  {
334    fwrite(warn_str,1,6,stdout);
335    fwrite(s,1,strlen(s),stdout);
336    fwrite("\n",1,1,stdout);
337    fflush(stdout);
338    if (feProt&PROT_O)
339    {
340      fwrite(warn_str,1,6,feProtFile);
341      fwrite(s,1,strlen(s),feProtFile);
342      fwrite("\n",1,1,feProtFile);
343    }
344  }
345}
346
347void Warn(const char *fmt, ...)
348{
349  va_list ap;
350  va_start(ap, fmt);
351  char *s=(char *)Alloc(256);
352  vsprintf(s, fmt, ap);
353  WarnS(s);
354  Free(s,256);
355  va_end(ap);
356}
357
358void fePrintReportBug(char* msg, char* file, int line)
359{
360  WarnS("YOU HAVE FOUND A BUG IN SINGULAR.");
361  WarnS("Please, email the following output to singular@mathematik.uni-kl.de");
362  Warn("Bug occured at %s:%d", file, line);
363  Warn("Message: %s", msg);
364  Warn("Version: %s %s (%d) %s %s", S_UNAME, S_VERSION1,
365       SINGULAR_VERSION_ID,__DATE__,__TIME__);
366}
367
368extern "C" {
369void assume_violation(char* file, int line)
370{
371  fprintf(stderr, "Internal assume violation: file %s line %d\n", file, line);
372}
373}
374
375#ifdef macintosh
376static  int lines = 0;
377static  int cols = 0;
378
379void mwrite(uchar c)
380{
381  if (c == '\n')
382  {
383    cols = 0;
384    if (lines == pagelength)
385    {
386      lines = 0;
387      fputs("pause>\n",stderr);
388      uchar c = fgetc(stdin);
389    }
390    else
391    {
392      lines++;
393      fePutChar(c);
394    }
395  }
396  else
397  {
398    fePutChar(c);
399    cols++;
400    if (cols == colmax)
401    {
402      // cols = 0;   //will be done by mwrite('\n');
403      mwrite('\n');
404    }
405  }
406}
407#endif
408
409// some routines which redirect the output of print to a string
410static char* sprint = NULL;
411void SPrintStart()
412{
413  sprint = mstrdup("");
414}
415
416static void SPrintS(char* s)
417{
418  mmTestL(sprint);
419  if (s == NULL) return;
420  int ls = strlen(s);
421  if (ls == 0) return;
422
423  char* ns;
424  int l = strlen(sprint);
425  ns = (char*) AllocL((l + ls + 1)*sizeof(char));
426  if (l > 0) strcpy(ns, sprint);
427
428  strcpy(&(ns[l]), s);
429  FreeL(sprint);
430  sprint = ns;
431  mmTestL(sprint);
432}
433
434char* SPrintEnd()
435{
436  char* ns = sprint;
437  sprint = NULL;
438  mmTestL(ns);
439  return ns;
440}
441
442// Print routines
443extern "C" {
444void PrintS(char *s)
445{
446  if (sprint != NULL)
447  {
448    SPrintS(s);
449    return;
450  }
451
452  if (feOut) /* do not print when option --no-out was given */
453  {
454
455#ifdef macintosh
456    char c;
457    while ('\0' != (c = *s++))
458    {
459      mwrite(c);
460    }
461#else
462#ifdef HAVE_TCL
463    if (tclmode)
464    {
465      PrintTCLS('N',s);
466    }
467    else
468#endif
469    {
470      fwrite(s,1,strlen(s),stdout);
471      fflush(stdout);
472      if (feProt&PROT_O)
473      {
474        fwrite(s,1,strlen(s),feProtFile);
475      }
476    }
477#endif
478  }
479}
480
481void PrintLn()
482{
483  PrintS("\n");
484}
485
486void Print(char *fmt, ...)
487{
488  if (sprint != NULL)
489  {
490    int ls = strlen(fmt);
491    va_list ap;
492    va_start(ap, fmt);
493    mmTestL(sprint);
494    if (fmt != NULL && ls > 0)
495    {
496      char* ns;
497      int l = strlen(sprint);
498      ns = (char*) AllocL(sizeof(char)*(ls + l + 256));
499      if (l > 0)  strcpy(ns, sprint);
500
501#ifdef HAVE_VSNPRINTF
502      l = vsnprintf(&(ns[l]), ls+255, fmt, ap);
503      assume(l != -1);
504#else
505      vsprintf(&(ns[l]), fmt, ap);
506#endif
507      mmTestL(ns);
508      FreeL(sprint);
509      sprint = ns;
510    }
511    va_end(ap);
512    return;
513  }
514  if (feOut)
515  {
516    va_list ap;
517    va_start(ap, fmt);
518#ifdef HAVE_TCL
519    if(tclmode)
520#endif
521#if (defined(HAVE_TCL) || defined(macintosh))
522    {
523      char *s=(char *)Alloc(strlen(fmt)+256);
524      vsprintf(s,fmt, ap);
525#ifdef HAVE_TCL
526      PrintTCLS('N',s);
527#endif
528#ifdef macintosh
529      char c;
530      while ('\0' != (c = *s++))
531      {
532        mwrite(c);
533      }
534      if (feProt&PROT_O)
535      {
536        vfprintf(feProtFile,fmt,ap);
537      }
538#endif
539    }
540#endif
541#if !defined(macintosh) || defined(HAVE_TCL)
542#ifdef HAVE_TCL
543    else
544#endif
545    {
546      vfprintf(stdout, fmt, ap);
547      fflush(stdout);
548      if (feProt&PROT_O)
549      {
550        vfprintf(feProtFile,fmt,ap);
551      }
552    }
553#endif
554    va_end(ap);
555  }
556}
557
558/* end extern "C" */
559}
560
561void monitor(char* s, int mode)
562{
563  if (feProt)
564  {
565    fclose(feProtFile);
566  }
567  if ((s!=NULL) && (*s!='\0'))
568  {
569    feProtFile = myfopen(s,"w");
570    if (feProtFile==NULL)
571    {
572      Werror("cannot open %s",s);
573    }
574    else
575      feProt = (BOOLEAN)mode;
576  }
577}
578
579
580char* eati(char *s, int *i)
581{
582  int l=0;
583
584  if    (*s >= '0' && *s <= '9')
585  {
586    *i = 0;
587    while (*s >= '0' && *s <= '9')
588    {
589      *i *= 10;
590      *i += *s++ - '0';
591      l++;
592      if ((l>=MAX_INT_LEN)||((*i) <0))
593      {
594        s-=l;
595        Werror("`%s` greater than %d(max. integer representation)",
596                s,MAX_INT_VAL);
597        return s;
598      }
599    }
600  }
601  else *i = 1;
602  return s;
603}
604
605#ifndef unix
606// Make sure that mode contains binary option
607FILE *myfopen(char *path, char *mode)
608{
609  char mmode[4];
610  int i;
611  BOOLEAN done = FALSE;
612
613  for (i=0;;i++)
614  {
615    mmode[i] = mode[i];
616    if (mode[i] == '\0') break;
617    if (mode[i] == 'b') done = TRUE;
618  }
619
620  if (! done)
621  {
622    mmode[i] = 'b';
623    mmode[i+1] = '\0';
624  }
625  return fopen(path, mmode);
626}
627#endif
628
629// replace "\r\n" by " \n" and "\r" by "\n"
630
631size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
632{
633  size_t got = fread(ptr, size, nmemb, stream) * size;
634  size_t i;
635
636  for (i=0; i<got; i++)
637  {
638    if ( ((char*) ptr)[i] == '\r')
639    {
640      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
641        ((char*) ptr)[i] = ' ';
642      else
643        ((char*) ptr)[i] = '\n';
644    }
645  }
646  return got;
647}
Note: See TracBrowser for help on using the repository browser.