source: git/Singular/febase.cc @ b98c7d

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