Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / gnu / usr.bin / as / cond.c
1 /* cond.c - conditional assembly pseudo-ops, and .include
2    Copyright (C) 1990, 1991, 1992, 1993 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  * $FreeBSD: src/gnu/usr.bin/as/cond.c,v 1.6 1999/08/27 23:34:13 peter Exp $
22  * $DragonFly: src/gnu/usr.bin/as/Attic/cond.c,v 1.2 2003/06/17 04:25:44 dillon Exp $
23  */
24 #include "as.h"
25
26 #include "obstack.h"
27
28 /* This is allocated to grow and shrink as .ifdef/.endif pairs are scanned. */
29 struct obstack cond_obstack;
30
31 struct file_line
32 {
33   char *file;
34   unsigned int line;
35 };                              /* file_line */
36
37 /* This is what we push and pop. */
38 struct conditional_frame
39   {
40     struct file_line if_file_line;      /* the source file & line number of the "if" */
41     struct file_line else_file_line;    /* the source file & line of the "else" */
42     struct conditional_frame *previous_cframe;
43     int else_seen;              /* have we seen an else yet? */
44     int ignoring;               /* if we are currently ignoring input. */
45     int dead_tree;              /* if a conditional at a higher level is ignoring input. */
46   };                            /* conditional_frame */
47
48 static void initialize_cframe PARAMS ((struct conditional_frame *cframe));
49
50 static struct conditional_frame *current_cframe = NULL;
51
52 void
53 s_ifdef (arg)
54      int arg;
55 {
56   register char *name;          /* points to name of symbol */
57   register struct symbol *symbolP;      /* Points to symbol */
58   struct conditional_frame cframe;
59
60   SKIP_WHITESPACE ();           /* Leading whitespace is part of operand. */
61   name = input_line_pointer;
62
63   if (!is_name_beginner (*name))
64     {
65       as_bad ("invalid identifier for \".ifdef\"");
66       obstack_1grow (&cond_obstack, 0);
67     }
68   else
69     {
70       get_symbol_end ();
71       ++input_line_pointer;
72       symbolP = symbol_find (name);
73
74       initialize_cframe (&cframe);
75       cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg);
76       current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe));
77     }                           /* if a valid identifyer name */
78
79   return;
80 }                               /* s_ifdef() */
81
82 void
83 s_if (arg)
84      int arg;
85 {
86   expressionS operand;
87   struct conditional_frame cframe;
88
89   SKIP_WHITESPACE ();           /* Leading whitespace is part of operand. */
90   expression (&operand);
91
92 #ifdef notyet
93   if (operand.X_op != O_constant)
94     as_bad ("non-constant expression in \".if\" statement");
95 #else
96   if (operand.X_add_symbol != NULL || operand.X_subtract_symbol != NULL) {
97         as_bad("non-constant expression in \".if\" statement");
98   } /* bad condition */
99 #endif
100
101   /* If the above error is signaled, this will dispatch
102      using an undefined result.  No big deal.  */
103   initialize_cframe (&cframe);
104   cframe.ignoring = cframe.dead_tree || !((operand.X_add_number != 0) ^ arg);
105   current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe));
106   return;
107 }                               /* s_if() */
108
109 void
110 s_endif (arg)
111      int arg;
112 {
113   struct conditional_frame *hold;
114
115   if (current_cframe == NULL)
116     {
117       as_bad ("\".endif\" without \".if\"");
118     }
119   else
120     {
121       hold = current_cframe;
122       current_cframe = current_cframe->previous_cframe;
123       obstack_free (&cond_obstack, hold);
124     }                           /* if one pop too many */
125
126   return;
127 }                               /* s_endif() */
128
129 void
130 s_else (arg)
131      int arg;
132 {
133   if (current_cframe == NULL)
134     {
135       as_bad (".else without matching .if - ignored");
136
137     }
138   else if (current_cframe->else_seen)
139     {
140       as_bad ("duplicate \"else\" - ignored");
141       as_bad_where (current_cframe->else_file_line.file,
142                     current_cframe->else_file_line.line,
143                     "here is the previous \"else\"");
144       as_bad_where (current_cframe->if_file_line.file,
145                     current_cframe->if_file_line.line,
146                     "here is the previous \"if\"");
147     }
148   else
149     {
150       as_where (&current_cframe->else_file_line.file,
151                 &current_cframe->else_file_line.line);
152
153       if (!current_cframe->dead_tree)
154         {
155           current_cframe->ignoring = !current_cframe->ignoring;
156         }                       /* if not a dead tree */
157
158       current_cframe->else_seen = 1;
159     }                           /* if error else do it */
160
161   return;
162 }                               /* s_else() */
163
164 void
165 s_ifeqs (arg)
166      int arg;
167 {
168   as_bad ("ifeqs not implemented.");
169
170   return;
171 }                               /* s_ifeqs() */
172
173 void
174 s_end (arg)
175      int arg;
176 {
177   return;
178 }                               /* s_end() */
179
180 int
181 ignore_input ()
182 {
183   /* We cannot ignore certain pseudo ops.  */
184   if (input_line_pointer[-1] == '.'
185       && ((input_line_pointer[0] == 'i'
186            && (!strncmp (input_line_pointer, "if", 2)
187                || !strncmp (input_line_pointer, "ifdef", 5)
188                || !strncmp (input_line_pointer, "ifndef", 6)))
189           || (input_line_pointer[0] == 'e'
190               && (!strncmp (input_line_pointer, "else", 4)
191                   || !strncmp (input_line_pointer, "endif", 5)))))
192     {
193       return 0;
194     }
195
196   return ((current_cframe != NULL) && (current_cframe->ignoring));
197 }                               /* ignore_input() */
198
199 static void
200 initialize_cframe (cframe)
201      struct conditional_frame *cframe;
202 {
203   memset (cframe, 0, sizeof (*cframe));
204   as_where (&cframe->if_file_line.file,
205             &cframe->if_file_line.line);
206   cframe->previous_cframe = current_cframe;
207   cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring;
208
209   return;
210 }                               /* initialize_cframe() */
211
212 /*
213  * Local Variables:
214  * fill-column: 131
215  * comment-column: 0
216  * End:
217  */
218
219 /* end of cond.c */