source: git/Singular/febase.cc @ c06a32

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