source: git/Singular/febase.cc @ 34b0bab

spielwiese
Last change on this file since 34b0bab was 34b0bab, checked in by Hans Schönemann <hannes@…>, 25 years ago
* hannes: minor changes for macs git-svn-id: file:///usr/local/Singular/svn/trunk@2495 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.67 1998-09-01 15:10:15 Singular Exp $ */
5/*
6* ABSTRACT: i/o system
7*/
8
9#include "mod2.h"
10
11#include <stdlib.h>
12#include <stdio.h>
13#include <limits.h>
14#include <stdarg.h>
15#ifndef __MWERKS__
16#include <unistd.h>
17#endif
18#ifdef NeXT
19#include <sys/file.h>
20#endif
21
22#include "tok.h"
23#include "febase.h"
24#include "mmemory.h"
25#include "subexpr.h"
26#include "ipshell.h"
27
28#include "si_paths.h"
29
30#ifndef MAXPATHLEN
31#define MAXPATHLEN 1024
32#endif
33
34#ifndef MAXNAMLEN
35#define MAXNAMLEN MAXPATHLEN
36#endif
37
38#define fePutChar(c) fputc((uchar)(c),stdout)
39/*0 implementation */
40
41char fe_promptstr[]
42#ifdef macintosh
43                   =" \n";
44#else
45                   ="  ";
46#endif
47
48#define INITIAL_PRINT_BUFFER 24*1024
49static int feBufferLength=INITIAL_PRINT_BUFFER;
50static char * feBuffer=(char *)Alloc(INITIAL_PRINT_BUFFER);
51
52int     si_echo = 0;
53int     printlevel = 0;
54#ifndef macintosh
55int     pagelength = 24;
56#else
57int     pagelength = -1;
58#endif
59int     colmax = 80;
60char    prompt_char = '>'; /*1 either '>' or '.'*/
61extern "C" {
62BITSET  verbose = 1
63                  | Sy_bit(V_REDEFINE)
64                  | Sy_bit(V_LOAD_LIB)
65                  | Sy_bit(V_SHOW_USE)
66                  | Sy_bit(V_PROMPT)
67/*                  | Sy_bit(V_DEBUG_MEM) */
68;}
69BOOLEAN errorreported = FALSE;
70BOOLEAN feBatch=FALSE;
71char *  feErrors=NULL;
72int     feErrorsLen=0;
73
74const char feNotImplemented[]="not implemented";
75
76BOOLEAN feProt = FALSE;
77FILE*   feProtFile;
78BOOLEAN tclmode=FALSE;
79/* TCL-Protocoll (Singular -x): <char type>:<int length>:<string> \n
80*  E:l:s  error
81*  W:l:s  warning
82*  N:l:s  stdout
83*  Q:0:   quit
84*  P:l:   prompt > (ring defined)
85*  U:l:   prompt > (no ring defined)
86*  P:l:   prompt .
87*  R:l:<ring-name> ring change
88*  L:l:<lib name> library loaded
89*  O:l:<list of options(space seperated)> option change
90*  M:l:<mem-usage> output from "option(mem)"
91*/
92
93#include "febase.inc"
94
95#ifdef macintosh
96#  define  DIR_SEP ':'
97#  define  DIR_SEPP ":"
98#else
99#ifdef MSDOS
100#  define  DIR_SEP '\\'
101#  define  DIR_SEPP "\\"
102#else
103#ifdef atarist
104#  define  DIR_SEP '\\'
105#  define  DIR_SEPP "\\"
106#else  /* unix */
107#  define  DIR_SEP '/'
108#  define  DIR_SEPP "/"
109#endif  /* atarist */
110#endif  /* MSDOS */
111#endif  /* macintosh */
112
113#if defined(WINNT)
114#  define  FS_SEP ';'
115#elif defined(macintosh)
116#define FS_SEP ','
117#else
118#define FS_SEP ':'
119#endif
120
121#ifndef __MWERKS__
122/*****************************************************************
123 *
124 * PATH STUFF
125 *
126 *****************************************************************/
127
128// Define to chatter about path stuff
129// #define PATH_DEBUG
130static char* feArgv0 = NULL;
131static char* feExpandedExecutable = NULL;
132static char* feBinDir = NULL;
133static char* feSearchPath = NULL;
134static char* feInfoProgram = NULL;
135static char* feInfoFile = NULL;
136static char* feInfoCall = NULL;
137
138extern "C" char* find_executable(const char* argv0);
139static char* feRemovePathnameHead(const char* expanded_executable);
140static char* CleanUpPath(char* path);
141static char* CleanUpName(char* filename);
142
143inline char* feGetExpandedExecutable(const char* argv0)
144{
145  return (argv0 != NULL ? find_executable(argv0) : (char* ) NULL);
146}
147
148inline char* feGetBinDir(const char* expanded_executable)
149{
150  return feRemovePathnameHead(expanded_executable);
151}
152
153// Return the file search path for singular w.r.t. the following steps:
154// 1.) SINGULARPATH Env Variable
155// 2.) bindir/LIB
156// 3.) bindir/LIB/VERSION
157// 4.) bindir/../../Singular/LIB
158// 5.) bindir/../../Singular/LIB/VERSION
159// 6.) ROOT_DIR/Singular/LIB/
160// 7.) ROOT_DIR/Singular/LIB/VERSION
161// 8.) Go through all dirs and remove duplicates dirs resp.
162//     those which do not exist
163static char* feGetSearchPath(const char* bindir)
164{
165  char *env = NULL, *path, *opath;
166  int plength = 0, tmp;
167
168#ifdef MSDOS
169    env=getenv("SPATH");
170#else
171    env=getenv("SINGULARPATH");
172#endif
173#ifdef PATH_DEBUG
174    Print("I'm going to chatter about the Search path:\n");
175#endif
176    if (env != NULL)
177      plength = strlen(env);
178
179    if (bindir != NULL)
180      plength += 4*strlen(bindir);
181
182    plength += 2*strlen(SINGULAR_ROOT_DIR)
183      + 3*(strlen(S_VERSION1) + 1)
184      + 24         + 36          + 12       + 6          + 7;
185      // == 6*/LIB + 4*/Singular + 2*/../.. + for colons + some room to breath
186
187    opath = (char*) AllocL(plength*sizeof(char));
188    path = opath;
189
190    if (env != NULL)
191    {
192      strcpy(path, env);
193      path += strlen(path);
194      *path=FS_SEP;
195      path++;
196#ifdef PATH_DEBUG
197      *(path +1) = '\0';
198      Print("Got from env var: %s\n", opath);
199#endif
200    }
201
202    if (bindir != NULL)
203    {
204      sprintf(
205        path,
206        "%s/LIB%c%s/LIB/%s%c%s/../../Singular/LIB%c%s/../../Singular/LIB/%s%c",
207        bindir, FS_SEP,
208        bindir, S_VERSION1, FS_SEP,
209        bindir, FS_SEP,
210        bindir, S_VERSION1, FS_SEP);
211#ifdef PATH_DEBUG
212      Print("From bindir: %s\n", path);
213#endif
214      path += strlen(path);
215    }
216
217    sprintf(path, "%s/Singular/LIB%c%s/Singular/LIB/%s",
218            SINGULAR_ROOT_DIR, FS_SEP,
219            SINGULAR_ROOT_DIR, S_VERSION1);
220#ifdef PATH_DEBUG
221    Print("From rootdir: %s\n", path);
222#endif
223    return CleanUpPath(opath);
224}
225
226static void mystrcpy(char* d, char* s)
227{
228  assume(d != NULL && s != NULL);
229  while (*s != '\0')
230  {
231    *d = *s;
232    d++;
233    s++;
234  }
235  *d = '\0';
236}
237
238// Return location of file singular.hlp. Search for it as follows:
239// bindir/../doc/singular.hlp
240// bindir/../info/singular.hlp
241// bindir/../../Singular/doc/$version/singular.hlp
242// bindir/../../Singular/doc/singular.hlp
243// bindir/../../info/singular.hlp
244// ROOTDIR/Singular/doc/$version/singular.hlp
245// ROOTDIR/Singular/doc/singular.hlp
246// ROOTDIR/info/singular.hlp
247// Singular search path
248#ifdef WINNT
249static char * feFixFileName(char *hlpdir)
250{
251  if(strncmp(hlpdir,"//",2)==0)
252  {
253    hlpdir[0]=hlpdir[2];
254    hlpdir[1]=':';
255    mystrcpy(hlpdir+2,hlpdir+3);
256  }
257  return hlpdir;
258}
259#else
260#define  feFixFileName(A) (A)
261#endif
262
263static char* feGetInfoFile(const char* bindir)
264{
265  char* hlpfile = (char*) AllocL(max((bindir != NULL ? strlen(bindir) : 0),
266                                     strlen(SINGULAR_ROOT_DIR))
267                                  + 50);
268
269#ifdef PATH_DEBUG
270  Print("Search for singular.hlp\n");
271#endif
272
273  if (bindir != NULL)
274  {
275    // bindir/../doc/singular.hlp
276    sprintf(hlpfile,"%s/../doc/singular.hlp", bindir);
277#ifdef PATH_DEBUG
278    Print("trying %s -- %s\n", hlpfile, ( access(CleanUpName(hlpfile), R_OK) ? "no" : "yes"));
279#endif
280    if (! access(CleanUpName(hlpfile), R_OK)) return feFixFileName(hlpfile);
281
282    // bindir/../info/singular.hlp
283    sprintf(hlpfile,"%s/../info/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/../../Singular/doc/$version/singular.hlp
290    sprintf(hlpfile,"%s/../../Singular/doc/%s/singular.hlp",bindir,S_VERSION1);
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/singular.hlp
297    sprintf(hlpfile,"%s/../../Singular/doc/singular.hlp", bindir);
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/../../info/singular.hlp
304    sprintf(hlpfile,"%s/../../info/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    // ROOTDIR/Singular/doc/$version/singular.hlp
311    sprintf(hlpfile,"%s/Singular/doc/%s/singular.hlp", SINGULAR_ROOT_DIR, S_VERSION1);
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/singular.hlp
318    sprintf(hlpfile,"%s/Singular/doc/singular.hlp", SINGULAR_ROOT_DIR);
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/info/singular.hlp
325    sprintf(hlpfile,"%s/info/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
332  // still here? Try all dirs in the search path
333  FILE *file = feFopen("singular.hlp", "r", hlpfile, 0);
334  if (file != NULL)
335  {
336    fclose(file);
337    return feFixFileName(hlpfile);
338  }
339  *hlpfile = '\0';
340  return hlpfile;
341}
342
343#ifdef WINNT
344#define INFOPROG "info.exe"
345#else
346#define INFOPROG "info"
347#endif
348
349// we first look into bindir, if nothing found there, we use HAVE_INFO
350static char* feGetInfoProgram(const char* bindir)
351{
352  char infoprog[MAXPATHLEN];
353  if (bindir != NULL)
354  {
355    sprintf(infoprog, "%s/%s", bindir, INFOPROG);
356    if (! access(infoprog, X_OK)) return mstrdup(infoprog);
357  }
358
359  sprintf(infoprog, "%s/%s", SINGULAR_BIN_DIR, INFOPROG);
360  if (! access(infoprog, X_OK)) return mstrdup(infoprog);
361
362#ifdef HAVE_INFO
363  sprintf(infoprog, "%s", HAVE_INFO);
364  if (! access(infoprog, X_OK)) return mstrdup(infoprog);
365#endif
366  // nothing found, let's try "info"
367  sprintf(infoprog, "info");
368  return mstrdup(infoprog);
369}
370
371#if defined(WINNT) && defined(__GNUC__)
372// add utility function of Cygwin32:
373extern "C" int cygwin32_posix_path_list_p (const char *path);
374#endif
375
376#ifdef WINNT
377static void feExpandPath(char *dir)
378{
379  char *path=getenv("PATH");
380  char buf[MAXNAMLEN];
381  if (path==NULL)
382  {
383    strcpy(buf,dir);
384  }
385  else
386  {
387    #if defined(WINNT) && defined(__GNUC__)
388    char path_delim = cygwin32_posix_path_list_p (path) ? ':' : ';';
389    #else
390    char path_delim=FS_SEP;
391    #endif
392    sprintf(buf,"%s%c%s",path,path_delim,dir);
393  }
394  setenv("PATH",buf,1);
395}
396#endif
397
398//
399// public routines
400//
401void feInitPaths(const char* argv0)
402{
403  feArgv0 = mstrdup(argv0);
404  #ifdef WINNT
405  // add the bindir and the BIN_DIR to the current PATH:
406  feExpandPath(feGetBinDir()); // can only be called after setting feArgv0
407  feExpandPath(SINGULAR_BIN_DIR);
408  #endif
409}
410
411char* feGetExpandedExecutable()
412{
413  if (feExpandedExecutable == NULL)
414    feExpandedExecutable = feGetExpandedExecutable(feArgv0);
415  return feExpandedExecutable;
416}
417
418char* feGetBinDir()
419{
420  if (feBinDir == NULL)
421    feBinDir = feGetBinDir(feGetExpandedExecutable());
422  return feBinDir;
423}
424
425char* feGetSearchPath()
426{
427  if (feSearchPath == NULL)
428    feSearchPath = feGetSearchPath(feGetBinDir());
429  return feSearchPath;
430}
431
432char* feGetInfoProgram()
433{
434  if (feInfoProgram == NULL)
435    feInfoProgram = feGetInfoProgram(feGetBinDir());
436  return feInfoProgram;
437}
438
439char* feGetInfoFile()
440{
441  if (feInfoFile == NULL)
442    feInfoFile = feGetInfoFile(feGetBinDir());
443  return feInfoFile;
444}
445
446char* feGetInfoCall(const char* what)
447{
448  if (feInfoCall == NULL)
449    feInfoCall = (char*) AllocL(strlen(feGetInfoProgram())
450                                + strlen(feGetInfoFile())
451                                + 100);
452  char *infofile = feGetInfoFile();
453
454  if (what != NULL && strcmp(what, "index") != 0)
455    sprintf(feInfoCall,
456            "%s %s %s Index %s",
457            feGetInfoProgram(),
458            (*infofile != '\0' ? "-f" : ""),
459            (*infofile != '\0' ? infofile : "Singular"),
460            what);
461  else
462    sprintf(feInfoCall,
463            "%s %s %s",
464            feGetInfoProgram(),
465            (*infofile != '\0' ? "-f" : ""),
466            (*infofile != '\0' ? infofile : "Singular"));
467
468#ifdef PATH_DEBUG
469  Print("Info call with: %s \n", feInfoCall);
470#endif
471  return feInfoCall;
472}
473
474//
475// auxillary routines
476//
477static char* feRemovePathnameHead(const char* ef)
478{
479  if (ef != NULL)
480  {
481    char* ret = mstrdup(ef);
482    char* p = strrchr(ret, DIR_SEP);
483    if (p != NULL) *p = '\0';
484    return ret;
485  }
486  return NULL;
487}
488
489// remove duplicates dir resp. those which do not exist
490static char* CleanUpPath(char* path)
491{
492#ifdef PATH_DEBUG
493  Print("Entered CleanUpPath with: %s\n", path);
494#endif
495  if (path == NULL) return path;
496
497  int n_comps = 1, i, j;
498  char* opath = path;
499  char** path_comps;
500
501  for (; *path != '\0'; path++)
502  {
503    if (*path == FS_SEP) n_comps++;
504  }
505
506
507  path_comps = (char**) AllocL(n_comps*sizeof(char*));
508  path_comps[0]=opath;
509  path=opath;
510  i = 1;
511
512  if (i < n_comps)
513  {
514    while (1)
515    {
516      if (*path == FS_SEP)
517      {
518        *path = '\0';
519        path_comps[i] = path+1;
520        i++;
521        if (i == n_comps) break;
522      }
523      path++;
524    }
525  }
526
527  for (i=0; i<n_comps; i++)
528    path_comps[i] = CleanUpName(path_comps[i]);
529#ifdef PATH_DEBUG
530  Print("After CleanUpName: ");
531  for (i=0; i<n_comps; i++)
532    Print("%s:", path_comps[i]);
533  Print("\n");
534#endif
535
536  for (i=0; i<n_comps;)
537  {
538#ifdef PATH_DEBUG
539    if (access(path_comps[i], X_OK))
540      Print("remove %d:%s -- can not access\n", i, path_comps[i]);
541#endif
542    if ( ! access(path_comps[i], X_OK))
543    {
544      // x- permission is granted -- we assume that it is a dir
545      for (j=0; j<i; j++)
546      {
547        if (strcmp(path_comps[j], path_comps[i]) == 0)
548        {
549          // found a duplicate
550#ifdef PATH_DEBUG
551          Print("remove %d:%s -- equal to %d:%s\n", j, path_comps[j], i, path_comps[i]);
552#endif
553          j = i+1;
554          break;
555        }
556      }
557      if (j == i)
558      {
559        i++;
560        continue;
561      }
562    }
563    // now we can either not access or found a duplicate
564    path_comps[i] = NULL;
565    for (j=i+1; j<n_comps; j++)
566        path_comps[j-1] = path_comps[j];
567    n_comps--;
568  }
569
570  // assemble everything again
571  for (path=opath, i=0;i<n_comps-1;i++)
572  {
573    strcpy(path, path_comps[i]);
574    path += strlen(path);
575    *path = FS_SEP;
576    path++;
577  }
578  if (n_comps) strcpy(path, path_comps[i]);
579  FreeL(path_comps);
580#ifdef PATH_DEBUG
581  Print("SearchPath is: %s\n", opath);
582#endif
583  return opath;
584}
585
586static char* CleanUpName(char* fname)
587{
588  char* fn, *s;
589
590  for (fn = fname; *fn != '\0'; fn++)
591  {
592    if (*fn == '/')
593    {
594      if (*(fn+1) == '\0')
595      {
596        if (fname != fn) *fn = '\0';
597        break;
598      }
599      if (*(fn + 1) == '/' && (fname != fn))
600      {
601        mystrcpy(fn, fn+1);
602        fn--;
603      }
604      else if (*(fn+1) == '.')
605      {
606        if (*(fn+2) == '.' && (*(fn + 3) == '/' || *(fn + 3) == '\0'))
607        {
608          *fn = '\0';
609          s = strrchr(fname, '/');
610          if (s != NULL)
611          {
612            mystrcpy(s+1, fn + (*(fn + 3) != '\0' ? 4 : 3));
613            fn = s-1;
614          }
615          else
616          {
617            *fn = '/';
618          }
619        }
620        else if (*(fn+2) == '/' || *(fn+2) == '\0')
621        {
622          mystrcpy(fn+1, fn+3);
623          fn--;
624        }
625      }
626    }
627  }
628  return fname;
629}
630#endif
631/*****************************************************************
632 *
633 * File handling
634 *
635 *****************************************************************/
636
637FILE * feFopen(char *path, char *mode, char *where,int useWerror)
638{
639#ifdef __MWERKS__
640  FILE * f=myfopen(path,mode);
641  if (f!=NULL)
642  {
643    if (where!=NULL) strcpy(where,path);
644    return f;
645  }
646  char *res;
647  int idat=strlen(SINGULAR_DATADIR),ipath=strlen(path);
648  char *env=getenv("SINGULARPATH");
649  int ienv=0, ii=0;
650  if (env!=NULL)
651  {
652    ienv=strlen(env);
653    ii=ienv;
654  }
655  if (ii<idat) ii = idat;
656  if (ii==0)
657  {
658    if (useWerror)
659      Werror("cannot open `%s`",path);
660    return f;
661  }
662  res=(char*) AllocL(ii+ipath+1);
663  if (ienv!=0)
664  {
665    memcpy(res,env,ienv);
666    memcpy(res+ienv,path,ipath);
667    res[ienv+ipath]='\0';
668    f=myfopen(res,mode);
669  }
670  if ((f==NULL)&&(idat!=0))
671  {
672    memcpy(res,SINGULAR_DATADIR,idat);
673    memcpy(res+idat,path,ipath);
674    res[idat+ipath]='\0';
675    f=myfopen(res,mode);
676  }
677  if (f==NULL)
678  {
679    if (useWerror)
680      Werror("cannot open `%s`",res);
681  }
682  else if (where!=NULL)
683    strcpy(where,res);
684  FreeL(res);
685#else
686  BOOLEAN tilde = FALSE;
687  char longpath[MAXPATHLEN];
688  if (path[0]=='~')
689  {
690    char* home = getenv("HOME");
691    if (home != NULL)
692    {
693      strcpy(longpath, home);
694      strcat(longpath, &(path[1]));
695      path = longpath;
696    }
697  }
698  FILE * f=myfopen(path,mode);
699  if (where!=NULL) strcpy(where,path);
700  if ((*mode=='r') && (path[0]!=DIR_SEP)&&(path[0]!='.')
701  &&(f==NULL))
702  {
703    char found = 0;
704    char* spath = feGetSearchPath();
705    char *s;
706
707    if (where==NULL) s=(char *)AllocL(250);
708    else             s=where;
709
710    if (spath!=NULL)
711    {
712      char *p,*q;
713      p = spath;
714      while( (q=strchr(p, FS_SEP)) != NULL)
715      {
716        *q = '\0';
717        strcpy(s,p);
718        *q = FS_SEP;
719        strcat(s, DIR_SEPP);
720        strcat(s, path);
721        #ifndef macintosh
722          if(!access(s, R_OK)) { found++; break; }
723        #else
724          f=fopen(s,mode); /* do not need myfopen: we test only the access */
725          if (f!=NULL)  { found++; fclose(f); break; }
726        #endif
727        p = q+1;
728      }
729      if(!found)
730      {
731        strcpy(s,p);
732        strcat(s, DIR_SEPP);
733        strcat(s, path);
734      }
735      f=myfopen(s,mode);
736      if (f!=NULL)
737      {
738        if (where==NULL) FreeL((ADDRESS)s);
739        return f;
740      }
741    }
742    else
743    {
744      if (where!=NULL) strcpy(s/*where*/,path);
745      f=myfopen(path,mode);
746    }
747    if (where==NULL) FreeL((ADDRESS)s);
748  }
749  if ((f==NULL)&&(useWerror))
750    Werror("cannot open `%s`",path);
751#endif
752  return f;
753}
754
755static char * feBufferStart;
756  /* only used in StringSet(S)/StringAppend(S)*/
757char * StringAppend(char *fmt, ...)
758{
759  va_list ap;
760  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
761  int more;
762  va_start(ap, fmt);
763  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
764  {
765    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
766    int l=s-feBuffer;
767    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
768                                                     more);
769    feBufferLength=more;
770    s=feBuffer+l;
771#ifndef BSD_SPRINTF
772    feBufferStart=s;
773#endif
774  }
775#ifdef BSD_SPRINTF
776  vsprintf(s, fmt, ap);
777  while (*s!='\0') s++;
778  feBufferStart =s;
779#else
780  feBufferStart += vsprintf(s, fmt, ap);
781#endif
782  va_end(ap);
783  return feBuffer;
784}
785
786char * StringAppendS(char *st)
787{
788  /* feBufferStart is feBuffer + strlen(feBuffer);*/
789  int more,l;
790  int ll=feBufferStart-feBuffer;
791  if ((more=ll+2+(l=strlen(st)))>feBufferLength)
792  {
793    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
794    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
795                                                     more);
796    feBufferLength=more;
797    feBufferStart=feBuffer+ll;
798  }
799  strcat(feBufferStart, st);
800  feBufferStart +=l;
801  return feBuffer;
802}
803
804char * StringSet(char *fmt, ...)
805{
806  va_list ap;
807  char *s = feBuffer;
808  va_start(ap, fmt);
809#ifdef BSD_SPRINTF
810  vsprintf(s, fmt, ap);
811  while (*s!='\0') s++;
812  feBufferStart = s;
813#else
814  feBufferStart = feBuffer + vsprintf(s, fmt, ap);
815#endif
816  va_end(ap);
817  return feBuffer;
818}
819
820char * StringSetS(char *st)
821{
822  int more,l;
823  if ((l=strlen(st))>feBufferLength)
824  {
825    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
826    feBuffer=(char *)ReAlloc((ADDRESS)feBuffer,feBufferLength,
827                                                     more);
828    feBufferLength=more;
829  }
830  strcpy(feBuffer,st);
831  feBufferStart=feBuffer+l;
832  return feBuffer;
833}
834
835#ifndef __MWERKS__
836#ifdef HAVE_TCL
837void PrintTCLS(const char c, const char *s)
838{
839  int l=strlen(s);
840  if (l>0) PrintTCL(c,l,s);
841}
842#endif
843#endif
844
845extern "C" {
846void WerrorS(const char *s)
847{
848#ifdef HAVE_MPSR
849  if (feBatch)
850  {
851    if (feErrors==NULL)
852    {
853      feErrors=(char *)Alloc(256);
854      feErrorsLen=256;
855      strcpy(feErrors,(char *)s);
856    }
857    else
858    {
859      if (((int)(strlen((char *)s)+strlen(feErrors)))>=feErrorsLen)
860      {
861        feErrors=(char *)ReAlloc(feErrors,feErrorsLen,feErrorsLen+256);
862        feErrorsLen+=256;
863      }
864      strcat(feErrors,(char *)s);
865    }
866    strcat(feErrors,"\n");
867  }
868  else
869#endif
870  {
871#ifdef HAVE_TCL
872    if (tclmode)
873    {
874      PrintTCLS('E',(char *)s);
875      PrintTCLS('E',"\n");
876    }
877    else
878#endif
879    {
880      fwrite("   ? ",1,5,stderr);
881      fwrite((char *)s,1,strlen((char *)s),stderr);
882      fwrite("\n",1,1,stderr);
883      fflush(stderr);
884      if (feProt&PROT_O)
885      {
886        fwrite("   ? ",1,5,feProtFile);
887        fwrite((char *)s,1,strlen((char *)s),feProtFile);
888        fwrite("\n",1,1,feProtFile);
889      }
890    }
891  }
892  errorreported = TRUE;
893}
894
895void Werror(char *fmt, ...)
896{
897  va_list ap;
898  va_start(ap, fmt);
899  char *s=(char *)Alloc(256);
900  vsprintf(s, fmt, ap);
901  WerrorS(s);
902  Free(s,256);
903  va_end(ap);
904}
905}
906
907void WarnS(const char *s)
908{
909  #define warn_str "// ** "
910#ifdef HAVE_TCL
911  if (tclmode)
912  {
913    PrintTCLS('W',warn_str);
914    PrintTCLS('W',s);
915    PrintTCLS('W',"\n");
916  }
917  else
918#endif
919#ifdef HAVE_MPSR
920  if (!feBatch) /* ignore warnings in febatch-mode */
921#endif
922  {
923    fwrite(warn_str,1,6,stdout);
924    fwrite(s,1,strlen(s),stdout);
925    fwrite("\n",1,1,stdout);
926    fflush(stdout);
927    if (feProt&PROT_O)
928    {
929      fwrite(warn_str,1,6,feProtFile);
930      fwrite(s,1,strlen(s),feProtFile);
931      fwrite("\n",1,1,feProtFile);
932    }
933  }
934}
935
936void Warn(const char *fmt, ...)
937{
938  va_list ap;
939  va_start(ap, fmt);
940  char *s=(char *)Alloc(256);
941  vsprintf(s, fmt, ap);
942  WarnS(s);
943  Free(s,256);
944  va_end(ap);
945}
946
947#ifdef macintosh
948static  int lines = 0;
949static  int cols = 0;
950
951void mwrite(uchar c)
952{
953  if (c == '\n')
954  {
955    cols = 0;
956    if (lines == pagelength)
957    {
958      lines = 0;
959      fePause();
960    }
961    else
962    {
963      lines++;
964      fePutChar(c);
965    }
966  }
967  else
968  {
969    fePutChar(c);
970    cols++;
971    if (cols == colmax)
972    {
973      // cols = 0;   //will be done by mwrite('\n');
974      mwrite('\n');
975    }
976  }
977}
978#endif
979
980void PrintS(char *s)
981{
982#ifdef macintosh
983  char c;
984  while ('\0' != (c = *s++))
985  {
986    mwrite(c);
987  }
988#else
989#ifdef HAVE_TCL
990  if (tclmode)
991  {
992    PrintTCLS('N',s);
993  }
994  else
995#endif
996  {
997    int i=strlen(s);
998    fwrite(s,1,i,stdout);
999    fflush(stdout);
1000    if (feProt&PROT_O)
1001    {
1002      fwrite(s,1,i,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.