home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Atari / Gnu / gassrc04.zoo / as.c < prev    next >
C/C++ Source or Header  |  1992-04-27  |  8KB  |  315 lines

  1. /* as.c - GAS main program.
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS 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; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * Main program for AS; a 32-bit assembler of GNU.
  22.  * Understands command arguments.
  23.  * Has a few routines that don't fit in other modules because they
  24.  * are shared.
  25.  *
  26.  *
  27.  *            bugs
  28.  *
  29.  * : initialisers
  30.  *    Since no-one else says they will support them in future: I
  31.  * don't support them now.
  32.  *
  33.  */
  34.  
  35. #ifdef _POSIX_SOURCE
  36. #include <sys/types.h>    /* For pid_t in signal.h */
  37. #endif
  38. #include <signal.h>
  39.  
  40. #define COMMON
  41. #include "as.h"
  42. #include "struc-symbol.h"
  43. #include "write.h"
  44.         /* Warning!  This may have some slightly strange side effects
  45.            if you try to compile two or more assemblers in the same
  46.            directory!
  47.          */
  48.  
  49. #ifndef SIGTY
  50. #define SIGTY int
  51. #endif
  52.  
  53. SIGTY got_sig();
  54.  
  55. #ifdef DONTDEF
  56. static char * gdb_symbol_file_name;
  57. long int gdb_begin();
  58. #endif
  59.  
  60. char *myname;        /* argv[0] */
  61. extern char version_string[];
  62.  
  63. main(argc,argv)
  64. int    argc;
  65. char    **argv;
  66. {
  67.     int    work_argc;    /* variable copy of argc */
  68.     char    **work_argv;    /* variable copy of argv */
  69.     char    *arg;        /* an arg to program */
  70.     char    a;        /* an arg flag (after -) */
  71.     static const int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
  72.  
  73.     extern int bad_error;    /* Did we hit a bad error ? */
  74.  
  75.     char    *stralloc();    /* Make a (safe) copy of a string. */
  76.     void    symbol_begin();
  77.     void    read_begin();
  78.     void    write_object_file();
  79.  
  80.     for(a=0;sig[a]!=0;a++)
  81.         if(signal(sig[a], SIG_IGN) != SIG_IGN)
  82.             signal(sig[a], got_sig);
  83.  
  84. #ifdef atarist
  85.     _binmode(1);
  86. #endif
  87.     myname=argv[0];
  88.     bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  89.     out_file_name    = "a.out";    /* default .o file */
  90.     symbol_begin();        /* symbols.c */
  91.     subsegs_begin();        /* subsegs.c */
  92.     read_begin();            /* read.c */
  93.     md_begin();            /* MACHINE.c */
  94.     input_scrub_begin();        /* input_scrub.c */
  95. #ifdef DONTDEF
  96.     gdb_symbol_file_name = 0;
  97. #endif
  98.     /*
  99.      * Parse arguments, but we are only interested in flags.
  100.      * When we find a flag, we process it then make it's argv[] NULL.
  101.      * This helps any future argv[] scanners avoid what we processed.
  102.      * Since it is easy to do here we interpret the special arg "-"
  103.      * to mean "use stdin" and we set that argv[] pointing to "".
  104.      * After we have munged argv[], the only things left are source file
  105.      * name(s) and ""(s) denoting stdin. These file names are used
  106.      * (perhaps more than once) later.
  107.      */
  108.     work_argc = argc-1;        /* don't count argv[0] */
  109.     work_argv = argv+1;        /* skip argv[0] */
  110.     for (;work_argc--;work_argv++) {
  111.         arg = * work_argv;    /* work_argv points to this argument */
  112.  
  113.         if (*arg!='-')        /* Filename. We need it later. */
  114.             continue;    /* Keep scanning args looking for flags. */
  115.         if (arg[1] == '-' && arg[2] == 0) {
  116.             /* "--" as an argument means read STDIN */
  117.             /* on this scan, we don't want to think about filenames */
  118.             * work_argv = "";    /* Code that means 'use stdin'. */
  119.             continue;
  120.         }
  121.                 /* This better be a switch. */
  122.         arg ++;        /* -> letter. */
  123.  
  124.         while (a = * arg)  {/* scan all the 1-char flags */
  125.             arg ++;    /* arg -> after letter. */
  126.             a &= 0x7F;    /* ascii only please */
  127.             if (flagseen[a])
  128.                 as_warn("%s: Flag option -%c has already been seen!",myname,a);
  129.             flagseen[a] = TRUE;
  130.             switch (a) {
  131.             case 'f':
  132.                 break;    /* -f means fast - no need for "app" preprocessor. */
  133.  
  134.             case 'D':
  135.                 /* DEBUG is implemented: it debugs different */
  136.                 /* things to other people's assemblers. */
  137.                 break;
  138.  
  139. #ifdef DONTDEF
  140.             case 'G':    /* GNU AS switch: include gdbsyms. */
  141.                 if (*arg)    /* Rest of argument is file-name. */
  142.                     gdb_symbol_file_name = stralloc (arg);
  143.                 else if (work_argc) {    /* Next argument is file-name. */
  144.                     work_argc --;
  145.                     * work_argv = NULL; /* Not a source file-name. */
  146.                     gdb_symbol_file_name = * ++ work_argv;
  147.                 } else
  148.                     as_warn( "%s: I expected a filename after -G",myname);
  149.                 arg = "";    /* Finished with this arg. */
  150.                 break;
  151. #endif
  152.  
  153. #ifndef WORKING_DOT_WORD
  154.             case 'k':
  155.                 break;
  156. #endif
  157.  
  158.             case 'L': /* -L means keep L* symbols */
  159.                 break;
  160.  
  161.             case 'o':
  162.                 if (*arg)    /* Rest of argument is object file-name. */
  163.                     out_file_name = stralloc (arg);
  164.                 else if (work_argc) {    /* Want next arg for a file-name. */
  165.                     * work_argv = NULL; /* This is not a file-name. */
  166.                     work_argc--;
  167.                     out_file_name = * ++ work_argv;
  168.                 } else
  169.                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  170.                 arg = "";    /* Finished with this arg. */
  171.                 break;
  172.  
  173.             case 'R':
  174.                 /* -R means put data into text segment */
  175.                 break;
  176.  
  177.             case 'v':
  178. #ifdef    VMS
  179.                 {
  180.                 extern char *compiler_version_string;
  181.                 compiler_version_string = arg;
  182.                 }
  183. #else /* not VMS */
  184. #if defined(CROSSATARI) || defined(atarist) || defined(atariminix)
  185. #include "PatchLev.h"
  186.                 fprintf(stderr, "%s atariST PatchLevel %s\n",
  187.                    version_string, PatchLevel);
  188. #else
  189.                 fprintf(stderr,version_string);
  190. #endif
  191.                 if(*arg && strcmp(arg,"ersion"))
  192.                     as_warn("Unknown -v option ignored");
  193. #endif
  194.                 while(*arg) arg++;    /* Skip the rest */
  195.                 break;
  196.  
  197.             case 'W':
  198.                 /* -W means don't warn about things */
  199.                 break;
  200.  
  201.             default:
  202.                 --arg;
  203.                 if(md_parse_option(&arg,&work_argc,&work_argv)==0)
  204.                     as_warn("%s: I don't understand '%c' flag!",myname,a);
  205.                 if(arg && *arg)
  206.                     arg++;
  207.                 break;
  208.             }
  209.         }
  210.         /*
  211.          * We have just processed a "-..." arg, which was not a
  212.          * file-name. Smash it so the
  213.          * things that look for filenames won't ever see it.
  214.          *
  215.          * Whatever work_argv points to, it has already been used
  216.          * as part of a flag, so DON'T re-use it as a filename.
  217.          */
  218.         *work_argv = NULL; /* NULL means 'not a file-name' */
  219.     }
  220. #ifdef DONTDEF
  221.     if (gdb_begin(gdb_symbol_file_name) == 0)
  222.         flagseen ['G'] = 0;    /* Don't do any gdbsym stuff. */
  223. #endif
  224.     /* Here with flags set up in flagseen[]. */
  225.     perform_an_assembly_pass(argc,argv); /* Assemble it. */
  226.     if (seen_at_least_1_file() && !bad_error)
  227.         write_object_file();/* relax() addresses then emit object file */
  228.     input_scrub_end();
  229.     md_end();            /* MACHINE.c */
  230. #ifndef    VMS
  231.     exit(bad_error);            /* WIN */
  232. #else    /* VMS */
  233.     exit(!bad_error);            /* WIN */
  234. #endif    /* VMS */
  235. }
  236.  
  237.  
  238. /*            perform_an_assembly_pass()
  239.  *
  240.  * Here to attempt 1 pass over each input file.
  241.  * We scan argv[*] looking for filenames or exactly "" which is
  242.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  243.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  244.  * expressions of the form (unknown value)+-(unknown value).
  245.  *
  246.  * Note the un*x semantics: there is only 1 logical input file, but it
  247.  * may be a catenation of many 'physical' input files.
  248.  */
  249. perform_an_assembly_pass (argc, argv)
  250. int    argc;
  251. char **    argv;
  252. {
  253.     char *    buffer;        /* Where each bufferful of lines will start. */
  254.     void    read_a_source_file();
  255.     int saw_a_file = 0;
  256.  
  257.     text_fix_root        = NULL;
  258.     data_fix_root        = NULL;
  259.     need_pass_2        = FALSE;
  260.  
  261.     argv++;            /* skip argv[0] */
  262.     argc--;            /* skip argv[0] */
  263.     while (argc--) {
  264.         if (*argv) {        /* Is it a file-name argument? */
  265.             /* argv -> "" if stdin desired, else -> filename */
  266.             if (buffer = input_scrub_new_file (*argv) ) {
  267.                 saw_a_file++;
  268.                 read_a_source_file(buffer);
  269.             }
  270.         }
  271.         argv++;            /* completed that argv */
  272.     }
  273.     if(!saw_a_file)
  274.         if(buffer = input_scrub_new_file("") )
  275.             read_a_source_file(buffer);
  276. }
  277.  
  278. /*
  279.  *            stralloc()
  280.  *
  281.  * Allocate memory for a new copy of a string. Copy the string.
  282.  * Return the address of the new string. Die if there is any error.
  283.  */
  284.  
  285. char *
  286. stralloc (str)
  287. char *    str;
  288. {
  289.     register char *    retval;
  290.     register long int    len;
  291.  
  292.     len = strlen (str) + 1;
  293.     retval = xmalloc (len);
  294.     (void)strcpy (retval, str);
  295.     return (retval);
  296. }
  297.  
  298. lose()
  299. {
  300.     as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  301. }
  302.  
  303. SIGTY
  304. got_sig(sig)
  305. int sig;
  306. {
  307.     static here_before = 0;
  308.  
  309.     as_bad("Interrupted by signal %d",sig);
  310.     if(here_before++)
  311.         exit(1);
  312. }
  313.  
  314. /* end: as.c */
  315.