source: git/Singular/febase.cc @ bdf4da

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