source: git/Singular/febase.cc @ 744d1ce

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