]> Git Repo - binutils.git/blob - gas/as.c
White space and comment changes, and #ifdef __STDC__ becomes #if
[binutils.git] / gas / as.c
1 /* as.c - GAS main program.
2    Copyright (C) 1987, 1990, 1991 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 2, 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 #include <stdio.h>
36 #include <string.h>
37
38 #ifdef _POSIX_SOURCE
39 #include <sys/types.h>  /* For pid_t in signal.h */
40 #endif
41 #include <signal.h>
42
43 #define COMMON
44
45 #include "as.h"
46 #include "subsegs.h"
47 #ifdef __STDC__
48
49 /* This prototype for got_sig() is ansi.  If you want
50    anything else, then your compiler is lying to you when
51    it says that it is __STDC__.  If you want to change it,
52    #ifdef protect it from those of us with real ansi
53    compilers. */
54
55 #define SIGTY void
56
57 static void got_sig(int sig);
58 static char *stralloc(char *str);
59 static void perform_an_assembly_pass(int argc, char **argv);
60
61 #else /* __STDC__ */
62
63 #ifndef SIGTY
64 #define SIGTY int
65 #endif
66
67 static SIGTY got_sig();
68 static char *stralloc();        /* Make a (safe) copy of a string. */
69 static void perform_an_assembly_pass();
70
71 #endif /* __STDC__ */
72
73 #ifdef DONTDEF
74 static char * gdb_symbol_file_name;
75 long gdb_begin();
76 #endif
77
78 int listing; /* true if a listing is wanted */
79
80 char *myname;           /* argv[0] */
81 extern char version_string[];
82 \f
83 int main(argc,argv)
84 int argc;
85 char **argv;
86 {
87         int work_argc;  /* variable copy of argc */
88         char **work_argv;       /* variable copy of argv */
89         char *arg;              /* an arg to program */
90         char a;         /* an arg flag (after -) */
91         static const int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
92         
93         for(a=0;sig[a]!=0;a++)
94             if(signal(sig[a], SIG_IGN) != SIG_IGN)
95                 signal(sig[a], got_sig);
96         
97         myname=argv[0];
98         bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
99 #ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
100 #define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
101 #endif /* OBJ_DEFAULT_OUTPUT_FILE_NAME */
102         out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
103         
104         symbol_begin();         /* symbols.c */
105         subsegs_begin();                /* subsegs.c */
106         read_begin();                   /* read.c */
107         md_begin();                     /* MACHINE.c */
108         input_scrub_begin();            /* input_scrub.c */
109 #ifdef DONTDEF
110         gdb_symbol_file_name = 0;
111 #endif
112         /*
113          * Parse arguments, but we are only interested in flags.
114          * When we find a flag, we process it then make it's argv[] NULL.
115          * This helps any future argv[] scanners avoid what we processed.
116          * Since it is easy to do here we interpret the special arg "-"
117          * to mean "use stdin" and we set that argv[] pointing to "".
118          * After we have munged argv[], the only things left are source file
119          * name(s) and ""(s) denoting stdin. These file names are used
120          * (perhaps more than once) later.
121          */
122         /* FIXME-SOMEDAY this should use getopt. */
123         work_argc = argc-1;             /* don't count argv[0] */
124         work_argv = argv+1;             /* skip argv[0] */
125         for (;work_argc--;work_argv++) {
126                 arg = * work_argv;      /* work_argv points to this argument */
127                 
128                 if (*arg!='-')          /* Filename. We need it later. */
129                     continue;   /* Keep scanning args looking for flags. */
130                 if (arg[1] == '-' && arg[2] == 0) {
131                         /* "--" as an argument means read STDIN */
132                         /* on this scan, we don't want to think about filenames */
133                         * work_argv = "";       /* Code that means 'use stdin'. */
134                         continue;
135                 }
136                 /* This better be a switch. */
137                 arg ++;         /*->letter. */
138                 
139                 while ((a = * arg) != '\0')  {/* scan all the 1-char flags */
140                         arg ++; /* arg->after letter. */
141                         a &= 0x7F;      /* ascii only please */
142                         /* if (flagseen[a])
143                            as_tsktsk("%s: Flag option - %c has already been seen.", myname, a); */
144                         flagseen[a] = 1;
145                         switch (a) {
146                                 
147                         case 'a': 
148                                 {
149                                         int loop =1;
150                                         
151                                         while (loop) {
152                                                 switch (*arg) 
153                                                     {
154                                                     case 'l':
155                                                             listing |= LISTING_LISTING;
156                                                             arg++;
157                                                             break;
158                                                     case 's':
159                                                             listing |= LISTING_SYMBOLS;
160                                                             arg++;
161                                                             break;
162                                                     case 'h':
163                                                             listing |= LISTING_HLL;
164                                                             arg++;
165                                                             break;
166                                                             
167                                                     case 'n':
168                                                             listing |= LISTING_NOFORM;
169                                                             arg++;
170                                                             break;
171                                                     case 'd':
172                                                             listing |= LISTING_NODEBUG;
173                                                             arg++;
174                                                             break;
175                                                     default:
176                                                             if (!listing)
177                                                                 listing= LISTING_DEFAULT;
178                                                             loop = 0;
179                                                             break;
180                                                     }
181                                         }
182                                 }
183                                 
184                                 break;
185                                 
186                                 
187                         case 'f':
188                                 break;  /* -f means fast - no need for "app" preprocessor. */
189                                 
190                         case 'D':
191                                 /* DEBUG is implemented: it debugs different */
192                                 /* things to other people's assemblers. */
193                                 break;
194                                 
195 #ifdef DONTDEF
196                         case 'G':       /* GNU AS switch: include gdbsyms. */
197                                 if (*arg)       /* Rest of argument is file-name. */
198                                     gdb_symbol_file_name = stralloc (arg);
199                                 else if (work_argc) {   /* Next argument is file-name. */
200                                         work_argc --;
201                                         * work_argv = NULL; /* Not a source file-name. */
202                                         gdb_symbol_file_name = * ++ work_argv;
203                                 } else
204                                     as_warn("%s: I expected a filename after -G", myname);
205                                 arg = "";       /* Finished with this arg. */
206                                 break;
207 #endif
208                                 
209                         case 'I': { /* Include file directory */
210                                 
211                                 char *temp = NULL;
212                                 if (*arg)
213                                     temp = stralloc (arg);
214                                 else if (work_argc) {
215                                         * work_argv = NULL;
216                                         work_argc--;
217                                         temp = * ++ work_argv;
218                                 } else
219                                     as_warn("%s: I expected a filename after -I", myname);
220                                 add_include_dir (temp);
221                                 arg = "";       /* Finished with this arg. */
222                                 break;
223                         }
224                                 
225 #ifndef WORKING_DOT_WORD
226                         case 'k':
227                                 break;
228 #endif
229                                 
230                         case 'L': /* -L means keep L* symbols */
231                                 break;
232                                 
233                         case 'o':
234                                 if (*arg)       /* Rest of argument is object file-name. */
235                                     out_file_name = stralloc (arg);
236                                 else if (work_argc) {   /* Want next arg for a file-name. */
237                                         * work_argv = NULL; /* This is not a file-name. */
238                                         work_argc--;
239                                         out_file_name = * ++ work_argv;
240                                 } else
241                                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.", myname, out_file_name);
242                                 arg = "";       /* Finished with this arg. */
243                                 break;
244                                 
245                         case 'R':
246                                 /* -R means put data into text segment */
247                                 break;
248                                 
249                         case 'v':
250 #ifdef  VMS
251                                 {
252                                         extern char *compiler_version_string;
253                                         compiler_version_string = arg;
254                                 }
255 #else /* not VMS */
256                                 fprintf(stderr,version_string);
257                                 if(*arg && strcmp(arg,"ersion"))
258                                     as_warn("Unknown -v option ignored");
259 #endif
260                                 while(*arg) arg++;      /* Skip the rest */
261                                 break;
262                                 
263                         case 'W':
264                                 /* -W means don't warn about things */
265                         case 'X':
266                                 /* -X means treat warnings as errors */
267                         case 'Z':
268                                 /* -Z means attempt to generate object file even after errors. */
269                                 break;
270                                 
271                         default:
272                                 --arg;
273                                 if(md_parse_option(&arg,&work_argc,&work_argv)==0)
274                                     as_warn("%s: I don't understand '%c' flag.", myname, a);
275                                 if(arg && *arg)
276                                     arg++;
277                                 break;
278                         }
279                 }
280                 /*
281                  * We have just processed a "-..." arg, which was not a
282                  * file-name. Smash it so the
283                  * things that look for filenames won't ever see it.
284                  *
285                  * Whatever work_argv points to, it has already been used
286                  * as part of a flag, so DON'T re-use it as a filename.
287                  */
288                 *work_argv = NULL; /* NULL means 'not a file-name' */
289         }
290 #ifdef DONTDEF
291         if (gdb_begin(gdb_symbol_file_name) == 0)
292             flagseen ['G'] = 0; /* Don't do any gdbsym stuff. */
293 #endif
294         /* Here with flags set up in flagseen[]. */
295         perform_an_assembly_pass(argc,argv); /* Assemble it. */
296 #ifdef TC_I960
297         brtab_emit();
298 #endif
299         if (seen_at_least_1_file()
300             && !((had_warnings() && flagseen['Z'])
301                  || had_errors() > 0)) { 
302                 write_object_file(); /* relax() addresses then emit object file */
303         } /* we also check in write_object_file() just before emit. */
304         
305         input_scrub_end();
306         md_end();                       /* MACHINE.c */
307         
308 #ifndef NO_LISTING
309         listing_print();
310 #endif
311         
312 #ifndef VMS
313         return((had_warnings() && flagseen['Z'])
314                || had_errors() > 0);                    /* WIN */
315 #else   /* VMS */
316         return(!((had_warnings() && flagseen['Z'])
317                  || had_errors() > 0));                 /* WIN */
318 #endif  /* VMS */
319         
320 } /* main() */
321
322 \f
323 /*                      perform_an_assembly_pass()
324  *
325  * Here to attempt 1 pass over each input file.
326  * We scan argv[*] looking for filenames or exactly "" which is
327  * shorthand for stdin. Any argv that is NULL is not a file-name.
328  * We set need_pass_2 TRUE if, after this, we still have unresolved
329  * expressions of the form (unknown value)+-(unknown value).
330  *
331  * Note the un*x semantics: there is only 1 logical input file, but it
332  * may be a catenation of many 'physical' input files.
333  */
334 static void perform_an_assembly_pass(argc, argv)
335 int argc;
336 char **argv;
337 {
338         int saw_a_file = 0;
339         unsigned int i;
340         need_pass_2             = 0;
341         
342 #ifdef MANY_SEGMENTS
343         
344         for (i= SEG_E0; i < SEG_UNKNOWN; i++) 
345             {
346                     segment_info[i].fix_root = 0;
347             }
348         /* Create the three fixed ones */
349         subseg_new (SEG_E0, 0);
350         subseg_new (SEG_E1, 0);
351         subseg_new (SEG_E2, 0);
352         strcpy(segment_info[SEG_E0].scnhdr.s_name,".text");
353         strcpy(segment_info[SEG_E1].scnhdr.s_name,".data");
354         strcpy(segment_info[SEG_E2].scnhdr.s_name,".bss");
355         
356         subseg_new (SEG_E0, 0);
357 #else
358         text_fix_root           = NULL;
359         data_fix_root           = NULL;
360         
361         subseg_new (SEG_TEXT, 0);
362 #endif
363         argv++; /* skip argv[0] */
364         argc--; /* skip argv[0] */
365         while (argc--) {
366                 if (*argv) { /* Is it a file-name argument? */
367                         saw_a_file++;
368                         /* argv->"" if stdin desired, else->filename */
369                         read_a_source_file(*argv);
370                 }
371                 argv++; /* completed that argv */
372         }
373         if(!saw_a_file)
374             read_a_source_file("");
375 } /* perform_an_assembly_pass() */
376 \f
377 /*
378  *                      stralloc()
379  *
380  * Allocate memory for a new copy of a string. Copy the string.
381  * Return the address of the new string. Die if there is any error.
382  */
383
384 static char *
385     stralloc (str)
386 char *  str;
387 {
388         register char * retval;
389         register long len;
390         
391         len = strlen (str) + 1;
392         retval = xmalloc (len);
393         (void) strcpy(retval, str);
394         return(retval);
395 }
396 \f
397 #ifdef comment
398 static void lose() {
399         as_fatal("%s: 2nd pass not implemented - get your code from random(3)", myname);
400         return;
401 } /* lose() */
402 #endif /* comment */
403
404 static SIGTY
405     got_sig(sig)
406 int sig;
407 {
408         static here_before = 0;
409         
410         as_bad("Interrupted by signal %d", sig);
411         if(here_before++)
412             exit(1);
413         return((SIGTY) 0);
414 }
415
416 /*
417  * Local Variables:
418  * comment-column: 0
419  * fill-column: 131
420  * End:
421  */
422
423 /* end of as.c */
This page took 0.050911 seconds and 4 git commands to generate.