source: git/Singular/emacs.cc @ 8051aa

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