1 /* $Id: cim.c,v 1.18 1997/01/26 14:30:21 cim Exp $ */
2 
3 /* Copyright (C) 1987-1998 Sverre Hvammen Johansen,
4  * Department of Informatics, University of Oslo.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 
19 /* Main for kompilatoren. */
20 
21 #include <stdio.h>
22 #include "const.h"
23 #include "name.h"
24 #include "filelist.h"
25 #include "newstr.h"
26 #include "cimcomp.h"
27 #include "error.h"
28 #include "lex.h"
29 #include "mellbuilder.h"
30 #include "checker.h"
31 #include "gen.h"
32 #include "trans.h"
33 
34 #if STDC_HEADERS || HAVE_STRING_H
35 #include <string.h>
36 #else /* not STDC_HEADERS and not HAVE_STRING_H */
37 #include <strings.h>
38 #endif /* not STDC_HEADERS and not HAVE_STRING_H */
39 
40 #if HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43 
44 #if STDC_HEADERS
45 #include <stdlib.h>
46 #endif
47 
48 #if HAVE_SIGNAL_H
49 #include <signal.h>
50 #endif
51 
52 #include "getopt.h"
53 
54 struct SENT *mainSent;
55 
56 FILE *ccode;
57 
58 char *extcodename;
59 char *mifcodename;
60 
61 static char *outputname = "";
62 static char *exekname;
63 static char *sourcename;
64 static char *listname;
65 static char *ccodename;
66 static char *ocodename;
67 static char *shlname;
68 
69 static char *ccomp;
70 
71 static char *ccompargs = "";
72 static char *linkargs = "";
73 static char *systemlibdir = LIBDIR;
74 static char *tmpdir;
75 char *includedir = INCLUDEDIR;
76 
77 int option_write_tokens;
78 int option_write_mif;
79 int option_nowarning;
80 int option_atr;
81 int option_line;
82 int option_reuse_timestamp;
83 int option_verbose;
84 int option_init_poolsize;
85 int option_dyn_poolsize;
86 int option_max_poolsize;
87 int option_bl_in_dir_line;
88 
89 static int option_static;
90 static int option_pic;
91 static int option_checkdiff;
92 static int option_nolink;
93 static int option_nosim;
94 static int option_nocc;
95 static int option_checkdif;
96 static int option_notempdel;
97 static int option_noexecdel;
98 static int option_quiet;
99 static int option_sscheck;
100 #ifdef DEBUG
101 static int option_lex,
102 static int option_gen_test;
103 static int option_declarations;
104 static int option_expressions;
105 static int option_msymbols;
106 static int option_input;
107 #endif
108 
109 #ifdef DEBUG
110 static int s_out;
111 #endif
112 char separat_comp;		/* Sier om kj|ringen er en separat
113 				 * kompilering eller ikke */
114 
115 char *progname;
116 
117 /******************************************************************************
118                                                                      XMALLOC */
119 
120 char *
xmalloc(size)121 xmalloc (size)
122      unsigned int size;
123 {
124   char *ptr = malloc (size);
125   if (! ptr)
126     {
127       fprintf (stderr, "%s: virtual memory exhausted\n", progname);
128       exit (1);
129     }
130   return ptr;
131 }
132 
133 /******************************************************************************
134                                                                TRAP-ROUTINES */
135 #if HAVE_SIGFPE
136 static RETSIGTYPE
float_trap()137 float_trap ()
138 {
139   lerror (25);
140 }
141 #endif
142 
143 #if HAVE_SIGSEGV
144 static RETSIGTYPE
seg_trap()145 seg_trap ()
146 {
147   lerror (26);
148 }
149 #endif
150 
151 #if HAVE_SIGILL
152 static RETSIGTYPE
illegal_trap()153 illegal_trap ()
154 {
155   lerror (28);
156 }
157 #endif
158 
159 #if HAVE_SIGTRAP
160 static RETSIGTYPE
trace_trap()161 trace_trap ()
162 {
163   lerror (29);
164 }
165 #endif
166 
167 #if HAVE_SIGBUS
168 static RETSIGTYPE
bus_trap()169 bus_trap ()
170 {
171   lerror (27);
172 }
173 #endif
174 
175 #if HAVE_SIGSYS
176 static RETSIGTYPE
sys_trap()177 sys_trap ()
178 {
179   lerror (30);
180 }
181 #endif
182 
init_trap_routines()183 static init_trap_routines()
184 {
185 #if HAVE_SIGFPE
186   signal (SIGFPE, float_trap);
187 #endif
188 #if HAVE_SIGSEGV
189   signal (SIGSEGV, seg_trap);
190 #endif
191 #if HAVE_SIGILL
192   signal (SIGILL, illegal_trap);
193 #endif
194 #if HAVE_SIGTRAP
195   signal (SIGTRAP, trace_trap);
196 #endif
197 #if HAVE_SIGSYS
198   signal (SIGSYS, sys_trap);
199 #endif
200 #if HAVE_SIGBUS
201   signal (SIGBUS, bus_trap);
202 #endif
203 }
204 
205 /******************************************************************************
206                                                                  GET_ALL_ENV */
207 
208 #if HAVE_GETENV
209 extern char *getenv ();
xgetenv(name,var)210 static xgetenv (name, var)
211      char *name;
212      char **var;
213 {
214   char *value;
215   value = getenv (name);
216   if (value != NULL)
217     *var = newstrcat1 (value);
218 }
219 #endif
220 
get_all_env()221 static get_all_env()
222 {
223 #if HAVE_GETENV
224   xgetenv ("CIMLIBDIR", &systemlibdir);
225   xgetenv ("CIMINCLUDEDIR", &includedir);
226   xgetenv ("TMPDIR", &tmpdir);
227   xgetenv ("CIMTMPDIR", &tmpdir);
228 #endif
229 }
230 
231 /******************************************************************************
232                                                                      SIMCOMP */
simcomp()233 static simcomp ()
234 {
235   mbuilderInit();
236 
237   if (initLex (sourcename)) return (TRUE);
238   if (option_write_tokens)
239     {
240       scan_and_write_tokens ();
241       return (FALSE);
242     }
243 #ifdef DEBUG
244   if (option_declarations || option_expressions
245       || option_msymbols || option_input || option_lex)
246     {
247       s_out = dup (stdout->_file);
248       if (freopen (listname, "w", stdout) == NULL)
249 	{
250 	  perror (newstrcat3 (progname, ": ", listname));
251 	  return (TRUE);
252 	}
253     }
254 #endif
255   if ((ccode = fopen (ccodename, "w")) == NULL)
256     {
257       perror (newstrcat3 (progname, ": ", ccodename));
258       return (TRUE);
259     }
260   if (!option_quiet)
261     fprintf (stderr, "Compiling %s:\n", sourcename);
262 
263   /* PASS 1 */
264 
265   initExtspec ();
266   init_parser ();
267   initDecl ();
268   yyparse ();
269 
270   /* PASS 2 AV KOMPILATOREN */
271 
272   if (anterror == 0)
273     {
274       mbuilderReinit();
275       ebuilderInit();
276       sbuilderInit();
277       mainSent= sbuild();
278       reinit ();
279       expCheckerInit ();
280       genInit ();
281       sentCheck (mainSent, TRUE);
282       if (anterror == 0)
283 	{
284 	  sentTrans (mainSent);
285 	  sentGen (mainSent);
286 	}
287       if (separat_comp && (anterror == 0 || option_atr))
288 	write_all_ext ();
289 #ifdef DEBUG
290       if (option_declarations)
291 	dump ();
292 #endif
293     }
294   fclose (ccode);
295 #ifdef DEBUG
296   if (option_declarations || option_expressions
297       || option_msymbols || option_input || option_lex)
298     {
299       fclose (stdout);
300       fdopen (s_out, "w");
301       dup2 (s_out, fileno (stdout));
302     }
303 #endif
304   if (anterror != 0)
305     return (TRUE);
306   else
307     return (FALSE);
308 }
309 
310 /******************************************************************************
311                                                                STRINGTOUPPER */
312 
313 static char *
stringtoupper(s)314 stringtoupper (s)
315      char *s;
316 {
317   char *st;
318   for (st = s; *st != '\0'; st++)
319     if (*st >= 'a' && *st <= 'z')
320       *st = *st - (char) 32;
321   return (s);
322 }
323 
324 /******************************************************************************
325                                                                     BASENAME */
326 static char *
basename(str)327 basename (str) char *str;
328 {
329   int i,j;
330   for (i = strlen (str) - 2; i >= 0; i--)
331     if (!strncmp (&str[i], "/", 1))
332       {
333 	str= &str[i + 1];
334 	break;
335       }
336   str= newstrcat1 (str);
337   i= strlen (str);
338   if (i > 4 && !(strcmp (&str[i - 4], ".sim")
339 		 && strcmp (&str[i - 4], ".SIM")
340 		 && strcmp (&str[i - 4], ".cim")
341 		 && strcmp (&str[i - 4], ".CIM")))
342     str[i - 4] = '\0';
343 
344   return str;
345 }
346 
347 /******************************************************************************
348                                                                   PRINT_HELP */
349 
print_help(status)350 static int print_help(status)int status;
351 {
352   fprintf(stderr,"Usage: %s"
353 	  " [-a] [--atr]"
354 	  " [-b flags] [--cflags=flags]"
355 	  "\n      "
356 	  " [-B flags] [--ldflags=flags]"
357           " [-c] [--suppress-linking]"
358 	  "\n      "
359 	  " [-d] [--compare]"
360 	  " [-D NAME] [--define=NAME]"
361 	  " [-e] [--static]"
362 	  "\n      "
363 	  " [-E] [--preprocess]"
364 	  " [-F] [--write-mif]"
365 	  " [-g] [--debug]"
366 	  "\n      "
367 	  " [-G] [--gcc]"
368 	  " [-I DIR] [--includedir=DIR]"
369 	  " [-h] [--help]"
370 	  "\n      "
371 	  " [-H] [--no-lines]"
372 	  " [-l LIBRARY] [--library=LIBRARY]"
373 	  "\n      "
374 	  " [-L DIR] [--library-dir=DIR]"
375 	  " [-m [N]] [--memory-pool-size[=N]]"
376 	  "\n      "
377 	  " [-M N] [--max-memory-pool-size=N]"
378 	  " [-N FILE] [--input=FILE]"
379 	  "\n      "
380 	  " [-o FILE] [--output=FILE]"
381 	  " [-O] [-ON]"
382 	  " [--optimize] [--optimize=N]"
383 	  "\n      "
384 	  " [-p] [--pic]"
385 	  " [-P] [--only-link]"
386 	  " [-q] [--quiet]"
387 	  "\n      "
388 	  " [-R] [--preserve-timestamp]"
389 	  " [--silent]"
390 	  " [-s] [--no-simula-compile]"
391 	  "\n      "
392 	  " [-S] [--only-simula-compile]"
393 	  " [-t] [--dont-remove-temporaries]"
394 	  "\n      "
395 	  " [-U NAME] [--undefine=NAME]"
396 	  " [-v] [--verbose]"
397 	  " [-V] [--version]"
398 	  "\n      "
399 	  " [-w] [--no-warn]"
400 	  " simula-file [file...]\n", progname);
401   exit(status);
402 }
403 
404 /******************************************************************************
405                                                                 PARSEOPTIONS */
parseoptions(argc,argv)406 static parseoptions (argc, argv)
407      int argc;
408      char *argv[];
409 {
410   int c;
411   int index;
412   while (1)
413     {
414       int option_index = 0;
415       static struct option long_options[] =
416 	{
417 	  {"atr", 0, 0, 'a'},
418 	  {"cflags=", 1, 0, 'b'},
419 	  {"ldflags", 1, 0, 'B'},
420 	  {"suppress-linking", 0, 0, 'c'},
421 	  {"c-compiler", 1, 0, 'C'},
422 	  {"compare", 0, 0, 'd'},
423 	  {"define", 1, 0, 'D'},
424 	  {"static", 0, 0, 'e'},
425 	  {"preprocess", 0, 0, 'E'},
426 	  {"write-mif", 0, 0, 'F'},
427 	  {"debug", 0, 0, 'g'},
428 	  {"gcc", 0, 0, 'G'},
429 	  {"include-dir", 1, 0, 'I'},
430 	  {"help", 0, 0, 'h'},
431 	  {"no-lines", 0, 0, 'H'},
432 	  {"library", 1, 0, 'l'},
433 	  {"library-dir", 2, 0, 'L'},
434 	  {"memory-pool-size", 2, 0, 'm'},
435 	  {"max-memory-pool-size", 1, 0, 'M'},
436 	  {"input", 1, 0, 'N'},
437 	  {"output", 1, 0, 'o'},
438 	  {"optimize", 2, 0, 'O'},
439 	  {"pic", 0, 0, 'p'},
440 	  {"only-link", 0, 0, 'P'},
441 	  {"quiet", 0, 0, 'q'},
442 	  {"silent", 0, 0, 'q'},
443 	  {"preserve-timestamp", 0, 0, 'R'},
444 	  {"no-simula-compile", 0, 0, 's'},
445 	  {"only-simula-compile", 0, 0, 'S'},
446 	  {"dont-remove-temporaries", 0, 0, 't'},
447 	  {"undefine", 1, 0, 'U'},
448 	  {"verbose", 0, 0, 'v'},
449 	  {"version", 0, 0, 'V'},
450 	  {"no-warn", 0, 0, 'w'},
451 #ifdef DEBUG
452 	  {"dd", 0, &option_declarations, 1},
453 	  {"de", 0, &option_expressions, 1},
454 	  {"dm", 0, &option_msymbols, 1},
455 	  {"di", 0, &option_input, 1},
456 	  {"dl", 0, &option_lex, 1},
457 	  {"dg", 0, &option_gen, 1},
458 #endif
459 	  {"oc", 1, 0, 'b'},
460 	  {"ol", 1, 0, 'B'},
461 	  {0, 0, 0, 0}
462 	};
463 
464       c = getopt_long_only (argc, argv, "ab:B:cC:edD:EFgGI:hHl:L::m::M:o:O::pP"
465 			    "qRsStTU:vVw", long_options, &option_index);
466 
467       if (c == EOF) break;
468 
469       switch (c)
470 	{
471      	case 0:
472      	  /* If this option set a flag, do nothing else now.   */
473      	  break;
474      	case 'a':
475 	  option_atr = TRUE;
476 	  option_checkdiff = TRUE;
477 	  option_reuse_timestamp = TRUE;
478 	  break;
479 	case 'b':
480 	  ccompargs = newstrcat3 (ccompargs, optarg, " ");
481 	  break;
482 	case 'B':
483 	  linkargs = newstrcat3 (linkargs, optarg, " ");
484 	  break;
485 	case 'c':
486 	  if (option_nolink || option_nocc)
487 	    {
488 	      fprintf (stderr, "%s: Option -c: Specified twise or "
489 		       "in combination with -S or -C\n", progname);
490 	      print_help (1);
491 	    }
492 	  option_nolink = TRUE;
493 	  break;
494 	case 'C':
495 	  ccomp = newstrcat1 (optarg);
496 	  break;
497 	case 'd':
498 	  option_checkdiff = TRUE;
499 	  option_reuse_timestamp = TRUE;
500 	  break;
501 	case 'D':
502 	  defineName (tag (stringtoupper (optarg)), TRUE);
503 	  break;
504 	case 'e':
505 	  option_static = TRUE;
506 	  break;
507 	case 'E':
508 	  option_write_tokens = TRUE;
509 	  break;
510 	case 'F':
511 	  option_write_mif = TRUE;
512 	  break;
513 	case 'g':
514 	  break;
515 	case 'G':
516 	  ccomp = "gcc -g -O2";
517 	  break;
518 	case 'h':
519 	  print_help(0);
520 	  break;
521 	case 'H':
522 	  option_line = TRUE;
523 	  break;
524 	case 'I':
525 	  includedir = newstrcat1 (optarg);
526 	  break;
527 	case 'l':
528 	  new_lib (optarg);
529 	  break;
530 	case 'L':
531 	  insert_name_in_dirlist (optarg);
532 	  break;
533 	case 'm':
534 	  if (optarg)
535 	    {
536 	      sscanf (optarg, "%d", &option_init_poolsize);
537 	      option_init_poolsize *= 1024;
538 	    } else
539 	      {
540 		option_dyn_poolsize = TRUE;
541 	      }
542 	  break;
543 	case 'M':
544 	  sscanf (optarg, "%d", &option_max_poolsize);
545 	  option_max_poolsize *= 1024;
546 	  break;
547 	case 'N':
548 	  if (sourcename != NULL)
549 	    {
550 	      fprintf (stderr, "%s: More than one simula-file "
551 		       "are specified\n", progname);
552 	      print_help (1);
553 	    };
554 	  sourcename = newstrcat1 (optarg);
555 	  break;
556 	case 'o':
557 	  outputname = newstrcat1 (optarg);
558 	  break;
559 	case 'O':
560 	  if (!optarg) optarg="";
561 	  ccompargs = newstrcat4 (ccompargs, "-O", optarg, " ");
562 	  break;
563 	case 'p':
564 	  option_pic = TRUE;
565 	  break;
566 	case 'P':
567 	  if (option_nolink || option_nocc || option_nosim)
568 	    {
569 	      fprintf (stderr, "%s: Option -C: Specified twise or "
570 		       "in combination with -s, -c or -S\n", progname);
571 	      print_help (1);
572 	    }
573 	  option_nocc = option_nosim = TRUE;
574 	  break;
575 	case 'q':
576 	  option_quiet = TRUE;
577 	  option_verbose = FALSE;
578 	  break;
579 	case 'R':
580 	  option_reuse_timestamp = TRUE;
581 	  break;
582 	case 's':
583 	  if (option_nocc || option_nosim)
584 	    {
585 	      fprintf (stderr, "%s: Option -s: Specified twise or in "
586 		       "combination with -S or -C\n", progname);
587 	      print_help (1);
588 	    }
589 	  option_nosim = TRUE;
590 	  break;
591 	case 'S':
592 	  if (option_nolink || option_nocc || option_nosim)
593 	    {
594 	      fprintf (stderr, "%s: Option -S: Specified twise or "
595 		       "in combination with -s, -c or -C\n", progname);
596 	      print_help (1);
597 	    }
598 	  option_nolink = option_nocc = TRUE;
599 	  break;
600 	case 't':
601 	  option_notempdel = TRUE;
602 	  break;
603 	case 'u':
604 	  option_bl_in_dir_line = TRUE;
605 	  break;
606 	case 'U':
607 	  defineName (tag (stringtoupper (optarg)), FALSE);
608 	  break;
609 	case 'v':
610 	  option_verbose = TRUE;
611           option_quiet = FALSE;
612 	  break;
613 	case 'V':
614 	  printf ("%s-%s\n", PACKAGE_VERSION, SYSTEM_TYPE);
615 	  exit (0);
616 	  break;
617 	case 'w':
618 	  option_nowarning = TRUE;
619 	  break;
620 	case '?':
621 	  return (TRUE);
622 	  break;
623 	}
624     }
625   for (index = optind; index < argc; index++)
626     {
627       int l = strlen (argv[index]);
628       if (l >= 6 && !strcmp (&argv[index][l - 6], "-atr.a"))
629 	{
630 	  insert_name_in_archlist (argv[index]);
631 	  insert_name_in_linklist (transform_name (argv[index], "-atr.a", ".a"), FALSE);
632 	} else
633       if (l >= 2 && !strcmp (&argv[index][l - 2], ".a"))
634 	{
635 	  insert_name_in_archlist (transform_name (argv[index], ".a", "-atr.a"));
636 	  insert_name_in_linklist (argv[index], FALSE);
637 	}
638       else if (l >= 2 && !strcmp (&argv[index][l - 2], ".o"))
639 	{
640 	  insert_name_in_linklist (argv[index], FALSE);
641 	}
642       else if (l >= 2 && argv[index][l - 2] == '.')
643 	{
644 	  fprintf (stderr, "%s: Illegal extension\n", progname);
645 	  print_help (1);
646 	}
647       else
648 	{
649 	  if (sourcename != NULL)
650 	    {
651 	      fprintf (stderr, "%s: More than one simula-files "
652 		       "are specified\n", progname);
653 	      print_help (1);
654 	    };
655 	  if (l > 4 && !(strcmp (&argv[index][l - 4], ".sim")
656 			 && strcmp (&argv[index][l - 4], ".SIM")
657 			 && strcmp (&argv[index][l - 4], ".cim")
658 			 && strcmp (&argv[index][l - 4], ".CIM")))
659 	    sourcename = newstrcat1 (argv[index]);
660 	  else
661 	    sourcename = newstrcat2 (argv[index], ".sim");
662 	}
663     }
664 
665   if (sourcename == NULL)
666     {
667       fprintf (stderr, "%s: No simula-file is specified\n", progname);
668       print_help (1);
669     };
670 
671   exekname= basename (sourcename);
672   listname= newstrcat2 (exekname, ".L");
673   extcodename= newstrcat2 (exekname, ".atr");
674   mifcodename= newstrcat2 (exekname, ".mif");
675   ccodename= newstrcat2 (exekname, ".c");
676   ocodename= newstrcat2 (exekname, ".o");
677   shlname= newstrcat3 ("./", exekname, ".shl");
678 
679   if (!strcmp (outputname, ""))
680     outputname = exekname;
681   else
682     exekname = outputname;
683 
684   if (strncmp (exekname, "/", 1))
685     exekname = newstrcat2 ("./", exekname);
686 
687   return (FALSE);
688 }
689 
690 /******************************************************************************
691                                                                         MAIN */
692 
main(argc,argv,envp)693 main (argc, argv, envp)
694      int argc;
695      char *argv[];
696      char *envp[];
697 {
698   char *archname;
699   char *kom;
700   char differ=TRUE;
701 
702   progname = argv[0];
703 
704   initNewstr ();
705   initFilelist ();
706 
707   ccomp = newstrcat3 (SCC, " ", SCFLAGS);
708 
709   init_trap_routines();
710 
711   get_all_env();
712 
713   insert_name_in_dirlist (systemlibdir);
714 
715   initName ();
716 
717   if (parseoptions (argc, argv))
718     return (1);
719 
720   new_lib ("cim");
721 
722   if (option_verbose)
723     {
724       fprintf
725 	(stderr,
726 	 "Cim Compiler (version: %s configuration name: %s).\n"
727 	 "Copyright 1989-1998 by Sverre Hvammen Johansen, Stein Krogdahl,"
728 	 "Terje Mj�s and Free Software Foundation, Inc.\n"
729 	 "Cim comes with ABSOLUTELY NO WARRANTY.\n"
730 	 "This is free software, and you are welcome to redistribute it\n"
731 	 "under the GNU General Public License; version 2.\n",
732 	 PACKAGE_VERSION, SYSTEM_TYPE);
733     }
734 
735   if(option_atr)
736     system (newstrcat6 ("cp -f ", extcodename, " ", extcodename,
737 			 ".old", " 2>/dev/null"));
738 
739   if(option_checkdiff)
740     {
741       rename (ccodename, newstrcat2 (ccodename, ".old"));
742     }
743 
744   if (!option_nosim && simcomp ())
745     {
746       unlink (ccodename);
747 
748       if(option_checkdiff)
749 	{
750 	  rename (ccodename, newstrcat2 (ccodename, ".old"));
751 	}
752       return (1);
753     }
754 
755   if (option_write_tokens)
756     return (0);
757 
758   if(option_atr)
759     {
760       char status;
761       unlink (ccodename);
762 
763       status = system (newstrcat5 ("cmp -s ", extcodename, " ",
764 				  extcodename, ".old 2>/dev/null"));
765       unlink (newstrcat2 (extcodename, ".old"));
766       if (status)
767 	{
768 	  if (option_verbose)
769 	    fprintf (stderr, "Atr file differ\n");
770 	  return (1);
771 	} else return (0);
772     }
773 
774   if (!option_nosim)
775     {
776       FILE *shlfile;
777 
778       if ((shlfile = fopen (shlname, "w")) == NULL)
779 	{
780 	  perror (newstrcat3 (progname, ": ", shlname));
781 	  return (1);
782 	}
783 
784       fprintf (shlfile,
785 	       "#! /bin/sh\n"
786 	       "\n"
787 	       "CC='%s'\n"
788 	       "CFLAGS='%s'\n"
789 	       "CFLAGS_ADD=\n"
790 	       "LDFLAGS='%s'\n"
791 	       "LDFLAGS_ADD=\n"
792 	       "wl='%s'\n"
793 	       "link_static_flag=\"%s\"\n"
794 	       "pic_flag=\"%s\"\n"
795 	       "\n"
796 	       "prev=\n"
797 	       "for option\n"
798 	       "do\n"
799 	       "  if test -n \"$prev\"; then\n"
800 	       "    eval \"$prev=\\$option\"\n"
801 	       "    prev=\n"
802 	       "    if test -n \"$CFLAGS_ADD\"; then\n"
803 	       "      CFLAGS=\"$CFLAGS $option\"\n"
804 	       "      CFLAGS_ADD=\n"
805 	       "    fi\n"
806 	       "    if test -n \"$LDFLAGS_ADD\"; then\n"
807 	       "      LDFLAGS=\"$LDFLAGS $option\"\n"
808 	       "      LDFLAGS_ADD=\n"
809 	       "    fi\n"
810 	       "    continue\n"
811 	       "  fi\n"
812 	       "\n"
813 	       "  case \"$option\" in\n"
814 	       "  -*=*) optarg=`echo \"$option\" | "
815 	       "sed 's/[-_a-zA-Z0-9]*=//'` ;;\n"
816 	       "  *) optarg= ;;\n"
817 	       "  esac\n"
818 	       "\n"
819 	       "  case \"$option\" in\n"
820 	       "  -c | --suppress-linking | -suppress-linking)\n"
821 	       "    option_nolink=yes ;;\n"
822 	       "  -e | --static | -static)\n"
823 	       "  LDFLAGS=\"$LDFLAGS $link_static_flag\" ;;\n"
824 	       "  -G | --gcc | -gcc)\n"
825 	       "    CC='gcc -g -O2'; static_flag='-static'; \n"
826 	       "    pic_flag=' -fPIC' ;;\n"
827 	       "  -q | --quiet | --silent | -quiet | -silent)\n"
828 	       "    option_quiet=yes ; option_verbose= ;;\n"
829 	       "  -v | --verbose | -verbose) "
830 	       "    option_quiet= ; option_verbose=yes ;;\n"
831 	       "  -p | --pic | -pic)\n"
832 	       "  CFLAGS=\"$CFLAGS $pic_flag\" ;;\n"
833 	       "  -P | --only-link | -only-link)\n"
834 	       "    option_nocc=yes ;;\n"
835 	       "  -t | --dont-remove-temporaries | -dont-remove-temporaries)\n"
836 	       "    option_notempdel=yes ;;\n"
837 	       "  -s | --no-simula-compile | -no-simula-compile)\n"
838 	       "    option_notempdel=yes ;;\n"
839 	       "  -S | --only-simula-compile | -only-simula-compile)\n"
840 	       "    option_nolink=yes; option_nocc=yes ;;\n"
841 	       "  -d | --compare | -compare) "
842 	       "    option_checkdiff=yes; option_notempdel=yes ;;\n"
843 	       "\n"
844 	       "  -b | --cflags | -cflags)\n"
845 	       "    prev=CFLAGS_ADD ;;\n"
846 	       "  -B | --ldflags | -ldflags)\n"
847 	       "    prev=LDFLAGS_ADD ;;\n"
848 	       "  -C | --c-compiler | -c-compiler)\n"
849 	       "    prev=CC ;;\n"
850 	       "  -b=* | --cflags=* | -cflags=*)\n"
851 	       "    CFLAGS=\"$CFLAGS $optarg\" ;;\n"
852 	       "  -B=* | --ldflags=* | -ldflags=*)\n"
853 	       "    LDFLAGS=\"$LDFLAGS $optarg\" ;;\n"
854 	       "  -C=* | --c-compiler=* | -c-compiler=*)\n"
855 	       "    CC=\"$optarg\" ;;\n"
856 	       /*	       "  *) { echo \"n.shl: $option: invalid option\" 1>&2; "
857 	       "exit 1 };;\n"*/
858 	       "  esac\n"
859 	       "done\n"
860 	       "\n"
861 	       "differ=yes\n"
862 	       "if test -z \"$option_nocc\"; then\n"
863 	       "  if test -n \"$option_checkdiff\"; then\n"
864 	       "    cmp -s %s %s.old &&\n"
865 	       "      differ=\n"
866 	       "    rm -f %s.old\n"
867 	       "  fi\n"
868 	       "\n"
869 	       "  if test -n \"$differ\"; then\n"
870 	       "    if test -z \"$option_quiet\"; then\n"
871 	       "      echo $CC $CFLAGS -c %s\n"
872 	       "    fi\n"
873 	       "    $CC $CFLAGS -c %s || exit 1\n"
874 	       "  else\n"
875 	       "    if test -z\"$option_quiet\"; then\n"
876 	       "      echo touch %s\n"
877 	       "    fi\n"
878 	       "    touch %s\n"
879 	       "  fi\n"
880 	       "  if test -z \"$option_notempdel\"; then\n"
881 	       "    rm -f %s\n"
882 	       "  fi\n"
883 	       "fi\n"
884 	       "\n",
885 	       ccomp, "", SLDFLAGS,
886 	       WL_FLAG, LINK_STATIC_FLAG, PIC_FLAG,
887 	       ccodename, ccodename,
888 	       ccodename,
889 	       ccodename, ccodename,
890 	       ocodename, ocodename,
891 	       ccodename);
892 
893       if (!separat_comp)
894 	{
895 	  more_modules ();
896 	  fprintf (shlfile,
897 		   "if test -z \"$option_nolink\"; then\n"
898 		   "  if test -z \"$option_quiet\"; then\n"
899 		   "    echo $CC $LDFLAGS -o %s %s %s\n"
900 		   "  fi\n"
901 		   "\n"
902 		   "  $CC $LDFLAGS -o %s %s %s %s || exit 1\n"
903 		   "fi\n",
904 		   outputname, ocodename, get_names_in_linklist (),
905 		   outputname, ocodename, get_names_in_linklist (), SLIBS);
906 	}
907       if (!((option_nolink && !separat_comp)
908 	    || option_nocc || option_notempdel))
909 	fprintf (shlfile, "rm -f %s\n",shlname);
910       fclose (shlfile);
911       system (newstrcat2 ("chmod +x ", shlname));
912     }
913   argv[0]= shlname;
914   execve (shlname, argv, envp);
915 }
916