source: git/Singular/febase.cc @ e51e9b

fieker-DuValspielwiese
Last change on this file since e51e9b was e51e9b, checked in by Olaf Bachmann <obachman@…>, 26 years ago
* fixed Module (rank bug) git-svn-id: file:///usr/local/Singular/svn/trunk@2476 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 24.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: febase.cc,v 1.66 1998-08-24 14:39:07 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;
73#ifdef macintosh
74static  int lines = 0;
75static  int cols = 0;
76#endif
77
78const char feNotImplemented[]="not implemented";
79
80BOOLEAN feProt = FALSE;
81FILE*   feProtFile;
82BOOLEAN tclmode=FALSE;
83/* TCL-Protocoll (Singular -x): <char type>:<int length>:<string> \n
84*  E:l:s  error
85*  W:l:s  warning
86*  N:l:s  stdout
87*  Q:0:   quit
88*  P:l:   prompt > (ring defined)
89*  U:l:   prompt > (no ring defined)
90*  P:l:   prompt .
91*  R:l:<ring-name> ring change
92*  L:l:<lib name> library loaded
93*  O:l:<list of options(space seperated)> option change
94*  M:l:<mem-usage> output from "option(mem)"
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#ifndef __MWERKS__
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    fclose(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#endif
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
839#ifndef __MWERKS__
840#ifdef HAVE_TCL
841void PrintTCLS(const char c, const char *s)
842{
843  int l=strlen(s);
844  if (l>0) PrintTCL(c,l,s);
845}
846#endif
847#endif
848
849extern "C" {
850void WerrorS(const char *s)
851{
852#ifdef HAVE_MPSR
853  if (feBatch)
854  {
855    if (feErrors==NULL)
856    {
857      feErrors=(char *)Alloc(256);
858      feErrorsLen=256;
859      strcpy(feErrors,(char *)s);
860    }
861    else
862    {
863      if (((int)(strlen((char *)s)+strlen(feErrors)))>=feErrorsLen)
864      {
865        feErrors=(char *)ReAlloc(feErrors,feErrorsLen,feErrorsLen+256);
866        feErrorsLen+=256;
867      }
868      strcat(feErrors,(char *)s);
869    }
870    strcat(feErrors,"\n");
871  }
872  else
873#endif
874  {
875#ifdef HAVE_TCL
876    if (tclmode)
877    {
878      PrintTCLS('E',(char *)s);
879      PrintTCLS('E',"\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  #define warn_str "// ** "
914#ifdef HAVE_TCL
915  if (tclmode)
916  {
917    PrintTCLS('W',warn_str);
918    PrintTCLS('W',s);
919    PrintTCLS('W',"\n");
920  }
921  else
922#endif
923#ifdef HAVE_MPSR
924  if (!feBatch) /* ignore warnings in febatch-mode */
925#endif
926  {
927    fwrite(warn_str,1,6,stdout);
928    fwrite(s,1,strlen(s),stdout);
929    fwrite("\n",1,1,stdout);
930    fflush(stdout);
931    if (feProt&PROT_O)
932    {
933      fwrite(warn_str,1,6,feProtFile);
934      fwrite(s,1,strlen(s),feProtFile);
935      fwrite("\n",1,1,feProtFile);
936    }
937  }
938}
939
940void Warn(const char *fmt, ...)
941{
942  va_list ap;
943  va_start(ap, fmt);
944  char *s=(char *)Alloc(256);
945  vsprintf(s, fmt, ap);
946  WarnS(s);
947  Free(s,256);
948  va_end(ap);
949}
950
951#ifdef macintosh
952void mwrite(uchar c)
953{
954  if (c == '\n')
955  {
956    cols = 0;
957    if (lines == pagelength)
958    {
959      lines = 0;
960      fePause();
961    }
962    else
963    {
964      lines++;
965      fePutChar(c);
966    }
967  }
968  else
969  {
970    fePutChar(c);
971    cols++;
972    if (cols == colmax)
973    {
974//      cols = 0;   //will be done by mwrite('\n');
975      mwrite('\n');
976    }
977  }
978}
979#endif
980
981void PrintS(char *s)
982{
983#ifdef macintosh
984  char c;
985  while ('\0' != (c = *s++))
986  {
987    mwrite(c);
988  }
989#else
990#ifdef HAVE_TCL
991  if (tclmode)
992  {
993    PrintTCLS('N',s);
994  }
995  else
996#endif
997  {
998    fwrite(s,1,strlen(s),stdout);
999    fflush(stdout);
1000    if (feProt&PROT_O)
1001    {
1002      fwrite(s,1,strlen(s),feProtFile);
1003    }
1004  }
1005#endif
1006}
1007
1008void PrintLn()
1009{
1010  PrintS("\n");
1011}
1012
1013void Print(char *fmt, ...)
1014{
1015  va_list ap;
1016  va_start(ap, fmt);
1017#ifdef HAVE_TCL
1018  if(tclmode)
1019#endif
1020#if (defined(HAVE_TCL) || defined(macintosh))
1021  {
1022    char *s=(char *)Alloc(strlen(fmt)+256);
1023    vsprintf(s,fmt, ap);
1024#ifdef HAVE_TCL
1025    PrintTCLS('N',s);
1026#endif
1027#ifdef macintosh
1028  char c;
1029  while ('\0' != (c = *s++))
1030  {
1031    mwrite(c);
1032  }
1033  if (feProt&PROT_O)
1034  {
1035    vfprintf(feProtFile,fmt,ap);
1036  }
1037#endif
1038  }
1039#endif
1040#if !defined(macintosh) || defined(HAVE_TCL)
1041#ifdef HAVE_TCL
1042  else
1043#endif
1044  {
1045    vfprintf(stdout, fmt, ap);
1046    fflush(stdout);
1047    if (feProt&PROT_O)
1048    {
1049      vfprintf(feProtFile,fmt,ap);
1050    }
1051  }
1052#endif
1053  va_end(ap);
1054}
1055
1056void fePause()
1057{
1058#ifdef HAVE_TCL
1059  if(!tclmode)
1060#endif
1061  {
1062    mflush();
1063#ifndef macintosh
1064    fputs("pause>",stderr);
1065#else
1066    fputs("pause>\n",stderr);
1067#endif
1068    uchar c = fgetc(stdin);
1069    if (((c == '\003') || (c == 'C')) || (c == 'c'))
1070    {
1071      m2_end(4);
1072    }
1073  }
1074}
1075
1076void monitor(char* s, int mode)
1077{
1078  if (feProt)
1079  {
1080    fclose(feProtFile);
1081  }
1082  if ((s!=NULL) && (*s!='\0'))
1083  {
1084    feProtFile = myfopen(s,"w");
1085    if (feProtFile==NULL)
1086    {
1087      Werror("cannot open %s",s);
1088    }
1089    else
1090      feProt = (BOOLEAN)mode;
1091  }
1092}
1093
1094
1095char* eati(char *s, int *i)
1096{
1097  int l=0;
1098
1099  if    (*s >= '0' && *s <= '9')
1100  {
1101    *i = 0;
1102    while (*s >= '0' && *s <= '9')
1103    {
1104      *i *= 10;
1105      *i += *s++ - '0';
1106      l++;
1107      if ((l>MAX_INT_LEN)||((*i) <0))
1108      {
1109        s-=l;
1110        Werror("`%s` greater than %d(max. integer representation)",
1111                s,INT_MAX);
1112        return s;
1113      }
1114    }
1115  }
1116  else *i = 1;
1117  return s;
1118}
1119
1120#ifndef unix
1121// Make sure that mode contains binary option
1122FILE *myfopen(char *path, char *mode)
1123{
1124  char mmode[4];
1125  int i;
1126  BOOLEAN done = FALSE;
1127
1128  for (i=0;;i++)
1129  {
1130    mmode[i] = mode[i];
1131    if (mode[i] == '\0') break;
1132    if (mode[i] == 'b') done = TRUE;
1133  }
1134
1135  if (! done)
1136  {
1137    mmode[i] = 'b';
1138    mmode[i+1] = '\0';
1139  }
1140  return fopen(path, mmode);
1141}
1142#endif
1143
1144// replace "\r\n" by " \n" and "\r" by "\n"
1145
1146size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
1147{
1148  size_t got = fread(ptr, size, nmemb, stream) * size;
1149  size_t i;
1150
1151  for (i=0; i<got; i++)
1152  {
1153    if ( ((char*) ptr)[i] == '\r')
1154    {
1155      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
1156        ((char*) ptr)[i] = ' ';
1157      else
1158        ((char*) ptr)[i] = '\n';
1159    }
1160  }
1161  return got;
1162}
Note: See TracBrowser for help on using the repository browser.