source: git/Singular/febase.cc @ d2b2a7

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