source: git/Singular/emacs.cc

spielwiese
Last change on this file was a95069, checked in by Hans Schoenemann <hannes@…>, 12 months ago
sprintf -> snprintf
  • Property mode set to 100644
File size: 8.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: Esingular main file
6*/
7
8
9
10
11#include "kernel/mod2.h"
12#include "omalloc/omalloc.h"
13#include "resources/feResource.h"
14#include "Singular/feOpt.h"
15
16#ifdef __CYGWIN__
17#define BOOLEAN boolean
18#endif
19
20#include <unistd.h>
21
22#ifdef DecAlpha_OSF1
23#define _BSD
24#endif
25
26#include <stdarg.h>
27
28#ifdef __CYGWIN__
29#include <windows.h>
30#endif
31
32
33#if !defined(TSINGULAR) && !defined(ESINGULAR)
34#define ESINGULAR
35#endif
36
37#ifdef system
38#undef system
39#endif
40
41#ifndef FALSE
42#define FALSE 0
43#endif
44#ifndef TRUE
45#define TRUE 1
46#endif
47#ifndef MAXPATHLEN
48#define MAXPATHLEN 1024
49#endif
50#  define  DIR_SEP '/'
51#  define  DIR_SEPP "/"
52#  define  UP_DIR ".."
53
54#ifndef __CYGWIN__
55void error(const char *fmt, ...)
56{
57  va_list ap;
58  va_start(ap, fmt);
59  vfprintf(stderr, fmt, ap);
60}
61#else
62void error(const char* fmt, ...)
63{
64   char buf[4096];
65   int j =0;
66   va_list args;
67   va_start(args, fmt);
68   j =   snprintf(buf,4096,    "");
69   j += vsnprintf(buf + j,4096-j,fmt,args);
70   j +=  snprintf(buf + j,4096-j,"\n");
71   va_end(args);
72   MessageBox(NULL, buf, "ESingular.exe", MB_ICONSTOP);
73   exit(1);
74}
75#endif
76
77#define Warn  error
78#define WarnS error
79#define StringAppend printf
80#define Print error
81
82#define feReportBug(s) fePrintReportBug(s, __FILE__, __LINE__)
83void fePrintReportBug(char* msg, char* file, int line)
84{
85  error("YOU HAVE FOUND A BUG IN SINGULAR.\n"
86"Please, email the following output to singular@mathematik.uni-kl.de\n"
87"Bug occurred at %s:%d\n"
88"Message: %s\n"
89"Version: " S_UNAME VERSION VERSION_DATE,
90        file, line, msg);
91
92}
93
94void mainUsage()
95{
96  error( "Use `%s --help' for a complete list of options\n", feArgv0);
97}
98
99extern char* feResourceDefault(const char id);
100extern char* feResourceDefault(const char* key);
101
102
103int main(int argc, char** argv)
104{
105  char* singular = NULL;
106  char* emacs = NULL;
107#ifndef TSINGULAR
108  char* emacs_dir = NULL;
109  char* emacs_load = NULL;
110  char cwd[MAXPATHLEN];
111#endif
112  int no_emacs_call = 0;
113
114  // parse-cmdline options
115
116  feInitResources(argv[0]);
117  feResource('S');
118  feResource('b');
119  feResource('r');
120
121  int optc, option_index;
122
123  while ((optc = fe_getopt_long(argc, argv, SHORT_OPTS_STRING,
124                                feOptSpec, &option_index))
125        != EOF)
126  {
127    switch(optc)
128    {
129      case 'h':
130          extern void feOptHelp(const char* name);
131
132          feOptHelp(feArgv0);
133          exit(0);
134          break;
135      case '?':
136      case ':':
137      case '\0':
138          mainUsage();
139          exit(1);
140
141      case  LONG_OPTION_RETURN:
142        {
143          switch(option_index)
144          {
145#ifdef TSINGULAR
146              case FE_OPT_XTERM:
147                emacs = fe_optarg;
148              break;
149#else
150              case FE_OPT_EMACS:
151                emacs = fe_optarg;
152                break;
153
154              case FE_OPT_EMACS_DIR:
155                emacs_dir = fe_optarg;
156                break;
157
158              case FE_OPT_EMACS_LOAD:
159                emacs_load = fe_optarg;
160                break;
161#endif
162              case FE_OPT_SINGULAR:
163                singular = fe_optarg;
164                break;
165
166              case FE_OPT_NO_CALL:
167                no_emacs_call = 1;
168                break;
169
170              case FE_OPT_DUMP_VERSIONTUPLE:
171                feOptDumpVersionTuple();
172                exit(0);
173                break;
174
175              default:
176                goto NEXT;
177          }
178          // delete options from option-list
179          if (fe_optind > 2 && *argv[fe_optind-1] != '-' &&
180              fe_optarg != NULL && feOptSpec[option_index].has_arg)
181          {
182            argv[fe_optind-2] = NULL;
183          }
184          argv[fe_optind-1] = NULL;
185        }
186    }
187    NEXT:{}
188  }
189
190  int i, length = 0;
191  char* syscall;
192  for (i=1; i<argc; i++)
193  {
194    if (argv[i] != NULL) length += strlen(argv[i]) + 3;
195  }
196
197#ifdef TSINGULAR
198  if (emacs == NULL) emacs = feResource('X', 0);
199  if (emacs == NULL)
200  {
201  #ifdef __CYGWIN__
202    error( "Error: Can't find rxvt program. \n Expected it at %s\n Specify alternative with --rxvt=PROGRAM option,\n or set RXVT environment variable to the name of the program to use as rxvt.\n",
203  #else
204    error( "Error: Can't find xterm program. \n Expected it at %s\n Specify alternative with --xterm=PROGRAM option,\n or set XTERM environment variable to the name of the program to use as xterm.\n",
205  #endif
206           feResourceDefault('X'));
207    mainUsage();
208    exit(1);
209  }
210
211  if (singular == NULL) singular = feResource("SingularXterm", 0);
212  if (singular == NULL)
213  {
214    error( "Error: Can't find singular executable.\n Expected it at %s\n Specify with --singular option,\n or set TSINGULAR_SINGULAR environment variable.\n",
215            feResourceDefault("SingularXterm"));
216    mainUsage();
217    exit(1);
218  }
219
220#ifdef __CYGWIN__
221#define EXTRA_XTERM_ARGS "+vb -sl 2000 -fb Courier-bold-12 -tn xterm -cr Red3"
222#else
223#define EXTRA_XTERM_ARGS ""
224#endif
225
226  size_t len=strlen(emacs) + strlen(singular) + length + 300;
227  syscall = (char*) omAlloc(len);
228  snprintf(syscall,len, "%s %s -e %s ", emacs, EXTRA_XTERM_ARGS, singular);
229
230  for (i=1; i<argc; i++)
231  {
232    if (argv[i] != NULL)
233    {
234      strcat(syscall, " ");
235      strcat(syscall, argv[i]);
236    }
237  }
238#else
239  // make sure  emacs, singular, emacs_dir, emacs_load are set
240  if (emacs == NULL) emacs = feResource("xemacs", 0);
241  if (emacs == NULL) emacs = feResource("emacs", 0);
242  if (emacs == NULL)
243  {
244    error( "Error: Can't find emacs or xemacs executable. \n Expected it at %s or %s\n Specify alternative with --emacs option,\n or set ESINGULAR_EMACS environment variable.\n",
245            feResourceDefault("emacs"), feResourceDefault("xemacs"));
246    mainUsage();
247    exit(1);
248  }
249
250  if (singular == NULL) singular = feResource("SingularEmacs", 0);
251  if (singular == NULL)
252  {
253    error( "Error: Can't find singular executable.\n Expected it at %s\n Specify with --singular option,\n or set ESINGULAR_SINGULAR environment variable.\n",
254            feResourceDefault("SingularEmacs"));
255    mainUsage();
256    exit(1);
257  }
258
259  if (emacs_dir == NULL) emacs_dir = feResource("EmacsDir", 0);
260  if (emacs_dir == NULL)
261  {
262    error( "Error: Can't find emacs directory for Singular lisp files. \n Expected it at %s\n Specify with --emacs-dir option,\n or set ESINGULAR_EMACS_DIR environment variable.\n",
263            feResourceDefault("EmacsDir"));
264    mainUsage();
265    exit(1);
266  }
267
268  if (emacs_load == NULL)
269  {
270    // look into env variable
271    emacs_load = getenv("ESINGULAR_EMACS_LOAD");
272    if (access(emacs_load, R_OK))
273    {
274      // look in home-dir
275      emacs_load = getenv("HOME");
276#ifdef __CYGWIN__
277      if ((emacs_load==NULL)||(!access(emacs_load,X_OK)))
278        emacs_load = getenv("SINGHOME");
279#endif
280      snprintf(cwd,MAXPATHLEN, "%s/.emacs-singular", emacs_load);
281      if (! access(cwd, R_OK))
282      {
283        emacs_load = omStrDup(cwd);
284      }
285      else
286      {
287        // try with resources
288        emacs_load = feResource("EmacsLoad", 0);
289        if (emacs_load == NULL)
290        {
291          error( "Error: Can't find emacs load file for Singular mode. \n Expected it at %s\n Specify with --emacs-load option,\n or set ESINGULAR_EMACS_LOAD environment variable,\n or put file '.emacs-singular' in your home directory.\n",
292                  feResourceDefault("EmacsLoad"));
293          mainUsage();
294          exit(1);
295        }
296      }
297    }
298  }
299
300  size_t len=strlen(emacs) + strlen(singular) + strlen(emacs_dir) + strlen(emacs_load) + length +300;
301  syscall = (char*) omAlloc(len);
302  const char* prefix = "--";
303  if (strstr(emacs, "xemacs") || strstr(emacs, "Xemacs") || strstr(emacs, "XEMACS"))
304    prefix = "-";
305  getcwd(cwd, MAXPATHLEN);
306  // append / at the end of cwd
307  if (cwd[strlen(cwd)-1] != '/') strcat(cwd, "/");
308
309  // Note: option -no-init-file should be equivalent to -q. Anyhow,
310  // xemacs-20.4 sometimes crashed on startup when using -q. DonŽt know why.
311  snprintf(syscall,len, "%s %sno-init-file %seval '(progn (setq singular-emacs-home-directory \"%s\") (load-file \"%s\") (singular-other \"%s\" \"%s\" (list ",
312          emacs, prefix, prefix, emacs_dir, emacs_load,
313          singular, cwd);
314
315
316  for (i=1; i<argc; i++)
317  {
318    if (argv[i] != NULL)
319    {
320      strcat(syscall, "\"");
321      strcat(syscall, argv[i]);
322      strcat(syscall, "\" ");
323    }
324  }
325  strcat(syscall, ") \"singular\"))'");
326#endif
327
328  if (no_emacs_call)
329  {
330    printf("%s\n", syscall);
331  }
332  else
333  {
334    if (system(syscall) != 0)
335    {
336      error( "Error: Execution of\n%s\n", syscall);
337      mainUsage();
338      exit(1);
339    }
340  }
341}
342
343
Note: See TracBrowser for help on using the repository browser.