source: git/Singular/febase.cc @ a79a128

spielwiese
Last change on this file since a79a128 was a79a128, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* use vsnprintf, instead of vsprintf, when possible * new string and print implementation * small bug fixes in iparith.cc git-svn-id: file:///usr/local/Singular/svn/trunk@2990 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 26.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.cc,v 1.71 1999-04-17 14:58:45 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, vs;
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#ifdef HAVE_VSNPRINTF
800  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
801  if (vs == -1)
802  {
803    assume(0);
804    feBufferStart = feBuffer + feBufferLength -1;
805  }
806  else
807  {
808    feBufferStart += vs;
809  }
810#else
811  feBufferStart += vsprintf(s, fmt, ap);
812#endif
813#endif
814  mmTest(feBuffer, feBufferLength);
815  va_end(ap);
816  return feBuffer;
817}
818
819char * StringAppendS(char *st)
820{
821  /* feBufferStart is feBuffer + strlen(feBuffer);*/
822  int more,l;
823  int ll=feBufferStart-feBuffer;
824  if ((more=ll+2+(l=strlen(st)))>feBufferLength)
825  {
826    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
827    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
828                                                     more);
829    feBufferLength=more;
830    feBufferStart=feBuffer+ll;
831  }
832  strcat(feBufferStart, st);
833  feBufferStart +=l;
834  return feBuffer;
835}
836
837char * StringSetS(char *st)
838{
839  int more,l;
840  if ((l=strlen(st))>feBufferLength)
841  {
842    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
843    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
844                                                     more);
845    feBufferLength=more;
846  }
847  strcpy(feBuffer,st);
848  feBufferStart=feBuffer+l;
849  return feBuffer;
850}
851
852#ifndef __MWERKS__
853#ifdef HAVE_TCL
854extern "C" {
855void PrintTCLS(const char c, const char *s)
856{
857  int l=strlen(s);
858  if (l>0) PrintTCL(c,l,s);
859}
860}
861#endif
862#endif
863
864extern "C" {
865void WerrorS(const char *s)
866{
867#ifdef HAVE_MPSR
868  if (feBatch)
869  {
870    if (feErrors==NULL)
871    {
872      feErrors=(char *)Alloc(256);
873      feErrorsLen=256;
874      *feErrors = '\0';
875    }
876    else
877    {
878      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
879      {
880        feErrors=(char *)ReAlloc(feErrors,feErrorsLen,feErrorsLen+256);
881        feErrorsLen+=256;
882      }
883    }
884    strcat(feErrors, "Singular error: ");
885    strcat(feErrors, (char *)s);
886  }
887  else
888#endif
889  {
890#ifdef HAVE_TCL
891    if (tclmode)
892    {
893      PrintTCLS('E',(char *)s);
894      PrintTCLS('E',"\n");
895    }
896    else
897#endif
898    {
899      fwrite("   ? ",1,5,stderr);
900      fwrite((char *)s,1,strlen((char *)s),stderr);
901      fwrite("\n",1,1,stderr);
902      fflush(stderr);
903      if (feProt&PROT_O)
904      {
905        fwrite("   ? ",1,5,feProtFile);
906        fwrite((char *)s,1,strlen((char *)s),feProtFile);
907        fwrite("\n",1,1,feProtFile);
908      }
909    }
910  }
911  errorreported = TRUE;
912}
913
914void Werror(char *fmt, ...)
915{
916  va_list ap;
917  va_start(ap, fmt);
918  char *s=(char *)Alloc(256);
919  vsprintf(s, fmt, ap);
920  WerrorS(s);
921  Free(s,256);
922  va_end(ap);
923}
924}
925
926void WarnS(const char *s)
927{
928  #define warn_str "// ** "
929#ifdef HAVE_TCL
930  if (tclmode)
931  {
932    PrintTCLS('W',warn_str);
933    PrintTCLS('W',s);
934    PrintTCLS('W',"\n");
935  }
936  else
937#endif
938  if (feWarn) /* ignore warnings in when optin --no-warn was given */
939  {
940    fwrite(warn_str,1,6,stdout);
941    fwrite(s,1,strlen(s),stdout);
942    fwrite("\n",1,1,stdout);
943    fflush(stdout);
944    if (feProt&PROT_O)
945    {
946      fwrite(warn_str,1,6,feProtFile);
947      fwrite(s,1,strlen(s),feProtFile);
948      fwrite("\n",1,1,feProtFile);
949    }
950  }
951}
952
953void Warn(const char *fmt, ...)
954{
955  va_list ap;
956  va_start(ap, fmt);
957  char *s=(char *)Alloc(256);
958  vsprintf(s, fmt, ap);
959  WarnS(s);
960  Free(s,256);
961  va_end(ap);
962}
963
964extern "C" {
965void assume_violation(char* file, int line)
966{
967  fprintf(stderr, "Internal assume violation: file %s line %d\n", file, line);
968}
969}
970
971#ifdef macintosh
972static  int lines = 0;
973static  int cols = 0;
974
975void mwrite(uchar c)
976{
977  if (c == '\n')
978  {
979    cols = 0;
980    if (lines == pagelength)
981    {
982      lines = 0;
983      fePause();
984    }
985    else
986    {
987      lines++;
988      fePutChar(c);
989    }
990  }
991  else
992  {
993    fePutChar(c);
994    cols++;
995    if (cols == colmax)
996    {
997      // cols = 0;   //will be done by mwrite('\n');
998      mwrite('\n');
999    }
1000  }
1001}
1002#endif
1003
1004// some routines which redirect the output of print to a string
1005static char* sprint = NULL;
1006void SPrintStart()
1007{
1008  sprint = mstrdup("");
1009}
1010
1011static void SPrintS(char* s)
1012{
1013  if (s == NULL) return;
1014  int ls = strlen(s);
1015  if (ls == 0) return;
1016 
1017  char* ns;
1018  int l = strlen(sprint);
1019  ns = (char*) AllocL((l + ls + 1)*sizeof(char));
1020  if (l > 0) strcpy(ns, sprint);
1021 
1022  strcpy(&(ns[l]), s);
1023  FreeL(sprint);
1024  sprint = ns;
1025}
1026
1027char* SPrintEnd()
1028{
1029  char* ns = sprint;
1030  sprint = NULL;
1031  return ns;
1032}
1033
1034// Print routines
1035extern "C" {
1036void PrintS(char *s)
1037{
1038  if (sprint != NULL)
1039  {
1040    SPrintS(s);
1041    return;
1042  }
1043 
1044  if (feOut) /* do not print when option --no-out was given */
1045  {
1046   
1047#ifdef macintosh
1048    char c;
1049    while ('\0' != (c = *s++))
1050    {
1051      mwrite(c);
1052    }
1053#else
1054#ifdef HAVE_TCL
1055    if (tclmode)
1056    {
1057      PrintTCLS('N',s);
1058    }
1059    else
1060#endif
1061    {
1062      fwrite(s,1,strlen(s),stdout);
1063      fflush(stdout);
1064      if (feProt&PROT_O)
1065      {
1066        fwrite(s,1,strlen(s),feProtFile);
1067      }
1068    }
1069#endif
1070  }
1071}
1072
1073void PrintLn()
1074{
1075  PrintS("\n");
1076}
1077
1078void Print(char *fmt, ...)
1079{
1080  if (sprint != NULL)
1081  {
1082    int ls = strlen(fmt);
1083    va_list ap;
1084    va_start(ap, fmt);
1085    if (fmt != NULL && ls > 0)
1086    {
1087      char* ns;
1088      int l = strlen(sprint);
1089      ns = (char*) AllocL(sizeof(char)*(ls + l + 256));
1090      if (l > 0)  strcpy(ns, sprint);
1091               
1092#ifdef HAVE_VSNPRINTF
1093      l = vsnprintf(&(ns[l]), ls+255, fmt, ap);
1094      assume(l != -1);
1095#else
1096      vsprintf(&(ns[l]), fmt, ap);
1097#endif
1098      mmTestL(ns);
1099      FreeL(sprint);
1100      sprint = ns;
1101    }
1102    va_end(ap);
1103    return;
1104  }
1105  if (feOut)
1106  {
1107    va_list ap;
1108    va_start(ap, fmt);
1109#ifdef HAVE_TCL
1110    if(tclmode)
1111#endif
1112#if (defined(HAVE_TCL) || defined(macintosh))
1113    {
1114      char *s=(char *)Alloc(strlen(fmt)+256);
1115      vsprintf(s,fmt, ap);
1116#ifdef HAVE_TCL
1117      PrintTCLS('N',s);
1118#endif
1119#ifdef macintosh
1120      char c;
1121      while ('\0' != (c = *s++))
1122      {
1123        mwrite(c);
1124      }
1125      if (feProt&PROT_O)
1126      {
1127        vfprintf(feProtFile,fmt,ap);
1128      }
1129#endif
1130    }
1131#endif
1132#if !defined(macintosh) || defined(HAVE_TCL)
1133#ifdef HAVE_TCL
1134    else
1135#endif
1136    {
1137      vfprintf(stdout, fmt, ap);
1138      fflush(stdout);
1139      if (feProt&PROT_O)
1140      {
1141        vfprintf(feProtFile,fmt,ap);
1142      }
1143    }
1144#endif
1145    va_end(ap);
1146  }
1147}
1148
1149/* end extern "C" */
1150}
1151
1152void fePause()
1153{
1154#ifdef HAVE_TCL
1155  if(!tclmode)
1156#endif
1157  {
1158    mflush();
1159#ifndef macintosh
1160    fputs("pause>",stderr);
1161#else
1162    fputs("pause>\n",stderr);
1163#endif
1164    uchar c = fgetc(stdin);
1165    if (((c == '\003') || (c == 'C')) || (c == 'c'))
1166    {
1167      m2_end(4);
1168    }
1169  }
1170}
1171
1172void monitor(char* s, int mode)
1173{
1174  if (feProt)
1175  {
1176    fclose(feProtFile);
1177  }
1178  if ((s!=NULL) && (*s!='\0'))
1179  {
1180    feProtFile = myfopen(s,"w");
1181    if (feProtFile==NULL)
1182    {
1183      Werror("cannot open %s",s);
1184    }
1185    else
1186      feProt = (BOOLEAN)mode;
1187  }
1188}
1189
1190
1191char* eati(char *s, int *i)
1192{
1193  int l=0;
1194
1195  if    (*s >= '0' && *s <= '9')
1196  {
1197    *i = 0;
1198    while (*s >= '0' && *s <= '9')
1199    {
1200      *i *= 10;
1201      *i += *s++ - '0';
1202      l++;
1203      if ((l>MAX_INT_LEN)||((*i) <0))
1204      {
1205        s-=l;
1206        Werror("`%s` greater than %d(max. integer representation)",
1207                s,INT_MAX);
1208        return s;
1209      }
1210    }
1211  }
1212  else *i = 1;
1213  return s;
1214}
1215
1216#ifndef unix
1217// Make sure that mode contains binary option
1218FILE *myfopen(char *path, char *mode)
1219{
1220  char mmode[4];
1221  int i;
1222  BOOLEAN done = FALSE;
1223
1224  for (i=0;;i++)
1225  {
1226    mmode[i] = mode[i];
1227    if (mode[i] == '\0') break;
1228    if (mode[i] == 'b') done = TRUE;
1229  }
1230
1231  if (! done)
1232  {
1233    mmode[i] = 'b';
1234    mmode[i+1] = '\0';
1235  }
1236  return fopen(path, mmode);
1237}
1238#endif
1239
1240// replace "\r\n" by " \n" and "\r" by "\n"
1241
1242size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
1243{
1244  size_t got = fread(ptr, size, nmemb, stream) * size;
1245  size_t i;
1246
1247  for (i=0; i<got; i++)
1248  {
1249    if ( ((char*) ptr)[i] == '\r')
1250    {
1251      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
1252        ((char*) ptr)[i] = ' ';
1253      else
1254        ((char*) ptr)[i] = '\n';
1255    }
1256  }
1257  return got;
1258}
Note: See TracBrowser for help on using the repository browser.