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");