source: git/Singular/febase.cc @ 2afef4

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