Mercurial > hg > xemacs-beta
comparison lib-src/ellcc.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | 11054d720c21 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
22 Please mail bugs and suggestions to the XEmacs maintainer. | 22 Please mail bugs and suggestions to the XEmacs maintainer. |
23 */ | 23 */ |
24 | 24 |
25 /* | 25 /* |
26 Here's the scoop. We would really like this to be a shell script, but | 26 Here's the scoop. We would really like this to be a shell script, but |
27 the various Windows platforms don't have reliable scripting that suits | 27 the various Windows platforms dont have reliable scripting that suits |
28 our needs. We don't want to rely on perl or some other such language | 28 our needs. We dont want to reply on perl or some other such language |
29 so we have to roll our own executable to act as a front-end for the | 29 so we have to roll our own executable to act as a front-end for the |
30 compiler. | 30 compiler. |
31 | 31 |
32 This program is used to invoke the compiler, the linker and to generate | 32 This program is used to invoke the compiler, the linker and to generate |
33 the module specific documentation and initialization code. We assume we | 33 the module specific documentation and initialization code. We assume we |
56 -o $@ $(SRCS) | 56 -o $@ $(SRCS) |
57 | 57 |
58 See the samples for more details. | 58 See the samples for more details. |
59 */ | 59 */ |
60 | 60 |
61 #include <config.h> | |
62 #include <stdio.h> | 61 #include <stdio.h> |
63 #include <stdlib.h> | 62 #include <stdlib.h> |
63 | |
64 #ifdef MSDOS | |
65 # include <fcntl.h> | |
66 # include <sys/param.h> | |
67 # include <io.h> | |
68 # ifndef HAVE_CONFIG_H | |
69 # define DOS_NT | |
70 # include <sys/config.h> | |
71 # endif | |
72 #endif /* MSDOS */ | |
73 | |
74 #ifdef WINDOWSNT | |
75 # include <stdlib.h> | |
76 # include <fcntl.h> | |
77 # include <string.h> | |
78 # include <io.h> | |
79 # define MAXPATHLEN _MAX_PATH | |
80 # ifdef HAVE_CONFIG_H | |
81 # undef HAVE_NTGUI | |
82 # else | |
83 # define DOS_NT | |
84 # define HAVE_GETCWD | |
85 # endif /* not HAVE_CONFIG_H */ | |
86 #endif /* WINDOWSNT */ | |
87 | |
88 #ifdef HAVE_CONFIG_H | |
89 # include <config.h> | |
90 /* On some systems, Emacs defines static as nothing for the sake | |
91 of unexec. We don't want that here since we don't use unexec. */ | |
92 # undef static | |
93 #endif /* HAVE_CONFIG_H */ | |
94 | |
95 #if !defined (WINDOWSNT) && defined (STDC_HEADERS) | |
96 #include <stdlib.h> | |
64 #include <string.h> | 97 #include <string.h> |
98 #endif | |
99 | |
100 #ifdef HAVE_UNISTD_H | |
101 # include <unistd.h> | |
102 #else | |
103 # ifdef HAVE_GETCWD | |
104 extern char *getcwd (); | |
105 # endif | |
106 #endif /* HAVE_UNISTD_H */ | |
107 | |
108 #include <stdio.h> | |
65 #include <ctype.h> | 109 #include <ctype.h> |
66 #include <errno.h> | 110 #include <errno.h> |
111 #ifndef errno | |
112 extern int errno; | |
113 #endif | |
67 #include <sys/types.h> | 114 #include <sys/types.h> |
68 | 115 #include <sys/stat.h> |
69 #ifdef HAVE_UNISTD_H | |
70 # include <unistd.h> | |
71 #endif /* HAVE_UNISTD_H */ | |
72 | 116 |
73 #define EMODULES_GATHER_VERSION | 117 #define EMODULES_GATHER_VERSION |
74 | 118 #include "emodules.h" |
75 #include <emodules.h> | 119 #include "ellcc.h" |
76 #include <ellcc.h> /* Generated files must be included using <...> */ | 120 |
121 #if !defined (S_ISREG) && defined (S_IFREG) | |
122 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | |
123 #endif | |
124 | |
125 /* Exit codes for success and failure. */ | |
126 #ifdef VMS | |
127 # define GOOD 1 | |
128 # define BAD 0 | |
129 #else | |
130 # define GOOD 0 | |
131 # define BAD 1 | |
132 #endif | |
77 | 133 |
78 #define DEBUG | 134 #define DEBUG |
79 | 135 |
80 #ifndef HAVE_SHLIB | 136 #ifndef HAVE_SHLIB |
81 int | 137 int |
82 main (int argc, char *argv[]) | 138 main() |
83 { | 139 { |
84 fprintf (stderr, "Dynamic modules not supported on this platform\n"); | 140 fprintf (stderr, "Dynamic modules not supported on this platform\n"); |
85 return EXIT_FAILURE; | 141 return (BAD); |
86 } | 142 } |
87 #else | 143 #else |
88 | 144 |
89 /* | 145 /* |
90 * Try to figure out the commands we need to use to create shared objects, | 146 * Try to figure out the commands we need to use to create shared objects, |
105 (op), (n) * sizeof (Type))) | 161 (op), (n) * sizeof (Type))) |
106 #else | 162 #else |
107 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) | 163 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) |
108 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type))) | 164 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type))) |
109 #endif | 165 #endif |
110 static void *xmalloc (size_t); | 166 long *xmalloc (), *xrealloc (); |
111 static void fatal (char *, char *); | 167 void fatal (), pfatal (); |
112 static void add_to_argv (const char *); | 168 char *ellcc_strchr (), *ellcc_strrchr (); |
113 static void do_compile_mode (void); | 169 void add_to_argv (); |
114 static void do_link_mode (void); | 170 void do_compile_mode(), do_link_mode(), do_init_mode(); |
115 static void do_init_mode (void); | |
116 | 171 |
117 #define SSTR(S) ((S)?(S):"") | 172 #define SSTR(S) ((S)?(S):"") |
118 | 173 |
119 #define ELLCC_COMPILE_MODE 0 | 174 #define ELLCC_COMPILE_MODE 0 |
120 #define ELLCC_LINK_MODE 1 | 175 #define ELLCC_LINK_MODE 1 |
139 STR = getenv(EVAR); \ | 194 STR = getenv(EVAR); \ |
140 if ((STR) == (char *)0) \ | 195 if ((STR) == (char *)0) \ |
141 STR = DFLT | 196 STR = DFLT |
142 | 197 |
143 int | 198 int |
144 main (int argc, char *argv[]) | 199 main (argc, argv) |
200 int argc; | |
201 char *argv[]; | |
145 { | 202 { |
146 char *tmp; | 203 char *tmp; |
147 int i, done_mode = 0; | 204 int i, done_mode = 0; |
148 | 205 |
149 prog_argc = argc; | 206 prog_argc = argc; |
150 prog_argv = argv; | 207 prog_argv = argv; |
151 | 208 |
152 #if defined(WIN32_NATIVE) | 209 #if defined(MSDOS) || defined(WINDOWSNT) |
153 tmp = strrchr (argv[0], '\\'); | 210 tmp = ellcc_strrchr (argv[0], '\\'); |
154 if (tmp != (char *)0) | 211 if (tmp != (char *)0) |
155 tmp++; | 212 tmp++; |
156 #elif !defined (VMS) | 213 #elif !defined (VMS) |
157 tmp = strrchr (argv[0], '/'); | 214 tmp = ellcc_strrchr (argv[0], '/'); |
158 if (tmp != (char *)0) | 215 if (tmp != (char *)0) |
159 tmp++; | 216 tmp++; |
160 #else | 217 #else |
161 tmp = argv[0]; | 218 tmp = argv[0]; |
162 #endif | 219 #endif |
189 if (strncmp (argv[i], "--mode=", 7) == 0) | 246 if (strncmp (argv[i], "--mode=", 7) == 0) |
190 { | 247 { |
191 char *modeopt = argv[i] + 7; | 248 char *modeopt = argv[i] + 7; |
192 | 249 |
193 if (done_mode && strcmp (modeopt, "verbose")) | 250 if (done_mode && strcmp (modeopt, "verbose")) |
194 fatal ("more than one mode specified", (char *) 0); | 251 fatal ("more than one mode specified"); |
195 if (strcmp (modeopt, "link") == 0) | 252 if (strcmp (modeopt, "link") == 0) |
196 { | 253 { |
197 done_mode++; | 254 done_mode++; |
198 ellcc_mode = ELLCC_LINK_MODE; | 255 ellcc_mode = ELLCC_LINK_MODE; |
199 } | 256 } |
228 else if (strcmp (argv[i], "--mod-config") == 0) | 285 else if (strcmp (argv[i], "--mod-config") == 0) |
229 { | 286 { |
230 printf ("%s\n", ELLCC_CONFIG); | 287 printf ("%s\n", ELLCC_CONFIG); |
231 return 0; | 288 return 0; |
232 } | 289 } |
233 else if (strncmp (argv[i], "--mod-name=", 11) == 0) | 290 else if (strncmp (argv[i], "--mod-name=", 10) == 0) |
234 mod_name = argv[i] + 11; | 291 mod_name = argv[i] + 11; |
235 else if (strncmp (argv[i], "--mod-title=", 12) == 0) | 292 else if (strncmp (argv[i], "--mod-title=", 11) == 0) |
236 mod_title = argv[i] + 12; | 293 mod_title = argv[i] + 12; |
237 else if (strncmp (argv[i], "--mod-version=", 14) == 0) | 294 else if (strncmp (argv[i], "--mod-version=", 13) == 0) |
238 mod_version = argv[i] + 14; | 295 mod_version = argv[i] + 14; |
239 else if (strncmp (argv[i], "--mod-output=", 13) == 0) | 296 else if (strncmp (argv[i], "--mod-output=", 12) == 0) |
240 mod_output = argv[i] + 13; | 297 mod_output = argv[i] + 13; |
241 else | 298 else |
242 { | 299 { |
243 exec_args[exec_argc] = i; | 300 exec_args[exec_argc] = i; |
244 exec_argc++; | 301 exec_argc++; |
280 printf ("\n"); | 337 printf ("\n"); |
281 } | 338 } |
282 #endif | 339 #endif |
283 | 340 |
284 if (exec_argc < 2) | 341 if (exec_argc < 2) |
285 fatal ("too few arguments", (char *) 0); | 342 fatal ("too few arguments"); |
286 | 343 |
287 /* | 344 /* |
288 * Get the over-rides from the environment | 345 * Get the over-rides from the environment |
289 */ | 346 */ |
290 OVERENV(ellcc, "ELLCC", ELLCC_CC); | 347 OVERENV(ellcc, "ELLCC", ELLCC_CC); |
319 printf ("%s exited with status %d\n", exec_argv[0], i); | 376 printf ("%s exited with status %d\n", exec_argv[0], i); |
320 return i; | 377 return i; |
321 } | 378 } |
322 | 379 |
323 /* Like malloc but get fatal error if memory is exhausted. */ | 380 /* Like malloc but get fatal error if memory is exhausted. */ |
324 static void * | 381 long * |
325 xmalloc (size_t size) | 382 xmalloc (size) |
326 { | 383 unsigned int size; |
327 void *result = malloc (size); | 384 { |
385 long *result = (long *) malloc (size); | |
328 if (result == NULL) | 386 if (result == NULL) |
329 fatal ("virtual memory exhausted", (char *)0); | 387 fatal ("virtual memory exhausted", (char *)NULL); |
330 return result; | 388 return result; |
331 } | 389 } |
332 | 390 |
391 long * | |
392 xrealloc (ptr, size) | |
393 char *ptr; | |
394 unsigned int size; | |
395 { | |
396 long *result = (long *) realloc (ptr, size); | |
397 if (result == NULL) | |
398 fatal ("virtual memory exhausted", (char *)NULL); | |
399 return result; | |
400 } | |
401 | |
333 /* Print error message and exit. */ | 402 /* Print error message and exit. */ |
334 static void | 403 void |
335 fatal (char *s1, char *s2) | 404 fatal (s1, s2) |
405 char *s1, *s2; | |
336 { | 406 { |
337 fprintf (stderr, "%s: ", progname); | 407 fprintf (stderr, "%s: ", progname); |
338 fprintf (stderr, s1, s2); | 408 fprintf (stderr, s1, s2); |
339 fprintf (stderr, "\n"); | 409 fprintf (stderr, "\n"); |
340 exit (EXIT_FAILURE); | 410 exit (BAD); |
411 } | |
412 | |
413 void | |
414 pfatal (s1) | |
415 char *s1; | |
416 { | |
417 perror (s1); | |
418 exit (BAD); | |
419 } | |
420 | |
421 /* | |
422 * Return the ptr in sp at which the character c last | |
423 * appears; NULL if not found | |
424 * | |
425 * Identical to System V strrchr, included for portability. | |
426 */ | |
427 char * | |
428 ellcc_strrchr (sp, c) | |
429 register char *sp, c; | |
430 { | |
431 register char *r; | |
432 | |
433 r = NULL; | |
434 do | |
435 { | |
436 if (*sp == c) | |
437 r = sp; | |
438 } while (*sp++); | |
439 return r; | |
440 } | |
441 | |
442 /* | |
443 * Return the ptr in sp at which the character c first | |
444 * appears; NULL if not found | |
445 * | |
446 * Identical to System V strchr, included for portability. | |
447 */ | |
448 char * | |
449 ellcc_strchr (sp, c) | |
450 register char *sp, c; | |
451 { | |
452 do | |
453 { | |
454 if (*sp == c) | |
455 return sp; | |
456 } while (*sp++); | |
457 return NULL; | |
341 } | 458 } |
342 | 459 |
343 /* | 460 /* |
344 * Add a string to the argument vector list that will be passed on down | 461 * Add a string to the argument vector list that will be passed on down |
345 * to the compiler or linker. We need to split individual words into | 462 * to the compiler or linker. We need to split individual words into |
346 * arguments, taking quoting into account. This can get ugly. | 463 * arguments, taking quoting into account. This can get ugly. |
347 */ | 464 */ |
348 static void | 465 void |
349 add_to_argv (const char *str) | 466 add_to_argv (str) |
467 CONST char *str; | |
350 { | 468 { |
351 int sm = 0; | 469 int sm = 0; |
352 const char *s = (const char *)0; | 470 CONST char *s = (CONST char *)0; |
353 | 471 |
354 if ((str == (const char *)0) || (str[0] == '\0')) | 472 if ((str == (CONST char *)0) || (str[0] == '\0')) |
355 return; | 473 return; |
356 | 474 |
357 while (*str) | 475 while (*str) |
358 { | 476 { |
359 switch (sm) | 477 switch (sm) |
360 { | 478 { |
361 case 0: /* Start of case - string leading whitespace */ | 479 case 0: /* Start of case - string leading whitespace */ |
362 if (isspace ((unsigned char) *str)) | 480 if (isspace (*str)) |
363 str++; | 481 str++; |
364 else | 482 else |
365 { | 483 { |
366 sm = 1; /* Change state to non-whitespace */ | 484 sm = 1; /* Change state to non-whitespace */ |
367 s = str; /* Mark the start of THIS argument */ | 485 s = str; /* Mark the start of THIS argument */ |
368 } | 486 } |
369 break; | 487 break; |
370 | 488 |
371 case 1: /* Non-whitespace character. Mark the start */ | 489 case 1: /* Non-whitespace character. Mark the start */ |
372 if (isspace ((unsigned char) *str)) | 490 if (isspace (*str)) |
373 { | 491 { |
374 /* Reached the end of the argument. Add it. */ | 492 /* Reached the end of the argument. Add it. */ |
375 int l = str-s; | 493 int l = str-s; |
376 exec_argv[real_argc] = xnew (l+2, char); | 494 exec_argv[real_argc] = xnew (l+2, char); |
377 strncpy (exec_argv[real_argc], s, l); | 495 strncpy (exec_argv[real_argc], s, l); |
378 exec_argv[real_argc][l] = '\0'; | 496 exec_argv[real_argc][l] = '\0'; |
379 real_argc++; | 497 real_argc++; |
380 sm = 0; /* Back to start state */ | 498 sm = 0; /* Back to start state */ |
381 s = (const char *)0; | 499 s = (CONST char *)0; |
382 break; | 500 break; |
383 } | 501 } |
384 else if (*str == '\\') | 502 else if (*str == '\\') |
385 { | 503 { |
386 sm = 2; /* Escaped character */ | 504 sm = 2; /* Escaped character */ |
421 str++; | 539 str++; |
422 break; | 540 break; |
423 } | 541 } |
424 } | 542 } |
425 | 543 |
426 if (s != (const char *)0) | 544 if (s != (CONST char *)0) |
427 { | 545 { |
428 int l = str-s; | 546 int l = str-s; |
429 exec_argv[real_argc] = xnew (l+2, char); | 547 exec_argv[real_argc] = xnew (l+2, char); |
430 strncpy (exec_argv[real_argc], s, l); | 548 strncpy (exec_argv[real_argc], s, l); |
431 exec_argv[real_argc][l] = '\0'; | 549 exec_argv[real_argc][l] = '\0'; |
432 real_argc++; | 550 real_argc++; |
433 s = (const char *)0; | 551 s = (CONST char *)0; |
434 } | 552 } |
435 } | 553 } |
436 | 554 |
437 /* | 555 /* |
438 * For compile mode, things are pretty straight forward. All we need to do | 556 * For compile mode, things are pretty straight forward. All we need to do |
439 * is build up the argument vector and exec() it. We must just make sure | 557 * is build up the argument vector and exec() it. We must just make sure |
440 * that we get all of the required arguments in place. | 558 * that we get all of the required arguments in place. |
441 */ | 559 */ |
442 static void | 560 void |
443 do_compile_mode (void) | 561 do_compile_mode() |
444 { | 562 { |
445 int i; | 563 int i; |
446 char ts[4096]; /* Plenty big enough */ | 564 char ts[4096]; /* Plenty big enough */ |
447 | 565 |
448 add_to_argv (ellcc); | 566 add_to_argv (ellcc); |
467 * insert the linker commands first, replace any occurrence of ELLSONAME | 585 * insert the linker commands first, replace any occurrence of ELLSONAME |
468 * with the desired output file name, insert the output arguments, then | 586 * with the desired output file name, insert the output arguments, then |
469 * all of the provided arguments, then the final post arguments. Once | 587 * all of the provided arguments, then the final post arguments. Once |
470 * all of this has been done, the argument vector is ready to run. | 588 * all of this has been done, the argument vector is ready to run. |
471 */ | 589 */ |
472 static void | 590 void |
473 do_link_mode (void) | 591 do_link_mode() |
474 { | 592 { |
475 int i,x; | 593 int i,x; |
476 char *t, ts[4096]; /* Plenty big enough */ | 594 char *t, ts[4096]; /* Plenty big enough */ |
477 | 595 |
478 add_to_argv (ellld); | 596 add_to_argv (ellld); |
528 * passed on the command line are the names of source files which the | 646 * passed on the command line are the names of source files which the |
529 * make-doc program will be processing. We prepare the output file with | 647 * make-doc program will be processing. We prepare the output file with |
530 * the header information first, as make-doc will append to the file by | 648 * the header information first, as make-doc will append to the file by |
531 * special dispensation. | 649 * special dispensation. |
532 */ | 650 */ |
533 static void | 651 void |
534 do_init_mode (void) | 652 do_init_mode() |
535 { | 653 { |
536 int i; | 654 int i; |
537 char ts[4096]; /* Plenty big enough */ | 655 char ts[4096]; /* Plenty big enough */ |
538 char *mdocprog; | 656 char *mdocprog; |
539 FILE *mout = fopen (mod_output, "w"); | 657 FILE *mout = fopen (mod_output, "w"); |