comparison lib-src/ellcc.c @ 398:74fd4e045ea6 r21-2-29

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