source: git/Singular/febase.cc @ 917fb5

spielwiese
Last change on this file since 917fb5 was 917fb5, checked in by Hans Schönemann <hannes@…>, 25 years ago
* hannes: removed pause; (scanner.l, febase.*) introduced pause([string]) (standard.lib) git-svn-id: file:///usr/local/Singular/svn/trunk@3237 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 26.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.cc,v 1.74 1999-07-06 15:32:43 Singular 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/doc/singular.hlp
254// ROOTDIR/info/singular.hlp
255// Singular search path
256#ifdef WINNT
257static char * feFixFileName(char *hlpdir)
258{
259  if(strncmp(hlpdir,"//",2)==0)
260  {
261    hlpdir[0]=hlpdir[2];
262    hlpdir[1]=':';
263    mystrcpy(hlpdir+2,hlpdir+3);
264  }
265  return hlpdir;
266}
267#else
268#define  feFixFileName(A) (A)
269#endif
270
271static char* feGetInfoFile(const char* bindir)
272{
273  char* hlpfile = (char*) AllocL(max((bindir != NULL ? strlen(bindir) : 0),
274                                     strlen(SINGULAR_ROOT_DIR))
275                                  + 50);
276
277#ifdef PATH_DEBUG
278  PrintS("Search for singular.hlp\n");
279#endif
280
281  if (bindir != NULL)
282  {
283    // bindir/../doc/singular.hlp
284    sprintf(hlpfile,"%s/../doc/singular.hlp", bindir);
285#ifdef PATH_DEBUG
286    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
287#endif
288    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
289
290    // bindir/../info/singular.hlp
291    sprintf(hlpfile,"%s/../info/singular.hlp", bindir);
292#ifdef PATH_DEBUG
293    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
294#endif
295    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
296
297    // bindir/../../Singular/doc/$version/singular.hlp
298    sprintf(hlpfile,"%s/../../Singular/doc/%s/singular.hlp",bindir,S_VERSION1);
299#ifdef PATH_DEBUG
300    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
301#endif
302    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
303
304    // bindir/../../Singular/doc/singular.hlp
305    sprintf(hlpfile,"%s/../../Singular/doc/singular.hlp", bindir);
306#ifdef PATH_DEBUG
307    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
308#endif
309    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
310
311    // bindir/../../info/singular.hlp
312    sprintf(hlpfile,"%s/../../info/singular.hlp", bindir);
313#ifdef PATH_DEBUG
314    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
315#endif
316    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
317
318    // ROOTDIR/Singular/doc/$version/singular.hlp
319    sprintf(hlpfile,"%s/Singular/doc/%s/singular.hlp", SINGULAR_ROOT_DIR, S_VERSION1);
320#ifdef PATH_DEBUG
321    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
322#endif
323    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
324
325    // ROOTDIR/Singular/doc/singular.hlp
326    sprintf(hlpfile,"%s/Singular/doc/singular.hlp", SINGULAR_ROOT_DIR);
327#ifdef PATH_DEBUG
328    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
329#endif
330    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
331
332    // ROOTDIR/doc/singular.hlp
333    sprintf(hlpfile,"%s/doc/singular.hlp", SINGULAR_ROOT_DIR);
334 #ifdef PATH_DEBUG
335    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
336#endif
337   if (! access(CleanUpName(hlpfile) , R_OK)) return feFixFileName(hlpfile);
338
339    // ROOTDIR/info/singular.hlp
340    sprintf(hlpfile,"%s/info/singular.hlp", SINGULAR_ROOT_DIR);
341 #ifdef PATH_DEBUG
342    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
343#endif
344   if (! access(CleanUpName(hlpfile) , R_OK)) return feFixFileName(hlpfile);
345  }
346
347  // still here? Try all dirs in the search path
348  FILE *file = feFopen("singular.hlp", "r", hlpfile, 0);
349  if (file != NULL)
350  {
351    fclose(file);
352    return feFixFileName(hlpfile);
353  }
354  *hlpfile = '\0';
355  return hlpfile;
356}
357
358#ifdef WINNT
359#define INFOPROG "info.exe"
360#else
361#define INFOPROG "info"
362#endif
363
364// we first look into bindir, if nothing found there, we use HAVE_INFO
365static char* feGetInfoProgram(const char* bindir)
366{
367  char infoprog[MAXPATHLEN];
368  if (bindir != NULL)
369  {
370    sprintf(infoprog, "%s/%s", bindir, INFOPROG);
371    if (! access(infoprog, X_OK)) return mstrdup(infoprog);
372  }
373
374  sprintf(infoprog, "%s/%s", SINGULAR_BIN_DIR, INFOPROG);
375  if (! access(infoprog, X_OK)) return mstrdup(infoprog);
376
377#ifdef HAVE_INFO
378  sprintf(infoprog, "%s", HAVE_INFO);
379  if (! access(infoprog, X_OK)) return mstrdup(infoprog);
380#endif
381  // nothing found, let's try "info"
382  sprintf(infoprog, "info");
383  return mstrdup(infoprog);
384}
385
386#if defined(WINNT) && defined(__GNUC__)
387// add utility function of Cygwin32:
388extern "C" int cygwin32_posix_path_list_p (const char *path);
389#endif
390
391#ifdef WINNT
392static void feExpandPath(char *dir)
393{
394  char *path=getenv("PATH");
395  char buf[MAXNAMLEN];
396  if (path==NULL)
397  {
398    strcpy(buf,dir);
399  }
400  else
401  {
402    #if defined(WINNT) && defined(__GNUC__)
403    char path_delim = cygwin32_posix_path_list_p (path) ? ':' : ';';
404    #else
405    char path_delim=FS_SEP;
406    #endif
407    sprintf(buf,"%s%c%s",path,path_delim,dir);
408  }
409  setenv("PATH",buf,1);
410}
411#endif
412
413//
414// public routines
415//
416void feInitPaths(const char* argv0)
417{
418  feArgv0 = mstrdup(argv0);
419  #ifdef WINNT
420  // add the bindir and the BIN_DIR to the current PATH:
421  feExpandPath(feGetBinDir()); // can only be called after setting feArgv0
422  feExpandPath(SINGULAR_BIN_DIR);
423  #endif
424}
425
426char* feGetExpandedExecutable()
427{
428  if (feExpandedExecutable == NULL)
429    feExpandedExecutable = feGetExpandedExecutable(feArgv0);
430  return feExpandedExecutable;
431}
432
433char* feGetBinDir()
434{
435  if (feBinDir == NULL)
436    feBinDir = feGetBinDir(feGetExpandedExecutable());
437  return feBinDir;
438}
439
440char* feGetSearchPath()
441{
442  if (feSearchPath == NULL)
443    feSearchPath = feGetSearchPath(feGetBinDir());
444  return feSearchPath;
445}
446
447char* feGetInfoProgram()
448{
449  if (feInfoProgram == NULL)
450    feInfoProgram = feGetInfoProgram(feGetBinDir());
451  return feInfoProgram;
452}
453
454char* feGetInfoFile()
455{
456  if (feInfoFile == NULL)
457    feInfoFile = feGetInfoFile(feGetBinDir());
458  return feInfoFile;
459}
460
461char* feGetInfoCall(const char* what)
462{
463  if (feInfoCall == NULL)
464    feInfoCall = (char*) AllocL(strlen(feGetInfoProgram())
465                                + strlen(feGetInfoFile())
466                                + 100);
467  char *infofile = feGetInfoFile();
468
469  if (what != NULL && strcmp(what, "index") != 0)
470    sprintf(feInfoCall,
471            "%s %s %s Index %s",
472            feGetInfoProgram(),
473            (*infofile != '\0' ? "-f" : ""),
474            (*infofile != '\0' ? infofile : "Singular"),
475            what);
476  else
477    sprintf(feInfoCall,
478            "%s %s %s",
479            feGetInfoProgram(),
480            (*infofile != '\0' ? "-f" : ""),
481            (*infofile != '\0' ? infofile : "Singular"));
482
483#ifdef PATH_DEBUG
484  Print("Info call with: %s \n", feInfoCall);
485#endif
486  return feInfoCall;
487}
488
489//
490// auxillary routines
491//
492static char* feRemovePathnameHead(const char* ef)
493{
494  if (ef != NULL)
495  {
496    char* ret = mstrdup(ef);
497    char* p = strrchr(ret, DIR_SEP);
498    if (p != NULL) *p = '\0';
499    return ret;
500  }
501  return NULL;
502}
503
504// remove duplicates dir resp. those which do not exist
505static char* CleanUpPath(char* path)
506{
507#ifdef PATH_DEBUG
508  Print("Entered CleanUpPath with: %s\n", path);
509#endif
510  if (path == NULL) return path;
511
512  int n_comps = 1, i, j;
513  char* opath = path;
514  char** path_comps;
515
516  for (; *path != '\0'; path++)
517  {
518    if (*path == FS_SEP) n_comps++;
519  }
520
521
522  path_comps = (char**) AllocL(n_comps*sizeof(char*));
523  path_comps[0]=opath;
524  path=opath;
525  i = 1;
526
527  if (i < n_comps)
528  {
529    while (1)
530    {
531      if (*path == FS_SEP)
532      {
533        *path = '\0';
534        path_comps[i] = path+1;
535        i++;
536        if (i == n_comps) break;
537      }
538      path++;
539    }
540  }
541
542  for (i=0; i<n_comps; i++)
543    path_comps[i] = CleanUpName(path_comps[i]);
544#ifdef PATH_DEBUG
545  PrintS("After CleanUpName: ");
546  for (i=0; i<n_comps; i++)
547    Print("%s:", path_comps[i]);
548  Print("\n");
549#endif
550
551  for (i=0; i<n_comps;)
552  {
553#ifdef PATH_DEBUG
554    if (access(path_comps[i], X_OK))
555      Print("remove %d:%s -- can not access\n", i, path_comps[i]);
556#endif
557    if ( ! access(path_comps[i], X_OK))
558    {
559      // x- permission is granted -- we assume that it is a dir
560      for (j=0; j<i; j++)
561      {
562        if (strcmp(path_comps[j], path_comps[i]) == 0)
563        {
564          // found a duplicate
565#ifdef PATH_DEBUG
566          Print("remove %d:%s -- equal to %d:%s\n", j, path_comps[j], i, path_comps[i]);
567#endif
568          j = i+1;
569          break;
570        }
571      }
572      if (j == i)
573      {
574        i++;
575        continue;
576      }
577    }
578    // now we can either not access or found a duplicate
579    path_comps[i] = NULL;
580    for (j=i+1; j<n_comps; j++)
581        path_comps[j-1] = path_comps[j];
582    n_comps--;
583  }
584
585  // assemble everything again
586  for (path=opath, i=0;i<n_comps-1;i++)
587  {
588    strcpy(path, path_comps[i]);
589    path += strlen(path);
590    *path = FS_SEP;
591    path++;
592  }
593  if (n_comps) strcpy(path, path_comps[i]);
594  FreeL(path_comps);
595#ifdef PATH_DEBUG
596  Print("SearchPath is: %s\n", opath);
597#endif
598  return opath;
599}
600
601static char* CleanUpName(char* fname)
602{
603  char* fn, *s;
604
605  for (fn = fname; *fn != '\0'; fn++)
606  {
607    if (*fn == '/')
608    {
609      if (*(fn+1) == '\0')
610      {
611        if (fname != fn) *fn = '\0';
612        break;
613      }
614      if (*(fn + 1) == '/' && (fname != fn))
615      {
616        mystrcpy(fn, fn+1);
617        fn--;
618      }
619      else if (*(fn+1) == '.')
620      {
621        if (*(fn+2) == '.' && (*(fn + 3) == '/' || *(fn + 3) == '\0'))
622        {
623          *fn = '\0';
624          s = strrchr(fname, '/');
625          if (s != NULL)
626          {
627            mystrcpy(s+1, fn + (*(fn + 3) != '\0' ? 4 : 3));
628            fn = s-1;
629          }
630          else
631          {
632            *fn = '/';
633          }
634        }
635        else if (*(fn+2) == '/' || *(fn+2) == '\0')
636        {
637          mystrcpy(fn+1, fn+3);
638          fn--;
639        }
640      }
641    }
642  }
643  return fname;
644}
645#endif
646/*****************************************************************
647 *
648 * File handling
649 *
650 *****************************************************************/
651
652FILE * feFopen(char *path, char *mode, char *where,int useWerror)
653{
654#ifdef __MWERKS__
655  FILE * f=myfopen(path,mode);
656  if (f!=NULL)
657  {
658    if (where!=NULL) strcpy(where,path);
659    return f;
660  }
661  char *res;
662  int idat=strlen(SINGULAR_DATADIR),
663      ilib=strlen(VERSION_DIR),
664      ipath=strlen(path);
665  int ialloc = idat+ilib+ipath+1;
666  char *env=getenv("SINGULARPATH");
667  int ienv=0, ii=0;
668  if (env!=NULL)
669  {
670    ienv=strlen(env);
671    ii=ienv;
672  }
673  if (ii<idat) ii = idat;
674  if (ii==0)
675  {
676    if (useWerror)
677      Werror("cannot open `%s`",path);
678    return f;
679  }
680  res=(char*) AllocL(ialloc);
681  if (ienv!=0)
682  {
683    memcpy(res,env,ienv);
684    memcpy(res+ienv,path,ipath);
685    res[ienv+ipath]='\0';
686    f=myfopen(res,mode);
687  }
688  if ((f==NULL)&&(idat!=0))
689  {
690    memcpy(res,SINGULAR_DATADIR,idat);
691    memcpy(res+idat,path,ipath);
692    res[idat+ipath]='\0';
693    f=myfopen(res,mode);
694  }
695  if ((f==NULL)&&(idat!=0))
696  {
697    memcpy(res,SINGULAR_DATADIR,idat);
698    memcpy(res+idat,VERSION_DIR,ilib);
699    idat += ilib;
700    memcpy(res+idat,path,ipath);
701    res[idat+ipath]='\0';
702    f=myfopen(res,mode);
703  }
704  if (f==NULL)
705  {
706    if (useWerror)
707      Werror("cannot open `%s`",res);
708  }
709  else if (where!=NULL)
710    strcpy(where,res);
711  FreeL(res);
712#else
713  BOOLEAN tilde = FALSE;
714  char longpath[MAXPATHLEN];
715  if (path[0]=='~')
716  {
717    char* home = getenv("HOME");
718    if (home != NULL)
719    {
720      strcpy(longpath, home);
721      strcat(longpath, &(path[1]));
722      path = longpath;
723    }
724  }
725  FILE * f=myfopen(path,mode);
726  if (where!=NULL) strcpy(where,path);
727  if ((*mode=='r') && (path[0]!=DIR_SEP)&&(path[0]!='.')
728  &&(f==NULL))
729  {
730    char found = 0;
731    char* spath = feGetSearchPath();
732    char *s;
733
734    if (where==NULL) s=(char *)AllocL(250);
735    else             s=where;
736
737    if (spath!=NULL)
738    {
739      char *p,*q;
740      p = spath;
741      while( (q=strchr(p, FS_SEP)) != NULL)
742      {
743        *q = '\0';
744        strcpy(s,p);
745        *q = FS_SEP;
746        strcat(s, DIR_SEPP);
747        strcat(s, path);
748        #ifndef macintosh
749          if(!access(s, R_OK)) { found++; break; }
750        #else
751          f=fopen(s,mode); /* do not need myfopen: we test only the access */
752          if (f!=NULL)  { found++; fclose(f); break; }
753        #endif
754        p = q+1;
755      }
756      if(!found)
757      {
758        strcpy(s,p);
759        strcat(s, DIR_SEPP);
760        strcat(s, path);
761      }
762      f=myfopen(s,mode);
763      if (f!=NULL)
764      {
765        if (where==NULL) FreeL((ADDRESS)s);
766        return f;
767      }
768    }
769    else
770    {
771      if (where!=NULL) strcpy(s/*where*/,path);
772      f=myfopen(path,mode);
773    }
774    if (where==NULL) FreeL((ADDRESS)s);
775  }
776  if ((f==NULL)&&(useWerror))
777    Werror("cannot open `%s`",path);
778#endif
779  return f;
780}
781
782static char * feBufferStart;
783  /* only used in StringSet(S)/StringAppend(S)*/
784char * StringAppend(char *fmt, ...)
785{
786  va_list ap;
787  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
788  int more, vs;
789  va_start(ap, fmt);
790  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
791  {
792    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
793    int l=s-feBuffer;
794    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
795                                                     more);
796    feBufferLength=more;
797    s=feBuffer+l;
798#ifndef BSD_SPRINTF
799    feBufferStart=s;
800#endif
801  }
802#ifdef BSD_SPRINTF
803  vsprintf(s, fmt, ap);
804  while (*s!='\0') s++;
805  feBufferStart =s;
806#else
807#ifdef HAVE_VSNPRINTF
808  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
809  if (vs == -1)
810  {
811    assume(0);
812    feBufferStart = feBuffer + feBufferLength -1;
813  }
814  else
815  {
816    feBufferStart += vs;
817  }
818#else
819  feBufferStart += vsprintf(s, fmt, ap);
820#endif
821#endif
822  mmTest(feBuffer, feBufferLength);
823  va_end(ap);
824  return feBuffer;
825}
826
827char * StringAppendS(char *st)
828{
829  /* feBufferStart is feBuffer + strlen(feBuffer);*/
830  int more,l;
831  int ll=feBufferStart-feBuffer;
832  if ((more=ll+2+(l=strlen(st)))>feBufferLength)
833  {
834    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
835    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
836                                                     more);
837    feBufferLength=more;
838    feBufferStart=feBuffer+ll;
839  }
840  strcat(feBufferStart, st);
841  feBufferStart +=l;
842  return feBuffer;
843}
844
845char * StringSetS(char *st)
846{
847  int more,l;
848  if ((l=strlen(st))>feBufferLength)
849  {
850    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
851    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
852                                                     more);
853    feBufferLength=more;
854  }
855  strcpy(feBuffer,st);
856  feBufferStart=feBuffer+l;
857  return feBuffer;
858}
859
860#ifndef __MWERKS__
861#ifdef HAVE_TCL
862extern "C" {
863void PrintTCLS(const char c, const char *s)
864{
865  int l=strlen(s);
866  if (l>0) PrintTCL(c,l,s);
867}
868}
869#endif
870#endif
871
872extern "C" {
873void WerrorS(const char *s)
874{
875#ifdef HAVE_MPSR
876  if (feBatch)
877  {
878    if (feErrors==NULL)
879    {
880      feErrors=(char *)Alloc(256);
881      feErrorsLen=256;
882      *feErrors = '\0';
883    }
884    else
885    {
886      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
887      {
888        feErrors=(char *)ReAlloc(feErrors,feErrorsLen,feErrorsLen+256);
889        feErrorsLen+=256;
890      }
891    }
892    strcat(feErrors, "Singular error: ");
893    strcat(feErrors, (char *)s);
894  }
895  else
896#endif
897  {
898#ifdef HAVE_TCL
899    if (tclmode)
900    {
901      PrintTCLS('E',(char *)s);
902      PrintTCLS('E',"\n");
903    }
904    else
905#endif
906    {
907      fwrite("   ? ",1,5,stderr);
908      fwrite((char *)s,1,strlen((char *)s),stderr);
909      fwrite("\n",1,1,stderr);
910      fflush(stderr);
911      if (feProt&PROT_O)
912      {
913        fwrite("   ? ",1,5,feProtFile);
914        fwrite((char *)s,1,strlen((char *)s),feProtFile);
915        fwrite("\n",1,1,feProtFile);
916      }
917    }
918  }
919  errorreported = TRUE;
920}
921
922void Werror(char *fmt, ...)
923{
924  va_list ap;
925  va_start(ap, fmt);
926  char *s=(char *)Alloc(256);
927  vsprintf(s, fmt, ap);
928  WerrorS(s);
929  Free(s,256);
930  va_end(ap);
931}
932}
933
934void WarnS(const char *s)
935{
936  #define warn_str "// ** "
937#ifdef HAVE_TCL
938  if (tclmode)
939  {
940    PrintTCLS('W',warn_str);
941    PrintTCLS('W',s);
942    PrintTCLS('W',"\n");
943  }
944  else
945#endif
946  if (feWarn) /* ignore warnings in when optin --no-warn was given */
947  {
948    fwrite(warn_str,1,6,stdout);
949    fwrite(s,1,strlen(s),stdout);
950    fwrite("\n",1,1,stdout);
951    fflush(stdout);
952    if (feProt&PROT_O)
953    {
954      fwrite(warn_str,1,6,feProtFile);
955      fwrite(s,1,strlen(s),feProtFile);
956      fwrite("\n",1,1,feProtFile);
957    }
958  }
959}
960
961void Warn(const char *fmt, ...)
962{
963  va_list ap;
964  va_start(ap, fmt);
965  char *s=(char *)Alloc(256);
966  vsprintf(s, fmt, ap);
967  WarnS(s);
968  Free(s,256);
969  va_end(ap);
970}
971
972extern "C" {
973void assume_violation(char* file, int line)
974{
975  fprintf(stderr, "Internal assume violation: file %s line %d\n", file, line);
976}
977}
978
979#ifdef macintosh
980static  int lines = 0;
981static  int cols = 0;
982
983void mwrite(uchar c)
984{
985  if (c == '\n')
986  {
987    cols = 0;
988    if (lines == pagelength)
989    {
990      lines = 0;
991      fputs("pause>\n",stderr);
992      uchar c = fgetc(stdin);
993    }
994    else
995    {
996      lines++;
997      fePutChar(c);
998    }
999  }
1000  else
1001  {
1002    fePutChar(c);
1003    cols++;
1004    if (cols == colmax)
1005    {
1006      // cols = 0;   //will be done by mwrite('\n');
1007      mwrite('\n');
1008    }
1009  }
1010}
1011#endif
1012
1013// some routines which redirect the output of print to a string
1014static char* sprint = NULL;
1015void SPrintStart()
1016{
1017  sprint = mstrdup("");
1018}
1019
1020static void SPrintS(char* s)
1021{
1022  mmTestL(sprint);
1023  if (s == NULL) return;
1024  int ls = strlen(s);
1025  if (ls == 0) return;
1026
1027  char* ns;
1028  int l = strlen(sprint);
1029  ns = (char*) AllocL((l + ls + 1)*sizeof(char));
1030  if (l > 0) strcpy(ns, sprint);
1031
1032  strcpy(&(ns[l]), s);
1033  FreeL(sprint);
1034  sprint = ns;
1035  mmTestL(sprint);
1036}
1037
1038char* SPrintEnd()
1039{
1040  char* ns = sprint;
1041  sprint = NULL;
1042  mmTestL(ns);
1043  return ns;
1044}
1045
1046// Print routines
1047extern "C" {
1048void PrintS(char *s)
1049{
1050  if (sprint != NULL)
1051  {
1052    SPrintS(s);
1053    return;
1054  }
1055
1056  if (feOut) /* do not print when option --no-out was given */
1057  {
1058
1059#ifdef macintosh
1060    char c;
1061    while ('\0' != (c = *s++))
1062    {
1063      mwrite(c);
1064    }
1065#else
1066#ifdef HAVE_TCL
1067    if (tclmode)
1068    {
1069      PrintTCLS('N',s);
1070    }
1071    else
1072#endif
1073    {
1074      fwrite(s,1,strlen(s),stdout);
1075      fflush(stdout);
1076      if (feProt&PROT_O)
1077      {
1078        fwrite(s,1,strlen(s),feProtFile);
1079      }
1080    }
1081#endif
1082  }
1083}
1084
1085void PrintLn()
1086{
1087  PrintS("\n");
1088}
1089
1090void Print(char *fmt, ...)
1091{
1092  if (sprint != NULL)
1093  {
1094    int ls = strlen(fmt);
1095    va_list ap;
1096    va_start(ap, fmt);
1097    mmTestL(sprint);
1098    if (fmt != NULL && ls > 0)
1099    {
1100      char* ns;
1101      int l = strlen(sprint);
1102      ns = (char*) AllocL(sizeof(char)*(ls + l + 256));
1103      if (l > 0)  strcpy(ns, sprint);
1104
1105#ifdef HAVE_VSNPRINTF
1106      l = vsnprintf(&(ns[l]), ls+255, fmt, ap);
1107      assume(l != -1);
1108#else
1109      vsprintf(&(ns[l]), fmt, ap);
1110#endif
1111      mmTestL(ns);
1112      FreeL(sprint);
1113      sprint = ns;
1114    }
1115    va_end(ap);
1116    return;
1117  }
1118  if (feOut)
1119  {
1120    va_list ap;
1121    va_start(ap, fmt);
1122#ifdef HAVE_TCL
1123    if(tclmode)
1124#endif
1125#if (defined(HAVE_TCL) || defined(macintosh))
1126    {
1127      char *s=(char *)Alloc(strlen(fmt)+256);
1128      vsprintf(s,fmt, ap);
1129#ifdef HAVE_TCL
1130      PrintTCLS('N',s);
1131#endif
1132#ifdef macintosh
1133      char c;
1134      while ('\0' != (c = *s++))
1135      {
1136        mwrite(c);
1137      }
1138      if (feProt&PROT_O)
1139      {
1140        vfprintf(feProtFile,fmt,ap);
1141      }
1142#endif
1143    }
1144#endif
1145#if !defined(macintosh) || defined(HAVE_TCL)
1146#ifdef HAVE_TCL
1147    else
1148#endif
1149    {
1150      vfprintf(stdout, fmt, ap);
1151      fflush(stdout);
1152      if (feProt&PROT_O)
1153      {
1154        vfprintf(feProtFile,fmt,ap);
1155      }
1156    }
1157#endif
1158    va_end(ap);
1159  }
1160}
1161
1162/* end extern "C" */
1163}
1164
1165void monitor(char* s, int mode)
1166{
1167  if (feProt)
1168  {
1169    fclose(feProtFile);
1170  }
1171  if ((s!=NULL) && (*s!='\0'))
1172  {
1173    feProtFile = myfopen(s,"w");
1174    if (feProtFile==NULL)
1175    {
1176      Werror("cannot open %s",s);
1177    }
1178    else
1179      feProt = (BOOLEAN)mode;
1180  }
1181}
1182
1183
1184char* eati(char *s, int *i)
1185{
1186  int l=0;
1187
1188  if    (*s >= '0' && *s <= '9')
1189  {
1190    *i = 0;
1191    while (*s >= '0' && *s <= '9')
1192    {
1193      *i *= 10;
1194      *i += *s++ - '0';
1195      l++;
1196      if ((l>MAX_INT_LEN)||((*i) <0))
1197      {
1198        s-=l;
1199        Werror("`%s` greater than %d(max. integer representation)",
1200                s,INT_MAX);
1201        return s;
1202      }
1203    }
1204  }
1205  else *i = 1;
1206  return s;
1207}
1208
1209#ifndef unix
1210// Make sure that mode contains binary option
1211FILE *myfopen(char *path, char *mode)
1212{
1213  char mmode[4];
1214  int i;
1215  BOOLEAN done = FALSE;
1216
1217  for (i=0;;i++)
1218  {
1219    mmode[i] = mode[i];
1220    if (mode[i] == '\0') break;
1221    if (mode[i] == 'b') done = TRUE;
1222  }
1223
1224  if (! done)
1225  {
1226    mmode[i] = 'b';
1227    mmode[i+1] = '\0';
1228  }
1229  return fopen(path, mmode);
1230}
1231#endif
1232
1233// replace "\r\n" by " \n" and "\r" by "\n"
1234
1235size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
1236{
1237  size_t got = fread(ptr, size, nmemb, stream) * size;
1238  size_t i;
1239
1240  for (i=0; i<got; i++)
1241  {
1242    if ( ((char*) ptr)[i] == '\r')
1243    {
1244      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
1245        ((char*) ptr)[i] = ' ';
1246      else
1247        ((char*) ptr)[i] = '\n';
1248    }
1249  }
1250  return got;
1251}
Note: See TracBrowser for help on using the repository browser.