source: git/Singular/febase.cc @ 907274

spielwiese
Last change on this file since 907274 was 52a5e8, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* new memory management scheme git-svn-id: file:///usr/local/Singular/svn/trunk@2703 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 25.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.cc,v 1.70 1998-12-02 13:57:25 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#include "si_paths.h"
29
30#ifndef MAXPATHLEN
31#define MAXPATHLEN 1024
32#endif
33
34#ifndef MAXNAMLEN
35#define MAXNAMLEN MAXPATHLEN
36#endif
37
38#define fePutChar(c) fputc((uchar)(c),stdout)
39/*0 implementation */
40
41char fe_promptstr[]
42#ifdef macintosh
43                   =" \n";
44#else
45                   ="  ";
46#endif
47
48#define INITIAL_PRINT_BUFFER 24*1024
49static int feBufferLength=INITIAL_PRINT_BUFFER;
50static char * feBuffer=(char *)Alloc(INITIAL_PRINT_BUFFER);
51
52int     si_echo = 0;
53int     printlevel = 0;
54#ifndef macintosh
55int     pagelength = 24;
56#else
57int     pagelength = -1;
58#endif
59int     colmax = 80;
60char    prompt_char = '>'; /*1 either '>' or '.'*/
61extern "C" {
62BITSET  verbose = 1
63                  | Sy_bit(V_REDEFINE)
64                  | Sy_bit(V_LOAD_LIB)
65                  | Sy_bit(V_SHOW_USE)
66                  | Sy_bit(V_PROMPT)
67/*                  | Sy_bit(V_DEBUG_MEM) */
68;}
69BOOLEAN errorreported = FALSE;
70BOOLEAN feBatch = FALSE;
71char *  feErrors=NULL;
72int     feErrorsLen=0;
73BOOLEAN feWarn = TRUE;
74BOOLEAN feOut = TRUE;
75
76#ifdef macintosh
77static  int lines = 0;
78static  int cols = 0;
79#endif
80
81const char feNotImplemented[]="not implemented";
82
83BOOLEAN feProt = FALSE;
84FILE*   feProtFile;
85BOOLEAN tclmode=FALSE;
86/* TCL-Protocoll (Singular -x): <char type>:<int length>:<string> \n
87*  E:l:s  error
88*  W:l:s  warning
89*  N:l:s  stdout
90*  Q:0:   quit
91*  P:l:   prompt > (ring defined)
92*  U:l:   prompt > (no ring defined)
93*  P:l:   prompt .
94*  R:l:<ring-name> ring change
95*  L:l:<lib name> library loaded
96*  O:l:<list of options(space seperated)> option change
97*  M:l:<mem-usage> output from "option(mem)"
98*/
99
100#include "febase.inc"
101
102#ifdef macintosh
103#  define  DIR_SEP ':'
104#  define  DIR_SEPP ":"
105#else
106#ifdef MSDOS
107#  define  DIR_SEP '\\'
108#  define  DIR_SEPP "\\"
109#else
110#ifdef atarist
111#  define  DIR_SEP '\\'
112#  define  DIR_SEPP "\\"
113#else  /* unix */
114#  define  DIR_SEP '/'
115#  define  DIR_SEPP "/"
116#endif  /* atarist */
117#endif  /* MSDOS */
118#endif  /* macintosh */
119
120#if defined(WINNT)
121#  define  FS_SEP ';'
122#elif defined(macintosh)
123#define FS_SEP ','
124#else
125#define FS_SEP ':'
126#endif
127
128#ifndef __MWERKS__
129/*****************************************************************
130 *
131 * PATH STUFF
132 *
133 *****************************************************************/
134
135// Define to chatter about path stuff
136// #define PATH_DEBUG
137static char* feArgv0 = NULL;
138static char* feExpandedExecutable = NULL;
139static char* feBinDir = NULL;
140static char* feSearchPath = NULL;
141static char* feInfoProgram = NULL;
142static char* feInfoFile = NULL;
143static char* feInfoCall = NULL;
144
145extern "C" char* find_executable(const char* argv0);
146static char* feRemovePathnameHead(const char* expanded_executable);
147static char* CleanUpPath(char* path);
148static char* CleanUpName(char* filename);
149
150inline char* feGetExpandedExecutable(const char* argv0)
151{
152  return (argv0 != NULL ? find_executable(argv0) : (char* ) NULL);
153}
154
155inline char* feGetBinDir(const char* expanded_executable)
156{
157  return feRemovePathnameHead(expanded_executable);
158}
159
160// Return the file search path for singular w.r.t. the following steps:
161// 1.) SINGULARPATH Env Variable
162// 2.) bindir/LIB
163// 3.) bindir/LIB/VERSION
164// 4.) bindir/../../Singular/LIB
165// 5.) bindir/../../Singular/LIB/VERSION
166// 6.) ROOT_DIR/Singular/LIB/
167// 7.) ROOT_DIR/Singular/LIB/VERSION
168// 8.) Go through all dirs and remove duplicates dirs resp.
169//     those which do not exist
170static char* feGetSearchPath(const char* bindir)
171{
172  char *env = NULL, *path, *opath;
173  int plength = 0, tmp;
174
175#ifdef MSDOS
176    env=getenv("SPATH");
177#else
178    env=getenv("SINGULARPATH");
179#endif
180#ifdef PATH_DEBUG
181    PrintS("I'm going to chatter about the Search path:\n");
182#endif
183    if (env != NULL)
184      plength = strlen(env);
185
186    if (bindir != NULL)
187      plength += 4*strlen(bindir);
188
189    plength += 2*strlen(SINGULAR_ROOT_DIR)
190      + 3*(strlen(S_VERSION1) + 1)
191      + 24         + 36          + 12       + 6          + 7;
192      // == 6*/LIB + 4*/Singular + 2*/../.. + for colons + some room to breath
193
194    opath = (char*) AllocL(plength*sizeof(char));
195    path = opath;
196
197    if (env != NULL)
198    {
199      strcpy(path, env);
200      path += strlen(path);
201      *path=FS_SEP;
202      path++;
203#ifdef PATH_DEBUG
204      *(path +1) = '\0';
205      Print("Got from env var: %s\n", opath);
206#endif
207    }
208
209    if (bindir != NULL)
210    {
211      sprintf(
212        path,
213        "%s/LIB%c%s/LIB/%s%c%s/../../Singular/LIB%c%s/../../Singular/LIB/%s%c",
214        bindir, FS_SEP,
215        bindir, S_VERSION1, FS_SEP,
216        bindir, FS_SEP,
217        bindir, S_VERSION1, FS_SEP);
218#ifdef PATH_DEBUG
219      Print("From bindir: %s\n", path);
220#endif
221      path += strlen(path);
222    }
223
224    sprintf(path, "%s/Singular/LIB%c%s/Singular/LIB/%s",
225            SINGULAR_ROOT_DIR, FS_SEP,
226            SINGULAR_ROOT_DIR, S_VERSION1);
227#ifdef PATH_DEBUG
228    Print("From rootdir: %s\n", path);
229#endif
230    return CleanUpPath(opath);
231}
232
233static void mystrcpy(char* d, char* s)
234{
235  assume(d != NULL && s != NULL);
236  while (*s != '\0')
237  {
238    *d = *s;
239    d++;
240    s++;
241  }
242  *d = '\0';
243}
244
245// Return location of file singular.hlp. Search for it as follows:
246// bindir/../doc/singular.hlp
247// bindir/../info/singular.hlp
248// bindir/../../Singular/doc/$version/singular.hlp
249// bindir/../../Singular/doc/singular.hlp
250// bindir/../../info/singular.hlp
251// ROOTDIR/Singular/doc/$version/singular.hlp
252// ROOTDIR/Singular/doc/singular.hlp
253// ROOTDIR/info/singular.hlp
254// Singular search path
255#ifdef WINNT
256static char * feFixFileName(char *hlpdir)
257{
258  if(strncmp(hlpdir,"//",2)==0)
259  {
260    hlpdir[0]=hlpdir[2];
261    hlpdir[1]=':';
262    mystrcpy(hlpdir+2,hlpdir+3);
263  }
264  return hlpdir;
265}
266#else
267#define  feFixFileName(A) (A)
268#endif
269
270static char* feGetInfoFile(const char* bindir)
271{
272  char* hlpfile = (char*) AllocL(max((bindir != NULL ? strlen(bindir) : 0),
273                                     strlen(SINGULAR_ROOT_DIR))
274                                  + 50);
275
276#ifdef PATH_DEBUG
277  PrintS("Search for singular.hlp\n");
278#endif
279
280  if (bindir != NULL)
281  {
282    // bindir/../doc/singular.hlp
283    sprintf(hlpfile,"%s/../doc/singular.hlp", bindir);
284#ifdef PATH_DEBUG
285    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
286#endif
287    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
288
289    // bindir/../info/singular.hlp
290    sprintf(hlpfile,"%s/../info/singular.hlp", bindir);
291#ifdef PATH_DEBUG
292    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
293#endif
294    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
295
296    // bindir/../../Singular/doc/$version/singular.hlp
297    sprintf(hlpfile,"%s/../../Singular/doc/%s/singular.hlp",bindir,S_VERSION1);
298#ifdef PATH_DEBUG
299    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
300#endif
301    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
302
303    // bindir/../../Singular/doc/singular.hlp
304    sprintf(hlpfile,"%s/../../Singular/doc/singular.hlp", bindir);
305#ifdef PATH_DEBUG
306    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
307#endif
308    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
309
310    // bindir/../../info/singular.hlp
311    sprintf(hlpfile,"%s/../../info/singular.hlp", bindir);
312#ifdef PATH_DEBUG
313    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
314#endif
315    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
316
317    // ROOTDIR/Singular/doc/$version/singular.hlp
318    sprintf(hlpfile,"%s/Singular/doc/%s/singular.hlp", SINGULAR_ROOT_DIR, S_VERSION1);
319#ifdef PATH_DEBUG
320    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
321#endif
322    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
323
324    // ROOTDIR/Singular/doc/singular.hlp
325    sprintf(hlpfile,"%s/Singular/doc/singular.hlp", SINGULAR_ROOT_DIR);
326#ifdef PATH_DEBUG
327    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
328#endif
329    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
330
331    // ROOTDIR/info/singular.hlp
332    sprintf(hlpfile,"%s/info/singular.hlp", SINGULAR_ROOT_DIR);
333 #ifdef PATH_DEBUG
334    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
335#endif
336   if (! access(CleanUpName(hlpfile) , R_OK)) return feFixFileName(hlpfile);
337  }
338
339  // still here? Try all dirs in the search path
340  FILE *file = feFopen("singular.hlp", "r", hlpfile, 0);
341  if (file != NULL)
342  {
343    fclose(file);
344    return feFixFileName(hlpfile);
345  }
346  *hlpfile = '\0';
347  return hlpfile;
348}
349
350#ifdef WINNT
351#define INFOPROG "info.exe"
352#else
353#define INFOPROG "info"
354#endif
355
356// we first look into bindir, if nothing found there, we use HAVE_INFO
357static char* feGetInfoProgram(const char* bindir)
358{
359  char infoprog[MAXPATHLEN];
360  if (bindir != NULL)
361  {
362    sprintf(infoprog, "%s/%s", bindir, INFOPROG);
363    if (! access(infoprog, X_OK)) return mstrdup(infoprog);
364  }
365
366  sprintf(infoprog, "%s/%s", SINGULAR_BIN_DIR, INFOPROG);
367  if (! access(infoprog, X_OK)) return mstrdup(infoprog);
368
369#ifdef HAVE_INFO
370  sprintf(infoprog, "%s", HAVE_INFO);
371  if (! access(infoprog, X_OK)) return mstrdup(infoprog);
372#endif
373  // nothing found, let's try "info"
374  sprintf(infoprog, "info");
375  return mstrdup(infoprog);
376}
377
378#if defined(WINNT) && defined(__GNUC__)
379// add utility function of Cygwin32:
380extern "C" int cygwin32_posix_path_list_p (const char *path);
381#endif
382
383#ifdef WINNT
384static void feExpandPath(char *dir)
385{
386  char *path=getenv("PATH");
387  char buf[MAXNAMLEN];
388  if (path==NULL)
389  {
390    strcpy(buf,dir);
391  }
392  else
393  {
394    #if defined(WINNT) && defined(__GNUC__)
395    char path_delim = cygwin32_posix_path_list_p (path) ? ':' : ';';
396    #else
397    char path_delim=FS_SEP;
398    #endif
399    sprintf(buf,"%s%c%s",path,path_delim,dir);
400  }
401  setenv("PATH",buf,1);
402}
403#endif
404
405//
406// public routines
407//
408void feInitPaths(const char* argv0)
409{
410  feArgv0 = mstrdup(argv0);
411  #ifdef WINNT
412  // add the bindir and the BIN_DIR to the current PATH:
413  feExpandPath(feGetBinDir()); // can only be called after setting feArgv0
414  feExpandPath(SINGULAR_BIN_DIR);
415  #endif
416}
417
418char* feGetExpandedExecutable()
419{
420  if (feExpandedExecutable == NULL)
421    feExpandedExecutable = feGetExpandedExecutable(feArgv0);
422  return feExpandedExecutable;
423}
424
425char* feGetBinDir()
426{
427  if (feBinDir == NULL)
428    feBinDir = feGetBinDir(feGetExpandedExecutable());
429  return feBinDir;
430}
431
432char* feGetSearchPath()
433{
434  if (feSearchPath == NULL)
435    feSearchPath = feGetSearchPath(feGetBinDir());
436  return feSearchPath;
437}
438
439char* feGetInfoProgram()
440{
441  if (feInfoProgram == NULL)
442    feInfoProgram = feGetInfoProgram(feGetBinDir());
443  return feInfoProgram;
444}
445
446char* feGetInfoFile()
447{
448  if (feInfoFile == NULL)
449    feInfoFile = feGetInfoFile(feGetBinDir());
450  return feInfoFile;
451}
452
453char* feGetInfoCall(const char* what)
454{
455  if (feInfoCall == NULL)
456    feInfoCall = (char*) AllocL(strlen(feGetInfoProgram())
457                                + strlen(feGetInfoFile())
458                                + 100);
459  char *infofile = feGetInfoFile();
460
461  if (what != NULL && strcmp(what, "index") != 0)
462    sprintf(feInfoCall,
463            "%s %s %s Index %s",
464            feGetInfoProgram(),
465            (*infofile != '\0' ? "-f" : ""),
466            (*infofile != '\0' ? infofile : "Singular"),
467            what);
468  else
469    sprintf(feInfoCall,
470            "%s %s %s",
471            feGetInfoProgram(),
472            (*infofile != '\0' ? "-f" : ""),
473            (*infofile != '\0' ? infofile : "Singular"));
474
475#ifdef PATH_DEBUG
476  Print("Info call with: %s \n", feInfoCall);
477#endif
478  return feInfoCall;
479}
480
481//
482// auxillary routines
483//
484static char* feRemovePathnameHead(const char* ef)
485{
486  if (ef != NULL)
487  {
488    char* ret = mstrdup(ef);
489    char* p = strrchr(ret, DIR_SEP);
490    if (p != NULL) *p = '\0';
491    return ret;
492  }
493  return NULL;
494}
495
496// remove duplicates dir resp. those which do not exist
497static char* CleanUpPath(char* path)
498{
499#ifdef PATH_DEBUG
500  Print("Entered CleanUpPath with: %s\n", path);
501#endif
502  if (path == NULL) return path;
503
504  int n_comps = 1, i, j;
505  char* opath = path;
506  char** path_comps;
507
508  for (; *path != '\0'; path++)
509  {
510    if (*path == FS_SEP) n_comps++;
511  }
512
513
514  path_comps = (char**) AllocL(n_comps*sizeof(char*));
515  path_comps[0]=opath;
516  path=opath;
517  i = 1;
518
519  if (i < n_comps)
520  {
521    while (1)
522    {
523      if (*path == FS_SEP)
524      {
525        *path = '\0';
526        path_comps[i] = path+1;
527        i++;
528        if (i == n_comps) break;
529      }
530      path++;
531    }
532  }
533
534  for (i=0; i<n_comps; i++)
535    path_comps[i] = CleanUpName(path_comps[i]);
536#ifdef PATH_DEBUG
537  PrintS("After CleanUpName: ");
538  for (i=0; i<n_comps; i++)
539    Print("%s:", path_comps[i]);
540  Print("\n");
541#endif
542
543  for (i=0; i<n_comps;)
544  {
545#ifdef PATH_DEBUG
546    if (access(path_comps[i], X_OK))
547      Print("remove %d:%s -- can not access\n", i, path_comps[i]);
548#endif
549    if ( ! access(path_comps[i], X_OK))
550    {
551      // x- permission is granted -- we assume that it is a dir
552      for (j=0; j<i; j++)
553      {
554        if (strcmp(path_comps[j], path_comps[i]) == 0)
555        {
556          // found a duplicate
557#ifdef PATH_DEBUG
558          Print("remove %d:%s -- equal to %d:%s\n", j, path_comps[j], i, path_comps[i]);
559#endif
560          j = i+1;
561          break;
562        }
563      }
564      if (j == i)
565      {
566        i++;
567        continue;
568      }
569    }
570    // now we can either not access or found a duplicate
571    path_comps[i] = NULL;
572    for (j=i+1; j<n_comps; j++)
573        path_comps[j-1] = path_comps[j];
574    n_comps--;
575  }
576
577  // assemble everything again
578  for (path=opath, i=0;i<n_comps-1;i++)
579  {
580    strcpy(path, path_comps[i]);
581    path += strlen(path);
582    *path = FS_SEP;
583    path++;
584  }
585  if (n_comps) strcpy(path, path_comps[i]);
586  FreeL(path_comps);
587#ifdef PATH_DEBUG
588  Print("SearchPath is: %s\n", opath);
589#endif
590  return opath;
591}
592
593static char* CleanUpName(char* fname)
594{
595  char* fn, *s;
596
597  for (fn = fname; *fn != '\0'; fn++)
598  {
599    if (*fn == '/')
600    {
601      if (*(fn+1) == '\0')
602      {
603        if (fname != fn) *fn = '\0';
604        break;
605      }
606      if (*(fn + 1) == '/' && (fname != fn))
607      {
608        mystrcpy(fn, fn+1);
609        fn--;
610      }
611      else if (*(fn+1) == '.')
612      {
613        if (*(fn+2) == '.' && (*(fn + 3) == '/' || *(fn + 3) == '\0'))
614        {
615          *fn = '\0';
616          s = strrchr(fname, '/');
617          if (s != NULL)
618          {
619            mystrcpy(s+1, fn + (*(fn + 3) != '\0' ? 4 : 3));
620            fn = s-1;
621          }
622          else
623          {
624            *fn = '/';
625          }
626        }
627        else if (*(fn+2) == '/' || *(fn+2) == '\0')
628        {
629          mystrcpy(fn+1, fn+3);
630          fn--;
631        }
632      }
633    }
634  }
635  return fname;
636}
637#endif
638/*****************************************************************
639 *
640 * File handling
641 *
642 *****************************************************************/
643
644FILE * feFopen(char *path, char *mode, char *where,int useWerror)
645{
646#ifdef __MWERKS__
647  FILE * f=myfopen(path,mode);
648  if (f!=NULL)
649  {
650    if (where!=NULL) strcpy(where,path);
651    return f;
652  }
653  char *res;
654  int idat=strlen(SINGULAR_DATADIR),
655      ilib=strlen(VERSION_DIR),
656      ipath=strlen(path);
657  int ialloc = idat+ilib+ipath+1;
658  char *env=getenv("SINGULARPATH");
659  int ienv=0, ii=0;
660  if (env!=NULL)
661  {
662    ienv=strlen(env);
663    ii=ienv;
664  }
665  if (ii<idat) ii = idat;
666  if (ii==0)
667  {
668    if (useWerror)
669      Werror("cannot open `%s`",path);
670    return f;
671  }
672  res=(char*) AllocL(ialloc);
673  if (ienv!=0)
674  {
675    memcpy(res,env,ienv);
676    memcpy(res+ienv,path,ipath);
677    res[ienv+ipath]='\0';
678    f=myfopen(res,mode);
679  }
680  if ((f==NULL)&&(idat!=0))
681  {
682    memcpy(res,SINGULAR_DATADIR,idat);
683    memcpy(res+idat,path,ipath);
684    res[idat+ipath]='\0';
685    f=myfopen(res,mode);
686  }
687  if ((f==NULL)&&(idat!=0))
688  {
689    memcpy(res,SINGULAR_DATADIR,idat);
690    memcpy(res+idat,VERSION_DIR,ilib);
691    idat += ilib;
692    memcpy(res+idat,path,ipath);
693    res[idat+ipath]='\0';
694    f=myfopen(res,mode);
695  }
696  if (f==NULL)
697  {
698    if (useWerror)
699      Werror("cannot open `%s`",res);
700  }
701  else if (where!=NULL)
702    strcpy(where,res);
703  FreeL(res);
704#else
705  BOOLEAN tilde = FALSE;
706  char longpath[MAXPATHLEN];
707  if (path[0]=='~')
708  {
709    char* home = getenv("HOME");
710    if (home != NULL)
711    {
712      strcpy(longpath, home);
713      strcat(longpath, &(path[1]));
714      path = longpath;
715    }
716  }
717  FILE * f=myfopen(path,mode);
718  if (where!=NULL) strcpy(where,path);
719  if ((*mode=='r') && (path[0]!=DIR_SEP)&&(path[0]!='.')
720  &&(f==NULL))
721  {
722    char found = 0;
723    char* spath = feGetSearchPath();
724    char *s;
725
726    if (where==NULL) s=(char *)AllocL(250);
727    else             s=where;
728
729    if (spath!=NULL)
730    {
731      char *p,*q;
732      p = spath;
733      while( (q=strchr(p, FS_SEP)) != NULL)
734      {
735        *q = '\0';
736        strcpy(s,p);
737        *q = FS_SEP;
738        strcat(s, DIR_SEPP);
739        strcat(s, path);
740        #ifndef macintosh
741          if(!access(s, R_OK)) { found++; break; }
742        #else
743          f=fopen(s,mode); /* do not need myfopen: we test only the access */
744          if (f!=NULL)  { found++; fclose(f); break; }
745        #endif
746        p = q+1;
747      }
748      if(!found)
749      {
750        strcpy(s,p);
751        strcat(s, DIR_SEPP);
752        strcat(s, path);
753      }
754      f=myfopen(s,mode);
755      if (f!=NULL)
756      {
757        if (where==NULL) FreeL((ADDRESS)s);
758        return f;
759      }
760    }
761    else
762    {
763      if (where!=NULL) strcpy(s/*where*/,path);
764      f=myfopen(path,mode);
765    }
766    if (where==NULL) FreeL((ADDRESS)s);
767  }
768  if ((f==NULL)&&(useWerror))
769    Werror("cannot open `%s`",path);
770#endif
771  return f;
772}
773
774static char * feBufferStart;
775  /* only used in StringSet(S)/StringAppend(S)*/
776char * StringAppend(char *fmt, ...)
777{
778  va_list ap;
779  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
780  int more;
781  va_start(ap, fmt);
782  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
783  {
784    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
785    int l=s-feBuffer;
786    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
787                                                     more);
788    feBufferLength=more;
789    s=feBuffer+l;
790#ifndef BSD_SPRINTF
791    feBufferStart=s;
792#endif
793  }
794#ifdef BSD_SPRINTF
795  vsprintf(s, fmt, ap);
796  while (*s!='\0') s++;
797  feBufferStart =s;
798#else
799  feBufferStart += vsprintf(s, fmt, ap);
800#endif
801  va_end(ap);
802  return feBuffer;
803}
804
805char * StringAppendS(char *st)
806{
807  /* feBufferStart is feBuffer + strlen(feBuffer);*/
808  int more,l;
809  int ll=feBufferStart-feBuffer;
810  if ((more=ll+2+(l=strlen(st)))>feBufferLength)
811  {
812    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
813    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
814                                                     more);
815    feBufferLength=more;
816    feBufferStart=feBuffer+ll;
817  }
818  strcat(feBufferStart, st);
819  feBufferStart +=l;
820  return feBuffer;
821}
822
823char * StringSet(char *fmt, ...)
824{
825  va_list ap;
826  char *s = feBuffer;
827  va_start(ap, fmt);
828#ifdef BSD_SPRINTF
829  vsprintf(s, fmt, ap);
830  while (*s!='\0') s++;
831  feBufferStart = s;
832#else
833  feBufferStart = feBuffer + vsprintf(s, fmt, ap);
834#endif
835  va_end(ap);
836  return feBuffer;
837}
838
839char * StringSetS(char *st)
840{
841  int more,l;
842  if ((l=strlen(st))>feBufferLength)
843  {
844    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
845    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
846                                                     more);
847    feBufferLength=more;
848  }
849  strcpy(feBuffer,st);
850  feBufferStart=feBuffer+l;
851  return feBuffer;
852}
853
854#ifndef __MWERKS__
855#ifdef HAVE_TCL
856extern "C" {
857void PrintTCLS(const char c, const char *s)
858{
859  int l=strlen(s);
860  if (l>0) PrintTCL(c,l,s);
861}
862}
863#endif
864#endif
865
866extern "C" {
867void WerrorS(const char *s)
868{
869#ifdef HAVE_MPSR
870  if (feBatch)
871  {
872    if (feErrors==NULL)
873    {
874      feErrors=(char *)Alloc(256);
875      feErrorsLen=256;
876      *feErrors = '\0';
877    }
878    else
879    {
880      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
881      {
882        feErrors=(char *)ReAlloc(feErrors,feErrorsLen,feErrorsLen+256);
883        feErrorsLen+=256;
884      }
885    }
886    strcat(feErrors, "Singular error: ");
887    strcat(feErrors, (char *)s);
888  }
889  else
890#endif
891  {
892#ifdef HAVE_TCL
893    if (tclmode)
894    {
895      PrintTCLS('E',(char *)s);
896      PrintTCLS('E',"\n");
897    }
898    else
899#endif
900    {
901      fwrite("   ? ",1,5,stderr);
902      fwrite((char *)s,1,strlen((char *)s),stderr);
903      fwrite("\n",1,1,stderr);
904      fflush(stderr);
905      if (feProt&PROT_O)
906      {
907        fwrite("   ? ",1,5,feProtFile);
908        fwrite((char *)s,1,strlen((char *)s),feProtFile);
909        fwrite("\n",1,1,feProtFile);
910      }
911    }
912  }
913  errorreported = TRUE;
914}
915
916void Werror(char *fmt, ...)
917{
918  va_list ap;
919  va_start(ap, fmt);
920  char *s=(char *)Alloc(256);
921  vsprintf(s, fmt, ap);
922  WerrorS(s);
923  Free(s,256);
924  va_end(ap);
925}
926}
927
928void WarnS(const char *s)
929{
930  #define warn_str "// ** "
931#ifdef HAVE_TCL
932  if (tclmode)
933  {
934    PrintTCLS('W',warn_str);
935    PrintTCLS('W',s);
936    PrintTCLS('W',"\n");
937  }
938  else
939#endif
940  if (feWarn) /* ignore warnings in when optin --no-warn was given */
941  {
942    fwrite(warn_str,1,6,stdout);
943    fwrite(s,1,strlen(s),stdout);
944    fwrite("\n",1,1,stdout);
945    fflush(stdout);
946    if (feProt&PROT_O)
947    {
948      fwrite(warn_str,1,6,feProtFile);
949      fwrite(s,1,strlen(s),feProtFile);
950      fwrite("\n",1,1,feProtFile);
951    }
952  }
953}
954
955void Warn(const char *fmt, ...)
956{
957  va_list ap;
958  va_start(ap, fmt);
959  char *s=(char *)Alloc(256);
960  vsprintf(s, fmt, ap);
961  WarnS(s);
962  Free(s,256);
963  va_end(ap);
964}
965
966extern "C" {
967void assume_violation(char* file, int line)
968{
969  fprintf(stderr, "Internal assume violation: file %s line %d\n", file, line);
970}
971}
972
973#ifdef macintosh
974static  int lines = 0;
975static  int cols = 0;
976
977void mwrite(uchar c)
978{
979  if (c == '\n')
980  {
981    cols = 0;
982    if (lines == pagelength)
983    {
984      lines = 0;
985      fePause();
986    }
987    else
988    {
989      lines++;
990      fePutChar(c);
991    }
992  }
993  else
994  {
995    fePutChar(c);
996    cols++;
997    if (cols == colmax)
998    {
999      // cols = 0;   //will be done by mwrite('\n');
1000      mwrite('\n');
1001    }
1002  }
1003}
1004#endif
1005
1006extern "C" {
1007void PrintS(char *s)
1008{
1009  if (feOut) /* do not print when option --no-out was given */
1010  {
1011   
1012#ifdef macintosh
1013    char c;
1014    while ('\0' != (c = *s++))
1015    {
1016      mwrite(c);
1017    }
1018#else
1019#ifdef HAVE_TCL
1020    if (tclmode)
1021    {
1022      PrintTCLS('N',s);
1023    }
1024    else
1025#endif
1026    {
1027      fwrite(s,1,strlen(s),stdout);
1028      fflush(stdout);
1029      if (feProt&PROT_O)
1030      {
1031        fwrite(s,1,strlen(s),feProtFile);
1032      }
1033    }
1034#endif
1035  }
1036}
1037
1038void PrintLn()
1039{
1040  PrintS("\n");
1041}
1042
1043void Print(char *fmt, ...)
1044{
1045  if (feOut)
1046  {
1047    va_list ap;
1048    va_start(ap, fmt);
1049#ifdef HAVE_TCL
1050    if(tclmode)
1051#endif
1052#if (defined(HAVE_TCL) || defined(macintosh))
1053    {
1054      char *s=(char *)Alloc(strlen(fmt)+256);
1055      vsprintf(s,fmt, ap);
1056#ifdef HAVE_TCL
1057      PrintTCLS('N',s);
1058#endif
1059#ifdef macintosh
1060      char c;
1061      while ('\0' != (c = *s++))
1062      {
1063        mwrite(c);
1064      }
1065      if (feProt&PROT_O)
1066      {
1067        vfprintf(feProtFile,fmt,ap);
1068      }
1069#endif
1070    }
1071#endif
1072#if !defined(macintosh) || defined(HAVE_TCL)
1073#ifdef HAVE_TCL
1074    else
1075#endif
1076    {
1077      vfprintf(stdout, fmt, ap);
1078      fflush(stdout);
1079      if (feProt&PROT_O)
1080      {
1081        vfprintf(feProtFile,fmt,ap);
1082      }
1083    }
1084#endif
1085    va_end(ap);
1086  }
1087}
1088
1089/* end extern "C" */
1090}
1091
1092void fePause()
1093{
1094#ifdef HAVE_TCL
1095  if(!tclmode)
1096#endif
1097  {
1098    mflush();
1099#ifndef macintosh
1100    fputs("pause>",stderr);
1101#else
1102    fputs("pause>\n",stderr);
1103#endif
1104    uchar c = fgetc(stdin);
1105    if (((c == '\003') || (c == 'C')) || (c == 'c'))
1106    {
1107      m2_end(4);
1108    }
1109  }
1110}
1111
1112void monitor(char* s, int mode)
1113{
1114  if (feProt)
1115  {
1116    fclose(feProtFile);
1117  }
1118  if ((s!=NULL) && (*s!='\0'))
1119  {
1120    feProtFile = myfopen(s,"w");
1121    if (feProtFile==NULL)
1122    {
1123      Werror("cannot open %s",s);
1124    }
1125    else
1126      feProt = (BOOLEAN)mode;
1127  }
1128}
1129
1130
1131char* eati(char *s, int *i)
1132{
1133  int l=0;
1134
1135  if    (*s >= '0' && *s <= '9')
1136  {
1137    *i = 0;
1138    while (*s >= '0' && *s <= '9')
1139    {
1140      *i *= 10;
1141      *i += *s++ - '0';
1142      l++;
1143      if ((l>MAX_INT_LEN)||((*i) <0))
1144      {
1145        s-=l;
1146        Werror("`%s` greater than %d(max. integer representation)",
1147                s,INT_MAX);
1148        return s;
1149      }
1150    }
1151  }
1152  else *i = 1;
1153  return s;
1154}
1155
1156#ifndef unix
1157// Make sure that mode contains binary option
1158FILE *myfopen(char *path, char *mode)
1159{
1160  char mmode[4];
1161  int i;
1162  BOOLEAN done = FALSE;
1163
1164  for (i=0;;i++)
1165  {
1166    mmode[i] = mode[i];
1167    if (mode[i] == '\0') break;
1168    if (mode[i] == 'b') done = TRUE;
1169  }
1170
1171  if (! done)
1172  {
1173    mmode[i] = 'b';
1174    mmode[i+1] = '\0';
1175  }
1176  return fopen(path, mmode);
1177}
1178#endif
1179
1180// replace "\r\n" by " \n" and "\r" by "\n"
1181
1182size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
1183{
1184  size_t got = fread(ptr, size, nmemb, stream) * size;
1185  size_t i;
1186
1187  for (i=0; i<got; i++)
1188  {
1189    if ( ((char*) ptr)[i] == '\r')
1190    {
1191      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
1192        ((char*) ptr)[i] = ' ';
1193      else
1194        ((char*) ptr)[i] = '\n';
1195    }
1196  }
1197  return got;
1198}
Note: See TracBrowser for help on using the repository browser.