source: git/Singular/febase.cc @ 138f0c

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