source: git/Singular/febase.cc @ 4a0a5d5

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