Commit | Line | Data |
---|---|---|
fecd2382 RP |
1 | /* cond.c - conditional assembly pseudo-ops, and .include |
2 | Copyright (C) 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 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 | /* static const char rcsid[] = "$Id$"; */ | |
21 | ||
22 | #include "as.h" | |
23 | ||
24 | #include "obstack.h" | |
25 | ||
26 | void s_ifdef(arg) | |
27 | int arg; | |
28 | { | |
29 | /* register char c; */ | |
30 | register char *name; /* points to name of symbol */ | |
31 | register struct symbol * symbolP; /* Points to symbol */ | |
32 | ||
33 | SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ | |
34 | name = input_line_pointer; | |
35 | if (!is_name_beginner(*name)) { | |
36 | as_bad("invalid identifier for .ifdef"); | |
37 | obstack_1grow (&cond_obstack, 0); | |
38 | } else { | |
39 | get_symbol_end(); | |
40 | ++input_line_pointer; | |
41 | symbolP = symbol_find(name); | |
42 | ||
43 | /* ??? Should we try to optimize such that if we hit a .endif | |
44 | before a .else, we don't need to push state? */ | |
45 | obstack_1grow(&cond_obstack, (symbolP != 0) ^ arg); | |
46 | } | |
47 | } /* s_ifdef() */ | |
48 | ||
49 | /* This is allocated to grow and shrink as .ifdef/.endif pairs | |
50 | are scanned. When the top element is nonzero, it means | |
51 | we should accept input. Otherwise, we should ignore input. */ | |
52 | struct obstack cond_obstack; | |
53 | ||
54 | void s_if(arg) | |
55 | int arg; | |
56 | { | |
57 | expressionS operand; | |
58 | ||
59 | SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ | |
60 | expr(0, &operand); | |
61 | ||
62 | if (operand.X_add_symbol != NULL | |
63 | || operand.X_subtract_symbol != NULL) | |
64 | as_bad("non-constant expression in .if statement"); | |
65 | ||
66 | /* If the above error is signaled, this will dispatch | |
67 | using an undefined result. No big deal. */ | |
68 | obstack_1grow(&cond_obstack, (operand.X_add_number != 0) ^ arg); | |
69 | } /* s_if() */ | |
70 | ||
71 | void s_endif(arg) | |
72 | int arg; | |
73 | { | |
74 | char *base = obstack_base(&cond_obstack); | |
75 | char *ptr = obstack_next_free(&cond_obstack); | |
76 | ||
77 | if (ptr-1 == base) { | |
78 | as_bad("unbalanced .endif"); | |
79 | } else { | |
80 | obstack_free(&cond_obstack, ptr-1); | |
81 | cond_obstack.object_base = base; | |
82 | } | |
83 | } /* s_endif() */ | |
84 | ||
85 | void s_else(arg) | |
86 | int arg; | |
87 | { | |
88 | char *ptr = obstack_next_free(&cond_obstack); | |
89 | if (ptr-1 == obstack_base(&cond_obstack)) { | |
90 | as_bad(".else without matching .if"); | |
91 | } else { | |
92 | ptr[-1] = !ptr[-1]; | |
93 | } | |
94 | } /* s_else() */ | |
95 | ||
96 | void s_ifeqs(arg) | |
97 | int arg; | |
98 | { | |
99 | as_bad("ifeqs not implemented."); | |
100 | } /* s_ifeqs() */ | |
101 | ||
102 | void s_end(arg) | |
103 | int arg; | |
104 | { | |
105 | ; | |
106 | } /* s_end() */ | |
107 | ||
108 | int ignore_input() { | |
109 | char *ptr = obstack_next_free (&cond_obstack); | |
110 | ||
111 | /* We cannot ignore certain pseudo ops. */ | |
112 | if (input_line_pointer[-1] == '.') | |
113 | { | |
114 | if (input_line_pointer[0] == 'i' | |
115 | && (!strncmp (input_line_pointer, "if", 2) | |
116 | || !strncmp (input_line_pointer, "ifdef", 5) | |
117 | || !strncmp (input_line_pointer, "ifndef", 6))) | |
118 | return 0; | |
119 | if (input_line_pointer[0] == 'e' | |
120 | && (!strncmp (input_line_pointer, "else", 4) | |
121 | || !strncmp (input_line_pointer, "endif", 5))) | |
122 | return 0; | |
123 | } | |
124 | ||
125 | return (ptr[-1] == 0); | |
126 | } /* ignore_input() */ | |
127 | ||
128 | /* end of cond.c */ |