source: git/Singular/febase.cc @ c19d54

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