source: git/Singular/febase.cc @ c20843

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