listing.c revision 1.1.1.9 1 1.1 skrll /* listing.c - maintain assembly listings
2 1.1.1.9 christos Copyright (C) 1991-2024 Free Software Foundation, Inc.
3 1.1 skrll
4 1.1 skrll This file is part of GAS, the GNU Assembler.
5 1.1 skrll
6 1.1 skrll GAS is free software; you can redistribute it and/or modify
7 1.1 skrll it under the terms of the GNU General Public License as published by
8 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
9 1.1 skrll any later version.
10 1.1 skrll
11 1.1 skrll GAS is distributed in the hope that it will be useful,
12 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 skrll GNU General Public License for more details.
15 1.1 skrll
16 1.1 skrll You should have received a copy of the GNU General Public License
17 1.1 skrll along with GAS; see the file COPYING. If not, write to the Free
18 1.1 skrll Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 1.1 skrll 02110-1301, USA. */
20 1.1 skrll
21 1.1 skrll /* Contributed by Steve Chamberlain <sac (at) cygnus.com>
22 1.1 skrll
23 1.1 skrll A listing page looks like:
24 1.1 skrll
25 1.1 skrll LISTING_HEADER sourcefilename pagenumber
26 1.1 skrll TITLE LINE
27 1.1 skrll SUBTITLE LINE
28 1.1 skrll linenumber address data source
29 1.1 skrll linenumber address data source
30 1.1 skrll linenumber address data source
31 1.1 skrll linenumber address data source
32 1.1 skrll
33 1.1 skrll If not overridden, the listing commands are:
34 1.1 skrll
35 1.1 skrll .title "stuff"
36 1.1 skrll Put "stuff" onto the title line
37 1.1 skrll .sbttl "stuff"
38 1.1 skrll Put stuff onto the subtitle line
39 1.1 skrll
40 1.1 skrll If these commands come within 10 lines of the top of the page, they
41 1.1 skrll will affect the page they are on, as well as any subsequent page
42 1.1 skrll
43 1.1 skrll .eject
44 1.1.1.6 christos Throw a page
45 1.1 skrll .list
46 1.1 skrll Increment the enable listing counter
47 1.1 skrll .nolist
48 1.1 skrll Decrement the enable listing counter
49 1.1 skrll
50 1.1 skrll .psize Y[,X]
51 1.1 skrll Set the paper size to X wide and Y high. Setting a psize Y of
52 1.1 skrll zero will suppress form feeds except where demanded by .eject
53 1.1 skrll
54 1.1 skrll If the counter goes below zero, listing is suppressed.
55 1.1 skrll
56 1.1 skrll Listings are a maintained by read calling various listing_<foo>
57 1.1 skrll functions. What happens most is that the macro NO_LISTING is not
58 1.1 skrll defined (from the Makefile), then the macro LISTING_NEWLINE expands
59 1.1 skrll into a call to listing_newline. The call is done from read.c, every
60 1.1 skrll time it sees a newline, and -l is on the command line.
61 1.1 skrll
62 1.1 skrll The function listing_newline remembers the frag associated with the
63 1.1 skrll newline, and creates a new frag - note that this is wasteful, but not
64 1.1 skrll a big deal, since listing slows things down a lot anyway. The
65 1.1 skrll function also remembers when the filename changes.
66 1.1 skrll
67 1.1 skrll When all the input has finished, and gas has had a chance to settle
68 1.1 skrll down, the listing is output. This is done by running down the list of
69 1.1 skrll frag/source file records, and opening the files as needed and printing
70 1.1 skrll out the bytes and chars associated with them.
71 1.1 skrll
72 1.1 skrll The only things which the architecture can change about the listing
73 1.1 skrll are defined in these macros:
74 1.1 skrll
75 1.1 skrll LISTING_HEADER The name of the architecture
76 1.1 skrll LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
77 1.1 skrll the clumping of the output data. eg a value of
78 1.1 skrll 2 makes words look like 1234 5678, whilst 1
79 1.1 skrll would make the same value look like 12 34 56
80 1.1 skrll 78
81 1.1 skrll LISTING_LHS_WIDTH Number of words of above size for the lhs
82 1.1 skrll
83 1.1 skrll LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
84 1.1 skrll for the second line
85 1.1 skrll
86 1.1 skrll LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation
87 1.1 skrll LISTING_RHS_WIDTH Number of chars from the input file to print
88 1.1 skrll on a line. */
89 1.1 skrll
90 1.1 skrll #include "as.h"
91 1.1.1.3 christos #include "filenames.h"
92 1.1 skrll #include "safe-ctype.h"
93 1.1 skrll #include "input-file.h"
94 1.1 skrll #include "subsegs.h"
95 1.1 skrll #include "bfdver.h"
96 1.1 skrll #include <time.h>
97 1.1.1.2 christos #include <stdarg.h>
98 1.1 skrll
99 1.1 skrll #ifndef NO_LISTING
100 1.1 skrll
101 1.1 skrll #ifndef LISTING_HEADER
102 1.1 skrll #define LISTING_HEADER "GAS LISTING"
103 1.1 skrll #endif
104 1.1 skrll #ifndef LISTING_WORD_SIZE
105 1.1 skrll #define LISTING_WORD_SIZE 4
106 1.1 skrll #endif
107 1.1 skrll #ifndef LISTING_LHS_WIDTH
108 1.1 skrll #define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
109 1.1 skrll #endif
110 1.1 skrll #ifndef LISTING_LHS_WIDTH_SECOND
111 1.1 skrll #define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
112 1.1 skrll #endif
113 1.1 skrll #ifndef LISTING_RHS_WIDTH
114 1.1 skrll #define LISTING_RHS_WIDTH 100
115 1.1 skrll #endif
116 1.1 skrll #ifndef LISTING_LHS_CONT_LINES
117 1.1 skrll #define LISTING_LHS_CONT_LINES 4
118 1.1 skrll #endif
119 1.1 skrll #define MAX_DATELEN 30
120 1.1 skrll
121 1.1 skrll /* This structure remembers which .s were used. */
122 1.1 skrll typedef struct file_info_struct
123 1.1 skrll {
124 1.1 skrll struct file_info_struct * next;
125 1.1 skrll char * filename;
126 1.1 skrll long pos;
127 1.1 skrll unsigned int linenum;
128 1.1 skrll int at_end;
129 1.1 skrll } file_info_type;
130 1.1 skrll
131 1.1.1.2 christos enum edict_enum
132 1.1.1.2 christos {
133 1.1.1.2 christos EDICT_NONE,
134 1.1.1.2 christos EDICT_SBTTL,
135 1.1.1.2 christos EDICT_TITLE,
136 1.1.1.2 christos EDICT_NOLIST,
137 1.1.1.2 christos EDICT_LIST,
138 1.1.1.2 christos EDICT_NOLIST_NEXT,
139 1.1.1.2 christos EDICT_EJECT
140 1.1.1.2 christos };
141 1.1.1.2 christos
142 1.1.1.2 christos
143 1.1.1.3 christos struct list_message
144 1.1.1.3 christos {
145 1.1.1.3 christos char *message;
146 1.1.1.3 christos struct list_message *next;
147 1.1.1.3 christos };
148 1.1.1.3 christos
149 1.1 skrll /* This structure remembers which line from which file goes into which
150 1.1 skrll frag. */
151 1.1 skrll struct list_info_struct
152 1.1 skrll {
153 1.1 skrll /* Frag which this line of source is nearest to. */
154 1.1 skrll fragS *frag;
155 1.1 skrll
156 1.1 skrll /* The actual line in the source file. */
157 1.1 skrll unsigned int line;
158 1.1 skrll
159 1.1 skrll /* Pointer to the file info struct for the file which this line
160 1.1 skrll belongs to. */
161 1.1 skrll file_info_type *file;
162 1.1 skrll
163 1.1 skrll /* The expanded text of any macro that may have been executing. */
164 1.1 skrll char *line_contents;
165 1.1 skrll
166 1.1 skrll /* Next in list. */
167 1.1 skrll struct list_info_struct *next;
168 1.1 skrll
169 1.1 skrll /* Pointer to the file info struct for the high level language
170 1.1 skrll source line that belongs here. */
171 1.1 skrll file_info_type *hll_file;
172 1.1 skrll
173 1.1 skrll /* High level language source line. */
174 1.1 skrll unsigned int hll_line;
175 1.1 skrll
176 1.1.1.3 christos /* Pointers to linked list of messages associated with this line. */
177 1.1.1.3 christos struct list_message *messages, *last_message;
178 1.1 skrll
179 1.1.1.2 christos enum edict_enum edict;
180 1.1 skrll char *edict_arg;
181 1.1 skrll
182 1.1 skrll /* Nonzero if this line is to be omitted because it contains
183 1.1 skrll debugging information. This can become a flags field if we come
184 1.1 skrll up with more information to store here. */
185 1.1 skrll int debugging;
186 1.1 skrll };
187 1.1 skrll
188 1.1 skrll typedef struct list_info_struct list_info_type;
189 1.1 skrll
190 1.1 skrll int listing_lhs_width = LISTING_LHS_WIDTH;
191 1.1 skrll int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
192 1.1 skrll int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES;
193 1.1 skrll int listing_rhs_width = LISTING_RHS_WIDTH;
194 1.1 skrll
195 1.1 skrll struct list_info_struct * listing_tail;
196 1.1 skrll
197 1.1 skrll static file_info_type * file_info_head;
198 1.1 skrll static file_info_type * last_open_file_info;
199 1.1 skrll static FILE * last_open_file;
200 1.1 skrll static struct list_info_struct * head;
201 1.1 skrll static int paper_width = 200;
202 1.1 skrll static int paper_height = 60;
203 1.1 skrll
204 1.1 skrll extern int listing;
205 1.1 skrll
206 1.1 skrll /* File to output listings to. */
207 1.1 skrll static FILE *list_file;
208 1.1 skrll
209 1.1 skrll /* This static array is used to keep the text of data to be printed
210 1.1 skrll before the start of the line. */
211 1.1 skrll
212 1.1 skrll #define MAX_BYTES \
213 1.1 skrll (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \
214 1.1 skrll + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \
215 1.1 skrll * listing_lhs_cont_lines) \
216 1.1 skrll + 20)
217 1.1 skrll
218 1.1 skrll static char *data_buffer;
219 1.1 skrll
220 1.1 skrll /* Prototypes. */
221 1.1 skrll static void listing_message (const char *, const char *);
222 1.1 skrll static file_info_type *file_info (const char *);
223 1.1 skrll static void new_frag (void);
224 1.1 skrll static void listing_page (list_info_type *);
225 1.1 skrll static unsigned int calc_hex (list_info_type *);
226 1.1.1.5 christos static void print_lines (list_info_type *, unsigned int, const char *,
227 1.1.1.5 christos unsigned int);
228 1.1 skrll static void list_symbol_table (void);
229 1.1 skrll static int debugging_pseudo (list_info_type *, const char *);
230 1.1 skrll static void listing_listing (char *);
231 1.1 skrll
232 1.1 skrll static void
233 1.1 skrll listing_message (const char *name, const char *message)
234 1.1 skrll {
235 1.1 skrll if (listing_tail != (list_info_type *) NULL)
236 1.1 skrll {
237 1.1.1.5 christos char *n = concat (name, message, (char *) NULL);
238 1.1.1.5 christos struct list_message *lm = XNEW (struct list_message);
239 1.1.1.3 christos lm->message = n;
240 1.1.1.3 christos lm->next = NULL;
241 1.1.1.3 christos
242 1.1.1.3 christos if (listing_tail->last_message)
243 1.1.1.3 christos listing_tail->last_message->next = lm;
244 1.1.1.3 christos else
245 1.1.1.3 christos listing_tail->messages = lm;
246 1.1.1.3 christos listing_tail->last_message = lm;
247 1.1 skrll }
248 1.1 skrll }
249 1.1 skrll
250 1.1 skrll void
251 1.1 skrll listing_warning (const char *message)
252 1.1 skrll {
253 1.1.1.4 christos listing_message (_("Warning: "), message);
254 1.1 skrll }
255 1.1 skrll
256 1.1 skrll void
257 1.1 skrll listing_error (const char *message)
258 1.1 skrll {
259 1.1.1.4 christos listing_message (_("Error: "), message);
260 1.1 skrll }
261 1.1 skrll
262 1.1 skrll static file_info_type *
263 1.1 skrll file_info (const char *file_name)
264 1.1 skrll {
265 1.1 skrll /* Find an entry with this file name. */
266 1.1 skrll file_info_type *p = file_info_head;
267 1.1 skrll
268 1.1 skrll while (p != (file_info_type *) NULL)
269 1.1 skrll {
270 1.1.1.3 christos if (filename_cmp (p->filename, file_name) == 0)
271 1.1 skrll return p;
272 1.1 skrll p = p->next;
273 1.1 skrll }
274 1.1 skrll
275 1.1 skrll /* Make new entry. */
276 1.1.1.5 christos p = XNEW (file_info_type);
277 1.1 skrll p->next = file_info_head;
278 1.1 skrll file_info_head = p;
279 1.1 skrll p->filename = xstrdup (file_name);
280 1.1 skrll p->pos = 0;
281 1.1 skrll p->linenum = 0;
282 1.1 skrll p->at_end = 0;
283 1.1 skrll
284 1.1 skrll return p;
285 1.1 skrll }
286 1.1 skrll
287 1.1 skrll static void
288 1.1 skrll new_frag (void)
289 1.1 skrll {
290 1.1 skrll frag_wane (frag_now);
291 1.1 skrll frag_new (0);
292 1.1 skrll }
293 1.1 skrll
294 1.1 skrll void
295 1.1 skrll listing_newline (char *ps)
296 1.1 skrll {
297 1.1.1.5 christos const char *file;
298 1.1 skrll unsigned int line;
299 1.1 skrll static unsigned int last_line = 0xffff;
300 1.1.1.5 christos static const char *last_file = NULL;
301 1.1.1.2 christos list_info_type *new_i = NULL;
302 1.1 skrll
303 1.1 skrll if (listing == 0)
304 1.1 skrll return;
305 1.1 skrll
306 1.1 skrll if (now_seg == absolute_section)
307 1.1 skrll return;
308 1.1 skrll
309 1.1 skrll #ifdef OBJ_ELF
310 1.1 skrll /* In ELF, anything in a section beginning with .debug or .line is
311 1.1 skrll considered to be debugging information. This includes the
312 1.1 skrll statement which switches us into the debugging section, which we
313 1.1 skrll can only set after we are already in the debugging section. */
314 1.1 skrll if ((listing & LISTING_NODEBUG) != 0
315 1.1 skrll && listing_tail != NULL
316 1.1 skrll && ! listing_tail->debugging)
317 1.1 skrll {
318 1.1 skrll const char *segname;
319 1.1 skrll
320 1.1 skrll segname = segment_name (now_seg);
321 1.1.1.8 christos if (startswith (segname, ".debug")
322 1.1.1.8 christos || startswith (segname, ".line"))
323 1.1 skrll listing_tail->debugging = 1;
324 1.1 skrll }
325 1.1 skrll #endif
326 1.1 skrll
327 1.1.1.6 christos /* PR 21977 - use the physical file name not the logical one unless high
328 1.1.1.6 christos level source files are being included in the listing. */
329 1.1.1.6 christos if (listing & LISTING_HLL)
330 1.1.1.6 christos file = as_where (&line);
331 1.1.1.6 christos else
332 1.1.1.6 christos file = as_where_physical (&line);
333 1.1.1.6 christos
334 1.1 skrll if (ps == NULL)
335 1.1 skrll {
336 1.1 skrll if (line == last_line
337 1.1.1.3 christos && !(last_file && file && filename_cmp (file, last_file)))
338 1.1 skrll return;
339 1.1 skrll
340 1.1.1.5 christos new_i = XNEW (list_info_type);
341 1.1 skrll
342 1.1 skrll /* Detect if we are reading from stdin by examining the file
343 1.1 skrll name returned by as_where().
344 1.1 skrll
345 1.1 skrll [FIXME: We rely upon the name in the strcmp below being the
346 1.1 skrll same as the one used by input_scrub_new_file(), if that is
347 1.1 skrll not true, then this code will fail].
348 1.1 skrll
349 1.1 skrll If we are reading from stdin, then we need to save each input
350 1.1 skrll line here (assuming of course that we actually have a line of
351 1.1 skrll input to read), so that it can be displayed in the listing
352 1.1 skrll that is produced at the end of the assembly. */
353 1.1 skrll if (strcmp (file, _("{standard input}")) == 0
354 1.1 skrll && input_line_pointer != NULL)
355 1.1 skrll {
356 1.1.1.5 christos char *copy, *src, *dest;
357 1.1 skrll int len;
358 1.1 skrll int seen_quote = 0;
359 1.1.1.2 christos int seen_slash = 0;
360 1.1 skrll
361 1.1.1.2 christos for (copy = input_line_pointer;
362 1.1 skrll *copy && (seen_quote
363 1.1.1.2 christos || is_end_of_line [(unsigned char) *copy] != 1);
364 1.1 skrll copy++)
365 1.1.1.2 christos {
366 1.1.1.2 christos if (seen_slash)
367 1.1.1.2 christos seen_slash = 0;
368 1.1.1.2 christos else if (*copy == '\\')
369 1.1.1.2 christos seen_slash = 1;
370 1.1.1.2 christos else if (*copy == '"')
371 1.1.1.2 christos seen_quote = !seen_quote;
372 1.1.1.2 christos }
373 1.1 skrll
374 1.1.1.2 christos len = copy - input_line_pointer + 1;
375 1.1 skrll
376 1.1.1.5 christos copy = XNEWVEC (char, len);
377 1.1 skrll
378 1.1.1.5 christos src = input_line_pointer;
379 1.1.1.5 christos dest = copy;
380 1.1 skrll
381 1.1.1.5 christos while (--len)
382 1.1.1.5 christos {
383 1.1.1.5 christos unsigned char c = *src++;
384 1.1 skrll
385 1.1.1.5 christos /* Omit control characters in the listing. */
386 1.1.1.5 christos if (!ISCNTRL (c))
387 1.1.1.5 christos *dest++ = c;
388 1.1 skrll }
389 1.1 skrll
390 1.1.1.5 christos *dest = 0;
391 1.1.1.5 christos
392 1.1.1.2 christos new_i->line_contents = copy;
393 1.1 skrll }
394 1.1 skrll else
395 1.1.1.2 christos new_i->line_contents = NULL;
396 1.1 skrll }
397 1.1 skrll else
398 1.1 skrll {
399 1.1.1.5 christos new_i = XNEW (list_info_type);
400 1.1.1.2 christos new_i->line_contents = ps;
401 1.1 skrll }
402 1.1 skrll
403 1.1 skrll last_line = line;
404 1.1 skrll last_file = file;
405 1.1 skrll
406 1.1 skrll new_frag ();
407 1.1 skrll
408 1.1 skrll if (listing_tail)
409 1.1.1.2 christos listing_tail->next = new_i;
410 1.1 skrll else
411 1.1.1.2 christos head = new_i;
412 1.1 skrll
413 1.1.1.2 christos listing_tail = new_i;
414 1.1 skrll
415 1.1.1.2 christos new_i->frag = frag_now;
416 1.1.1.2 christos new_i->line = line;
417 1.1.1.2 christos new_i->file = file_info (file);
418 1.1.1.2 christos new_i->next = (list_info_type *) NULL;
419 1.1.1.3 christos new_i->messages = NULL;
420 1.1.1.3 christos new_i->last_message = NULL;
421 1.1.1.2 christos new_i->edict = EDICT_NONE;
422 1.1.1.2 christos new_i->hll_file = (file_info_type *) NULL;
423 1.1.1.2 christos new_i->hll_line = 0;
424 1.1.1.2 christos new_i->debugging = 0;
425 1.1 skrll
426 1.1 skrll new_frag ();
427 1.1 skrll
428 1.1 skrll #ifdef OBJ_ELF
429 1.1 skrll /* In ELF, anything in a section beginning with .debug or .line is
430 1.1 skrll considered to be debugging information. */
431 1.1 skrll if ((listing & LISTING_NODEBUG) != 0)
432 1.1 skrll {
433 1.1 skrll const char *segname;
434 1.1 skrll
435 1.1 skrll segname = segment_name (now_seg);
436 1.1.1.8 christos if (startswith (segname, ".debug")
437 1.1.1.8 christos || startswith (segname, ".line"))
438 1.1.1.2 christos new_i->debugging = 1;
439 1.1 skrll }
440 1.1 skrll #endif
441 1.1 skrll }
442 1.1 skrll
443 1.1 skrll /* Attach all current frags to the previous line instead of the
444 1.1 skrll current line. This is called by the MIPS backend when it discovers
445 1.1 skrll that it needs to add some NOP instructions; the added NOP
446 1.1 skrll instructions should go with the instruction that has the delay, not
447 1.1 skrll with the new instruction. */
448 1.1 skrll
449 1.1 skrll void
450 1.1 skrll listing_prev_line (void)
451 1.1 skrll {
452 1.1 skrll list_info_type *l;
453 1.1 skrll fragS *f;
454 1.1 skrll
455 1.1 skrll if (head == (list_info_type *) NULL
456 1.1 skrll || head == listing_tail)
457 1.1 skrll return;
458 1.1 skrll
459 1.1 skrll new_frag ();
460 1.1 skrll
461 1.1 skrll for (l = head; l->next != listing_tail; l = l->next)
462 1.1 skrll ;
463 1.1 skrll
464 1.1 skrll for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
465 1.1 skrll if (f->line == listing_tail)
466 1.1 skrll f->line = l;
467 1.1 skrll
468 1.1 skrll listing_tail->frag = frag_now;
469 1.1 skrll new_frag ();
470 1.1 skrll }
471 1.1 skrll
472 1.1 skrll /* This function returns the next source line from the file supplied,
473 1.1 skrll truncated to size. It appends a fake line to the end of each input
474 1.1.1.2 christos file to make using the returned buffer simpler. */
475 1.1 skrll
476 1.1.1.5 christos static const char *
477 1.1 skrll buffer_line (file_info_type *file, char *line, unsigned int size)
478 1.1 skrll {
479 1.1 skrll unsigned int count = 0;
480 1.1 skrll int c;
481 1.1 skrll char *p = line;
482 1.1 skrll
483 1.1 skrll /* If we couldn't open the file, return an empty line. */
484 1.1 skrll if (file->at_end)
485 1.1 skrll return "";
486 1.1 skrll
487 1.1 skrll /* Check the cache and see if we last used this file. */
488 1.1 skrll if (!last_open_file_info || file != last_open_file_info)
489 1.1 skrll {
490 1.1 skrll if (last_open_file)
491 1.1 skrll {
492 1.1 skrll last_open_file_info->pos = ftell (last_open_file);
493 1.1 skrll fclose (last_open_file);
494 1.1 skrll }
495 1.1 skrll
496 1.1.1.2 christos /* Open the file in the binary mode so that ftell above can
497 1.1.1.2 christos return a reliable value that we can feed to fseek below. */
498 1.1 skrll last_open_file_info = file;
499 1.1.1.2 christos last_open_file = fopen (file->filename, FOPEN_RB);
500 1.1 skrll if (last_open_file == NULL)
501 1.1 skrll {
502 1.1 skrll file->at_end = 1;
503 1.1 skrll return "";
504 1.1 skrll }
505 1.1 skrll
506 1.1 skrll /* Seek to where we were last time this file was open. */
507 1.1 skrll if (file->pos)
508 1.1 skrll fseek (last_open_file, file->pos, SEEK_SET);
509 1.1 skrll }
510 1.1 skrll
511 1.1.1.2 christos c = fgetc (last_open_file);
512 1.1.1.2 christos
513 1.1.1.2 christos while (c != EOF && c != '\n' && c != '\r')
514 1.1 skrll {
515 1.1.1.8 christos if (++count < size)
516 1.1 skrll *p++ = c;
517 1.1 skrll c = fgetc (last_open_file);
518 1.1.1.2 christos }
519 1.1 skrll
520 1.1.1.2 christos /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
521 1.1.1.2 christos is followed by '\r', swallow that as well. */
522 1.1.1.2 christos if (c == '\r' || c == '\n')
523 1.1.1.2 christos {
524 1.1.1.2 christos int next = fgetc (last_open_file);
525 1.1.1.2 christos
526 1.1.1.2 christos if ((c == '\r' && next != '\n')
527 1.1.1.2 christos || (c == '\n' && next != '\r'))
528 1.1.1.2 christos ungetc (next, last_open_file);
529 1.1 skrll }
530 1.1.1.2 christos
531 1.1 skrll if (c == EOF)
532 1.1 skrll {
533 1.1 skrll file->at_end = 1;
534 1.1.1.8 christos if (count + 3 < size)
535 1.1 skrll {
536 1.1 skrll *p++ = '.';
537 1.1 skrll *p++ = '.';
538 1.1 skrll *p++ = '.';
539 1.1 skrll }
540 1.1 skrll }
541 1.1 skrll file->linenum++;
542 1.1 skrll *p++ = 0;
543 1.1 skrll return line;
544 1.1 skrll }
545 1.1 skrll
546 1.1.1.2 christos
547 1.1.1.2 christos /* This function rewinds the requested file back to the line requested,
548 1.1.1.2 christos reads it in again into the buffer provided and then restores the file
549 1.1.1.5 christos back to its original location. */
550 1.1.1.2 christos
551 1.1.1.5 christos static void
552 1.1.1.2 christos rebuffer_line (file_info_type * file,
553 1.1.1.2 christos unsigned int linenum,
554 1.1.1.2 christos char * buffer,
555 1.1.1.2 christos unsigned int size)
556 1.1.1.2 christos {
557 1.1.1.2 christos unsigned int count = 0;
558 1.1.1.4 christos unsigned int current_line;
559 1.1.1.2 christos char * p = buffer;
560 1.1.1.2 christos long pos;
561 1.1.1.4 christos long pos2;
562 1.1.1.2 christos int c;
563 1.1.1.8 christos bool found = false;
564 1.1.1.2 christos
565 1.1.1.2 christos /* Sanity checks. */
566 1.1.1.4 christos if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum)
567 1.1.1.5 christos return;
568 1.1.1.2 christos
569 1.1.1.2 christos /* Check the cache and see if we last used this file. */
570 1.1.1.2 christos if (last_open_file_info == NULL || file != last_open_file_info)
571 1.1.1.2 christos {
572 1.1.1.2 christos if (last_open_file)
573 1.1.1.2 christos {
574 1.1.1.2 christos last_open_file_info->pos = ftell (last_open_file);
575 1.1.1.2 christos fclose (last_open_file);
576 1.1.1.2 christos }
577 1.1.1.2 christos
578 1.1.1.2 christos /* Open the file in the binary mode so that ftell above can
579 1.1.1.2 christos return a reliable value that we can feed to fseek below. */
580 1.1.1.2 christos last_open_file_info = file;
581 1.1.1.2 christos last_open_file = fopen (file->filename, FOPEN_RB);
582 1.1.1.2 christos if (last_open_file == NULL)
583 1.1.1.2 christos {
584 1.1.1.2 christos file->at_end = 1;
585 1.1.1.5 christos return;
586 1.1.1.2 christos }
587 1.1.1.2 christos
588 1.1.1.2 christos /* Seek to where we were last time this file was open. */
589 1.1.1.2 christos if (file->pos)
590 1.1.1.2 christos fseek (last_open_file, file->pos, SEEK_SET);
591 1.1.1.2 christos }
592 1.1.1.2 christos
593 1.1.1.2 christos /* Remember where we are in the current file. */
594 1.1.1.4 christos pos2 = pos = ftell (last_open_file);
595 1.1.1.4 christos if (pos < 3)
596 1.1.1.5 christos return;
597 1.1.1.4 christos current_line = file->linenum;
598 1.1.1.2 christos
599 1.1.1.4 christos /* Leave room for the nul at the end of the buffer. */
600 1.1.1.4 christos size -= 1;
601 1.1.1.4 christos buffer[size] = 0;
602 1.1.1.2 christos
603 1.1.1.4 christos /* Increment the current line count by one.
604 1.1.1.4 christos This is to allow for the fact that we are searching for the
605 1.1.1.4 christos start of a previous line, but we do this by detecting end-of-line
606 1.1.1.4 christos character(s) not start-of-line characters. */
607 1.1.1.4 christos ++ current_line;
608 1.1.1.4 christos
609 1.1.1.4 christos while (pos2 > 0 && ! found)
610 1.1.1.2 christos {
611 1.1.1.4 christos char * ptr;
612 1.1.1.4 christos
613 1.1.1.4 christos /* Move backwards through the file, looking for earlier lines. */
614 1.1.1.4 christos pos2 = (long) size > pos2 ? 0 : pos2 - size;
615 1.1.1.4 christos fseek (last_open_file, pos2, SEEK_SET);
616 1.1.1.4 christos
617 1.1.1.4 christos /* Our caller has kindly provided us with a buffer, so we use it. */
618 1.1.1.4 christos if (fread (buffer, 1, size, last_open_file) != size)
619 1.1.1.2 christos {
620 1.1.1.4 christos as_warn (_("unable to rebuffer file: %s\n"), file->filename);
621 1.1.1.5 christos return;
622 1.1.1.2 christos }
623 1.1.1.2 christos
624 1.1.1.4 christos for (ptr = buffer + size; ptr >= buffer; -- ptr)
625 1.1.1.2 christos {
626 1.1.1.4 christos if (*ptr == '\n')
627 1.1.1.4 christos {
628 1.1.1.4 christos -- current_line;
629 1.1.1.2 christos
630 1.1.1.4 christos if (current_line == linenum)
631 1.1.1.4 christos {
632 1.1.1.4 christos /* We have found the start of the line we seek. */
633 1.1.1.8 christos found = true;
634 1.1.1.4 christos
635 1.1.1.4 christos /* FIXME: We could skip the read-in-the-line code
636 1.1.1.4 christos below if we know that we already have the whole
637 1.1.1.4 christos line in the buffer. */
638 1.1.1.4 christos
639 1.1.1.4 christos /* Advance pos2 to the newline character we have just located. */
640 1.1.1.4 christos pos2 += (ptr - buffer);
641 1.1.1.4 christos
642 1.1.1.4 christos /* Skip the newline and, if present, the carriage return. */
643 1.1.1.4 christos if (ptr + 1 == buffer + size)
644 1.1.1.4 christos {
645 1.1.1.4 christos ++pos2;
646 1.1.1.4 christos if (fgetc (last_open_file) == '\r')
647 1.1.1.4 christos ++ pos2;
648 1.1.1.4 christos }
649 1.1.1.4 christos else
650 1.1.1.4 christos pos2 += (ptr[1] == '\r' ? 2 : 1);
651 1.1.1.4 christos
652 1.1.1.4 christos /* Move the file pointer to this location. */
653 1.1.1.4 christos fseek (last_open_file, pos2, SEEK_SET);
654 1.1.1.4 christos break;
655 1.1.1.4 christos }
656 1.1.1.4 christos }
657 1.1.1.2 christos }
658 1.1.1.2 christos }
659 1.1.1.2 christos
660 1.1.1.2 christos /* Read in the line. */
661 1.1.1.2 christos c = fgetc (last_open_file);
662 1.1.1.2 christos
663 1.1.1.2 christos while (c != EOF && c != '\n' && c != '\r')
664 1.1.1.2 christos {
665 1.1.1.2 christos if (count < size)
666 1.1.1.2 christos *p++ = c;
667 1.1.1.2 christos count++;
668 1.1.1.2 christos
669 1.1.1.2 christos c = fgetc (last_open_file);
670 1.1.1.2 christos }
671 1.1.1.2 christos
672 1.1.1.2 christos /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
673 1.1.1.2 christos is followed by '\r', swallow that as well. */
674 1.1.1.2 christos if (c == '\r' || c == '\n')
675 1.1.1.2 christos {
676 1.1.1.2 christos int next = fgetc (last_open_file);
677 1.1.1.2 christos
678 1.1.1.2 christos if ((c == '\r' && next != '\n')
679 1.1.1.2 christos || (c == '\n' && next != '\r'))
680 1.1.1.2 christos ungetc (next, last_open_file);
681 1.1.1.2 christos }
682 1.1.1.2 christos
683 1.1.1.2 christos /* Terminate the line. */
684 1.1.1.2 christos *p++ = 0;
685 1.1.1.2 christos
686 1.1.1.2 christos /* Reset the file position. */
687 1.1.1.2 christos fseek (last_open_file, pos, SEEK_SET);
688 1.1.1.2 christos }
689 1.1.1.2 christos
690 1.1 skrll static const char *fn;
691 1.1.1.5 christos static unsigned int eject; /* Eject pending. */
692 1.1.1.5 christos static unsigned int page; /* Current page number. */
693 1.1.1.5 christos static const char *title; /* Current title. */
694 1.1.1.5 christos static const char *subtitle; /* Current subtitle. */
695 1.1.1.5 christos static unsigned int on_page; /* Number of lines printed on current page. */
696 1.1 skrll
697 1.1 skrll static void
698 1.1 skrll listing_page (list_info_type *list)
699 1.1 skrll {
700 1.1 skrll /* Grope around, see if we can see a title or subtitle edict coming up
701 1.1 skrll soon. (we look down 10 lines of the page and see if it's there) */
702 1.1 skrll if ((eject || (on_page >= (unsigned int) paper_height))
703 1.1 skrll && paper_height != 0)
704 1.1 skrll {
705 1.1 skrll unsigned int c = 10;
706 1.1 skrll int had_title = 0;
707 1.1 skrll int had_subtitle = 0;
708 1.1 skrll
709 1.1 skrll page++;
710 1.1 skrll
711 1.1 skrll while (c != 0 && list)
712 1.1 skrll {
713 1.1 skrll if (list->edict == EDICT_SBTTL && !had_subtitle)
714 1.1 skrll {
715 1.1 skrll had_subtitle = 1;
716 1.1 skrll subtitle = list->edict_arg;
717 1.1 skrll }
718 1.1 skrll if (list->edict == EDICT_TITLE && !had_title)
719 1.1 skrll {
720 1.1 skrll had_title = 1;
721 1.1 skrll title = list->edict_arg;
722 1.1 skrll }
723 1.1 skrll list = list->next;
724 1.1 skrll c--;
725 1.1 skrll }
726 1.1 skrll
727 1.1 skrll if (page > 1)
728 1.1 skrll {
729 1.1 skrll fprintf (list_file, "\f");
730 1.1 skrll }
731 1.1 skrll
732 1.1 skrll fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
733 1.1 skrll fprintf (list_file, "%s\n", title);
734 1.1 skrll fprintf (list_file, "%s\n", subtitle);
735 1.1 skrll on_page = 3;
736 1.1 skrll eject = 0;
737 1.1 skrll }
738 1.1 skrll }
739 1.1 skrll
740 1.1.1.2 christos /* Print a line into the list_file. Update the line count
741 1.1.1.2 christos and if necessary start a new page. */
742 1.1.1.2 christos
743 1.1.1.2 christos static void
744 1.1.1.2 christos emit_line (list_info_type * list, const char * format, ...)
745 1.1.1.2 christos {
746 1.1.1.2 christos va_list args;
747 1.1.1.2 christos
748 1.1.1.2 christos va_start (args, format);
749 1.1.1.2 christos
750 1.1.1.2 christos vfprintf (list_file, format, args);
751 1.1.1.2 christos on_page++;
752 1.1.1.2 christos listing_page (list);
753 1.1.1.2 christos
754 1.1.1.2 christos va_end (args);
755 1.1.1.2 christos }
756 1.1.1.2 christos
757 1.1 skrll static unsigned int
758 1.1 skrll calc_hex (list_info_type *list)
759 1.1 skrll {
760 1.1 skrll int data_buffer_size;
761 1.1 skrll list_info_type *first = list;
762 1.1 skrll unsigned int address = ~(unsigned int) 0;
763 1.1 skrll fragS *frag;
764 1.1 skrll fragS *frag_ptr;
765 1.1 skrll unsigned int octet_in_frag;
766 1.1 skrll
767 1.1 skrll /* Find first frag which says it belongs to this line. */
768 1.1 skrll frag = list->frag;
769 1.1 skrll while (frag && frag->line != list)
770 1.1 skrll frag = frag->fr_next;
771 1.1 skrll
772 1.1 skrll frag_ptr = frag;
773 1.1 skrll
774 1.1 skrll data_buffer_size = 0;
775 1.1 skrll
776 1.1 skrll /* Dump all the frags which belong to this line. */
777 1.1 skrll while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
778 1.1 skrll {
779 1.1 skrll /* Print as many bytes from the fixed part as is sensible. */
780 1.1 skrll octet_in_frag = 0;
781 1.1.1.7 christos while (octet_in_frag < frag_ptr->fr_fix
782 1.1 skrll && data_buffer_size < MAX_BYTES - 3)
783 1.1 skrll {
784 1.1 skrll if (address == ~(unsigned int) 0)
785 1.1 skrll address = frag_ptr->fr_address / OCTETS_PER_BYTE;
786 1.1 skrll
787 1.1 skrll sprintf (data_buffer + data_buffer_size,
788 1.1 skrll "%02X",
789 1.1 skrll (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
790 1.1 skrll data_buffer_size += 2;
791 1.1 skrll octet_in_frag++;
792 1.1 skrll }
793 1.1 skrll if (frag_ptr->fr_type == rs_fill)
794 1.1 skrll {
795 1.1 skrll unsigned int var_rep_max = octet_in_frag;
796 1.1 skrll unsigned int var_rep_idx = octet_in_frag;
797 1.1 skrll
798 1.1 skrll /* Print as many bytes from the variable part as is sensible. */
799 1.1.1.7 christos while ((octet_in_frag
800 1.1.1.7 christos < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)
801 1.1 skrll && data_buffer_size < MAX_BYTES - 3)
802 1.1 skrll {
803 1.1 skrll if (address == ~(unsigned int) 0)
804 1.1 skrll address = frag_ptr->fr_address / OCTETS_PER_BYTE;
805 1.1 skrll
806 1.1 skrll sprintf (data_buffer + data_buffer_size,
807 1.1 skrll "%02X",
808 1.1 skrll (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
809 1.1 skrll data_buffer_size += 2;
810 1.1 skrll
811 1.1 skrll var_rep_idx++;
812 1.1 skrll octet_in_frag++;
813 1.1 skrll
814 1.1.1.7 christos if (var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
815 1.1 skrll var_rep_idx = var_rep_max;
816 1.1 skrll }
817 1.1 skrll }
818 1.1.1.9 christos else if (frag_ptr->fr_type == rs_fill_nop && frag_ptr->fr_opcode)
819 1.1.1.9 christos {
820 1.1.1.9 christos gas_assert (!octet_in_frag);
821 1.1.1.9 christos
822 1.1.1.9 christos /* Print as many bytes from fr_opcode as is sensible. */
823 1.1.1.9 christos while (octet_in_frag < (unsigned int) frag_ptr->fr_offset
824 1.1.1.9 christos && data_buffer_size < MAX_BYTES - 3)
825 1.1.1.9 christos {
826 1.1.1.9 christos if (address == ~(unsigned int) 0)
827 1.1.1.9 christos address = frag_ptr->fr_address / OCTETS_PER_BYTE;
828 1.1.1.9 christos
829 1.1.1.9 christos sprintf (data_buffer + data_buffer_size,
830 1.1.1.9 christos "%02X",
831 1.1.1.9 christos frag_ptr->fr_opcode[octet_in_frag] & 0xff);
832 1.1.1.9 christos data_buffer_size += 2;
833 1.1.1.9 christos
834 1.1.1.9 christos octet_in_frag++;
835 1.1.1.9 christos }
836 1.1.1.9 christos
837 1.1.1.9 christos free (frag_ptr->fr_opcode);
838 1.1.1.9 christos frag_ptr->fr_opcode = NULL;
839 1.1.1.9 christos }
840 1.1 skrll
841 1.1 skrll frag_ptr = frag_ptr->fr_next;
842 1.1 skrll }
843 1.1 skrll data_buffer[data_buffer_size] = '\0';
844 1.1 skrll return address;
845 1.1 skrll }
846 1.1 skrll
847 1.1 skrll static void
848 1.1 skrll print_lines (list_info_type *list, unsigned int lineno,
849 1.1.1.5 christos const char *string, unsigned int address)
850 1.1 skrll {
851 1.1 skrll unsigned int idx;
852 1.1 skrll unsigned int nchars;
853 1.1 skrll unsigned int lines;
854 1.1 skrll unsigned int octet_in_word = 0;
855 1.1 skrll char *src = data_buffer;
856 1.1 skrll int cur;
857 1.1.1.3 christos struct list_message *msg;
858 1.1 skrll
859 1.1 skrll /* Print the stuff on the first line. */
860 1.1 skrll listing_page (list);
861 1.1 skrll nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
862 1.1 skrll
863 1.1 skrll /* Print the hex for the first line. */
864 1.1 skrll if (address == ~(unsigned int) 0)
865 1.1 skrll {
866 1.1 skrll fprintf (list_file, "% 4d ", lineno);
867 1.1 skrll for (idx = 0; idx < nchars; idx++)
868 1.1 skrll fprintf (list_file, " ");
869 1.1 skrll
870 1.1.1.2 christos emit_line (NULL, "\t%s\n", string ? string : "");
871 1.1 skrll return;
872 1.1 skrll }
873 1.1 skrll
874 1.1 skrll if (had_errors ())
875 1.1 skrll fprintf (list_file, "% 4d ???? ", lineno);
876 1.1 skrll else
877 1.1 skrll fprintf (list_file, "% 4d %04x ", lineno, address);
878 1.1 skrll
879 1.1 skrll /* And the data to go along with it. */
880 1.1 skrll idx = 0;
881 1.1 skrll cur = 0;
882 1.1 skrll while (src[cur] && idx < nchars)
883 1.1 skrll {
884 1.1 skrll int offset;
885 1.1 skrll offset = cur;
886 1.1 skrll fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
887 1.1 skrll cur += 2;
888 1.1 skrll octet_in_word++;
889 1.1 skrll
890 1.1 skrll if (octet_in_word == LISTING_WORD_SIZE)
891 1.1 skrll {
892 1.1 skrll fprintf (list_file, " ");
893 1.1 skrll idx++;
894 1.1 skrll octet_in_word = 0;
895 1.1 skrll }
896 1.1 skrll
897 1.1 skrll idx += 2;
898 1.1 skrll }
899 1.1 skrll
900 1.1 skrll for (; idx < nchars; idx++)
901 1.1 skrll fprintf (list_file, " ");
902 1.1 skrll
903 1.1.1.2 christos emit_line (list, "\t%s\n", string ? string : "");
904 1.1 skrll
905 1.1.1.3 christos for (msg = list->messages; msg; msg = msg->next)
906 1.1.1.3 christos emit_line (list, "**** %s\n", msg->message);
907 1.1 skrll
908 1.1 skrll for (lines = 0;
909 1.1 skrll lines < (unsigned int) listing_lhs_cont_lines
910 1.1 skrll && src[cur];
911 1.1 skrll lines++)
912 1.1 skrll {
913 1.1 skrll nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
914 1.1 skrll idx = 0;
915 1.1 skrll
916 1.1 skrll /* Print any more lines of data, but more compactly. */
917 1.1 skrll fprintf (list_file, "% 4d ", lineno);
918 1.1 skrll
919 1.1 skrll while (src[cur] && idx < nchars)
920 1.1 skrll {
921 1.1 skrll int offset;
922 1.1 skrll offset = cur;
923 1.1 skrll fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
924 1.1 skrll cur += 2;
925 1.1 skrll idx += 2;
926 1.1 skrll octet_in_word++;
927 1.1 skrll
928 1.1 skrll if (octet_in_word == LISTING_WORD_SIZE)
929 1.1 skrll {
930 1.1 skrll fprintf (list_file, " ");
931 1.1 skrll idx++;
932 1.1 skrll octet_in_word = 0;
933 1.1 skrll }
934 1.1 skrll }
935 1.1 skrll
936 1.1.1.2 christos emit_line (list, "\n");
937 1.1 skrll }
938 1.1 skrll }
939 1.1 skrll
940 1.1 skrll static void
941 1.1 skrll list_symbol_table (void)
942 1.1 skrll {
943 1.1 skrll extern symbolS *symbol_rootP;
944 1.1 skrll int got_some = 0;
945 1.1 skrll
946 1.1 skrll symbolS *ptr;
947 1.1 skrll eject = 1;
948 1.1.1.2 christos listing_page (NULL);
949 1.1 skrll
950 1.1 skrll for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
951 1.1 skrll {
952 1.1 skrll if (SEG_NORMAL (S_GET_SEGMENT (ptr))
953 1.1 skrll || S_GET_SEGMENT (ptr) == absolute_section)
954 1.1 skrll {
955 1.1 skrll /* Don't report section symbols. They are not interesting. */
956 1.1 skrll if (symbol_section_p (ptr))
957 1.1 skrll continue;
958 1.1 skrll
959 1.1 skrll if (S_GET_NAME (ptr))
960 1.1 skrll {
961 1.1.1.9 christos char buf[30];
962 1.1 skrll valueT val = S_GET_VALUE (ptr);
963 1.1 skrll
964 1.1.1.9 christos bfd_sprintf_vma (stdoutput, buf, val);
965 1.1 skrll if (!got_some)
966 1.1 skrll {
967 1.1 skrll fprintf (list_file, "DEFINED SYMBOLS\n");
968 1.1 skrll on_page++;
969 1.1 skrll got_some = 1;
970 1.1 skrll }
971 1.1 skrll
972 1.1 skrll if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
973 1.1 skrll {
974 1.1 skrll fprintf (list_file, "%20s:%-5d %s:%s %s\n",
975 1.1 skrll symbol_get_frag (ptr)->line->file->filename,
976 1.1 skrll symbol_get_frag (ptr)->line->line,
977 1.1 skrll segment_name (S_GET_SEGMENT (ptr)),
978 1.1 skrll buf, S_GET_NAME (ptr));
979 1.1 skrll }
980 1.1 skrll else
981 1.1 skrll {
982 1.1 skrll fprintf (list_file, "%33s:%s %s\n",
983 1.1 skrll segment_name (S_GET_SEGMENT (ptr)),
984 1.1 skrll buf, S_GET_NAME (ptr));
985 1.1 skrll }
986 1.1 skrll
987 1.1 skrll on_page++;
988 1.1.1.2 christos listing_page (NULL);
989 1.1 skrll }
990 1.1 skrll }
991 1.1 skrll
992 1.1 skrll }
993 1.1 skrll if (!got_some)
994 1.1 skrll {
995 1.1 skrll fprintf (list_file, "NO DEFINED SYMBOLS\n");
996 1.1 skrll on_page++;
997 1.1 skrll }
998 1.1.1.2 christos emit_line (NULL, "\n");
999 1.1 skrll
1000 1.1 skrll got_some = 0;
1001 1.1 skrll
1002 1.1 skrll for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
1003 1.1 skrll {
1004 1.1 skrll if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
1005 1.1 skrll {
1006 1.1 skrll if (S_GET_SEGMENT (ptr) == undefined_section)
1007 1.1 skrll {
1008 1.1 skrll if (!got_some)
1009 1.1 skrll {
1010 1.1 skrll got_some = 1;
1011 1.1.1.2 christos
1012 1.1.1.2 christos emit_line (NULL, "UNDEFINED SYMBOLS\n");
1013 1.1 skrll }
1014 1.1.1.2 christos
1015 1.1.1.2 christos emit_line (NULL, "%s\n", S_GET_NAME (ptr));
1016 1.1 skrll }
1017 1.1 skrll }
1018 1.1 skrll }
1019 1.1.1.2 christos
1020 1.1 skrll if (!got_some)
1021 1.1.1.2 christos emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
1022 1.1 skrll }
1023 1.1 skrll
1024 1.1.1.2 christos typedef struct cached_line
1025 1.1 skrll {
1026 1.1.1.2 christos file_info_type * file;
1027 1.1.1.2 christos unsigned int line;
1028 1.1.1.2 christos char buffer [LISTING_RHS_WIDTH];
1029 1.1.1.2 christos } cached_line;
1030 1.1.1.2 christos
1031 1.1.1.2 christos static void
1032 1.1.1.2 christos print_source (file_info_type * current_file,
1033 1.1.1.2 christos list_info_type * list,
1034 1.1.1.2 christos unsigned int width)
1035 1.1.1.2 christos {
1036 1.1.1.2 christos #define NUM_CACHE_LINES 3
1037 1.1.1.2 christos static cached_line cached_lines[NUM_CACHE_LINES];
1038 1.1.1.2 christos static int next_free_line = 0;
1039 1.1.1.2 christos cached_line * cache = NULL;
1040 1.1.1.2 christos
1041 1.1.1.2 christos if (current_file->linenum > list->hll_line
1042 1.1.1.2 christos && list->hll_line > 0)
1043 1.1.1.2 christos {
1044 1.1.1.2 christos /* This can happen with modern optimizing compilers. The source
1045 1.1.1.2 christos lines from the high level language input program are split up
1046 1.1.1.2 christos and interleaved, meaning the line number we want to display
1047 1.1.1.2 christos (list->hll_line) can have already been displayed. We have
1048 1.1.1.2 christos three choices:
1049 1.1.1.2 christos
1050 1.1.1.2 christos a. Do nothing, since we have already displayed the source
1051 1.1.1.2 christos line. This was the old behaviour.
1052 1.1.1.2 christos
1053 1.1.1.2 christos b. Display the particular line requested again, but only
1054 1.1.1.2 christos that line. This is the new behaviour.
1055 1.1.1.2 christos
1056 1.1.1.2 christos c. Display the particular line requested again and reset
1057 1.1.1.2 christos the current_file->line_num value so that we redisplay
1058 1.1.1.2 christos all the following lines as well the next time we
1059 1.1.1.2 christos encounter a larger line number. */
1060 1.1.1.2 christos int i;
1061 1.1.1.2 christos
1062 1.1.1.2 christos /* Check the cache, maybe we already have the line saved. */
1063 1.1.1.2 christos for (i = 0; i < NUM_CACHE_LINES; i++)
1064 1.1.1.2 christos if (cached_lines[i].file == current_file
1065 1.1.1.2 christos && cached_lines[i].line == list->hll_line)
1066 1.1.1.2 christos {
1067 1.1.1.2 christos cache = cached_lines + i;
1068 1.1.1.2 christos break;
1069 1.1.1.2 christos }
1070 1.1.1.2 christos
1071 1.1.1.2 christos if (i == NUM_CACHE_LINES)
1072 1.1.1.2 christos {
1073 1.1.1.2 christos cache = cached_lines + next_free_line;
1074 1.1.1.2 christos next_free_line ++;
1075 1.1.1.2 christos if (next_free_line == NUM_CACHE_LINES)
1076 1.1.1.2 christos next_free_line = 0;
1077 1.1.1.2 christos
1078 1.1.1.2 christos cache->file = current_file;
1079 1.1.1.2 christos cache->line = list->hll_line;
1080 1.1.1.2 christos cache->buffer[0] = 0;
1081 1.1.1.2 christos rebuffer_line (current_file, cache->line, cache->buffer, width);
1082 1.1.1.2 christos }
1083 1.1.1.2 christos
1084 1.1.1.2 christos emit_line (list, "%4u:%-13s **** %s\n",
1085 1.1.1.2 christos cache->line, cache->file->filename, cache->buffer);
1086 1.1.1.2 christos return;
1087 1.1.1.2 christos }
1088 1.1.1.2 christos
1089 1.1 skrll if (!current_file->at_end)
1090 1.1 skrll {
1091 1.1.1.2 christos int num_lines_shown = 0;
1092 1.1.1.2 christos
1093 1.1 skrll while (current_file->linenum < list->hll_line
1094 1.1 skrll && !current_file->at_end)
1095 1.1 skrll {
1096 1.1.1.5 christos const char *p;
1097 1.1.1.2 christos
1098 1.1.1.2 christos cache = cached_lines + next_free_line;
1099 1.1.1.2 christos cache->file = current_file;
1100 1.1.1.2 christos cache->line = current_file->linenum + 1;
1101 1.1.1.2 christos cache->buffer[0] = 0;
1102 1.1.1.2 christos p = buffer_line (current_file, cache->buffer, width);
1103 1.1.1.2 christos
1104 1.1.1.2 christos /* Cache optimization: If printing a group of lines
1105 1.1.1.2 christos cache the first and last lines in the group. */
1106 1.1.1.2 christos if (num_lines_shown == 0)
1107 1.1.1.2 christos {
1108 1.1.1.2 christos next_free_line ++;
1109 1.1.1.2 christos if (next_free_line == NUM_CACHE_LINES)
1110 1.1.1.2 christos next_free_line = 0;
1111 1.1.1.2 christos }
1112 1.1 skrll
1113 1.1.1.2 christos emit_line (list, "%4u:%-13s **** %s\n",
1114 1.1.1.2 christos cache->line, cache->file->filename, p);
1115 1.1.1.2 christos num_lines_shown ++;
1116 1.1 skrll }
1117 1.1 skrll }
1118 1.1 skrll }
1119 1.1 skrll
1120 1.1 skrll /* Sometimes the user doesn't want to be bothered by the debugging
1121 1.1 skrll records inserted by the compiler, see if the line is suspicious. */
1122 1.1 skrll
1123 1.1 skrll static int
1124 1.1 skrll debugging_pseudo (list_info_type *list, const char *line)
1125 1.1 skrll {
1126 1.1.1.2 christos #ifdef OBJ_ELF
1127 1.1 skrll static int in_debug;
1128 1.1 skrll int was_debug;
1129 1.1.1.2 christos #endif
1130 1.1 skrll
1131 1.1 skrll if (list->debugging)
1132 1.1 skrll {
1133 1.1.1.2 christos #ifdef OBJ_ELF
1134 1.1 skrll in_debug = 1;
1135 1.1.1.2 christos #endif
1136 1.1 skrll return 1;
1137 1.1 skrll }
1138 1.1.1.2 christos #ifdef OBJ_ELF
1139 1.1 skrll was_debug = in_debug;
1140 1.1 skrll in_debug = 0;
1141 1.1.1.2 christos #endif
1142 1.1 skrll
1143 1.1 skrll while (ISSPACE (*line))
1144 1.1 skrll line++;
1145 1.1 skrll
1146 1.1 skrll if (*line != '.')
1147 1.1 skrll {
1148 1.1 skrll #ifdef OBJ_ELF
1149 1.1 skrll /* The ELF compiler sometimes emits blank lines after switching
1150 1.1 skrll out of a debugging section. If the next line drops us back
1151 1.1 skrll into debugging information, then don't print the blank line.
1152 1.1 skrll This is a hack for a particular compiler behaviour, not a
1153 1.1 skrll general case. */
1154 1.1 skrll if (was_debug
1155 1.1 skrll && *line == '\0'
1156 1.1 skrll && list->next != NULL
1157 1.1 skrll && list->next->debugging)
1158 1.1 skrll {
1159 1.1 skrll in_debug = 1;
1160 1.1 skrll return 1;
1161 1.1 skrll }
1162 1.1 skrll #endif
1163 1.1 skrll
1164 1.1 skrll return 0;
1165 1.1 skrll }
1166 1.1 skrll
1167 1.1 skrll line++;
1168 1.1 skrll
1169 1.1.1.8 christos if (startswith (line, "def"))
1170 1.1 skrll return 1;
1171 1.1.1.8 christos if (startswith (line, "val"))
1172 1.1 skrll return 1;
1173 1.1.1.8 christos if (startswith (line, "scl"))
1174 1.1 skrll return 1;
1175 1.1.1.8 christos if (startswith (line, "line"))
1176 1.1 skrll return 1;
1177 1.1.1.8 christos if (startswith (line, "endef"))
1178 1.1 skrll return 1;
1179 1.1.1.8 christos if (startswith (line, "ln"))
1180 1.1 skrll return 1;
1181 1.1.1.8 christos if (startswith (line, "type"))
1182 1.1 skrll return 1;
1183 1.1.1.8 christos if (startswith (line, "size"))
1184 1.1 skrll return 1;
1185 1.1.1.8 christos if (startswith (line, "dim"))
1186 1.1 skrll return 1;
1187 1.1.1.8 christos if (startswith (line, "tag"))
1188 1.1 skrll return 1;
1189 1.1.1.8 christos if (startswith (line, "stabs"))
1190 1.1 skrll return 1;
1191 1.1.1.8 christos if (startswith (line, "stabn"))
1192 1.1 skrll return 1;
1193 1.1 skrll
1194 1.1 skrll return 0;
1195 1.1 skrll }
1196 1.1 skrll
1197 1.1 skrll static void
1198 1.1 skrll listing_listing (char *name ATTRIBUTE_UNUSED)
1199 1.1 skrll {
1200 1.1 skrll list_info_type *list = head;
1201 1.1 skrll file_info_type *current_hll_file = (file_info_type *) NULL;
1202 1.1 skrll char *buffer;
1203 1.1.1.5 christos const char *p;
1204 1.1 skrll int show_listing = 1;
1205 1.1 skrll unsigned int width;
1206 1.1 skrll
1207 1.1.1.5 christos buffer = XNEWVEC (char, listing_rhs_width);
1208 1.1.1.5 christos data_buffer = XNEWVEC (char, MAX_BYTES);
1209 1.1 skrll eject = 1;
1210 1.1 skrll list = head->next;
1211 1.1 skrll
1212 1.1 skrll while (list)
1213 1.1 skrll {
1214 1.1 skrll unsigned int list_line;
1215 1.1 skrll
1216 1.1 skrll width = listing_rhs_width > paper_width ? paper_width :
1217 1.1 skrll listing_rhs_width;
1218 1.1 skrll
1219 1.1 skrll list_line = list->line;
1220 1.1 skrll switch (list->edict)
1221 1.1 skrll {
1222 1.1 skrll case EDICT_LIST:
1223 1.1 skrll /* Skip all lines up to the current. */
1224 1.1 skrll list_line--;
1225 1.1 skrll break;
1226 1.1 skrll case EDICT_NOLIST:
1227 1.1 skrll show_listing--;
1228 1.1 skrll break;
1229 1.1 skrll case EDICT_NOLIST_NEXT:
1230 1.1 skrll if (show_listing == 0)
1231 1.1 skrll list_line--;
1232 1.1 skrll break;
1233 1.1 skrll case EDICT_EJECT:
1234 1.1 skrll break;
1235 1.1 skrll case EDICT_NONE:
1236 1.1 skrll break;
1237 1.1 skrll case EDICT_TITLE:
1238 1.1 skrll title = list->edict_arg;
1239 1.1 skrll break;
1240 1.1 skrll case EDICT_SBTTL:
1241 1.1 skrll subtitle = list->edict_arg;
1242 1.1 skrll break;
1243 1.1 skrll default:
1244 1.1 skrll abort ();
1245 1.1 skrll }
1246 1.1 skrll
1247 1.1 skrll if (show_listing <= 0)
1248 1.1 skrll {
1249 1.1 skrll while (list->file->linenum < list_line
1250 1.1 skrll && !list->file->at_end)
1251 1.1 skrll p = buffer_line (list->file, buffer, width);
1252 1.1 skrll }
1253 1.1 skrll
1254 1.1 skrll if (list->edict == EDICT_LIST
1255 1.1 skrll || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1256 1.1 skrll {
1257 1.1 skrll /* Enable listing for the single line that caused the enable. */
1258 1.1 skrll list_line++;
1259 1.1 skrll show_listing++;
1260 1.1 skrll }
1261 1.1 skrll
1262 1.1 skrll if (show_listing > 0)
1263 1.1 skrll {
1264 1.1 skrll /* Scan down the list and print all the stuff which can be done
1265 1.1 skrll with this line (or lines). */
1266 1.1 skrll if (list->hll_file)
1267 1.1 skrll current_hll_file = list->hll_file;
1268 1.1 skrll
1269 1.1 skrll if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1270 1.1.1.2 christos print_source (current_hll_file, list, width);
1271 1.1 skrll
1272 1.1.1.9 christos if (!list->line_contents || list->file->linenum)
1273 1.1 skrll {
1274 1.1 skrll while (list->file->linenum < list_line
1275 1.1 skrll && !list->file->at_end)
1276 1.1 skrll {
1277 1.1 skrll unsigned int address;
1278 1.1 skrll
1279 1.1 skrll p = buffer_line (list->file, buffer, width);
1280 1.1 skrll
1281 1.1 skrll if (list->file->linenum < list_line)
1282 1.1 skrll address = ~(unsigned int) 0;
1283 1.1 skrll else
1284 1.1 skrll address = calc_hex (list);
1285 1.1 skrll
1286 1.1 skrll if (!((listing & LISTING_NODEBUG)
1287 1.1 skrll && debugging_pseudo (list, p)))
1288 1.1 skrll print_lines (list, list->file->linenum, p, address);
1289 1.1 skrll }
1290 1.1 skrll }
1291 1.1 skrll
1292 1.1.1.9 christos if (list->line_contents)
1293 1.1.1.9 christos {
1294 1.1.1.9 christos if (!((listing & LISTING_NODEBUG)
1295 1.1.1.9 christos && debugging_pseudo (list, list->line_contents)))
1296 1.1.1.9 christos print_lines (list, list->line, list->line_contents,
1297 1.1.1.9 christos calc_hex (list));
1298 1.1.1.9 christos
1299 1.1.1.9 christos free (list->line_contents);
1300 1.1.1.9 christos list->line_contents = NULL;
1301 1.1.1.9 christos }
1302 1.1.1.9 christos
1303 1.1 skrll if (list->edict == EDICT_EJECT)
1304 1.1 skrll eject = 1;
1305 1.1 skrll }
1306 1.1 skrll
1307 1.1 skrll if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1308 1.1 skrll --show_listing;
1309 1.1 skrll
1310 1.1 skrll list = list->next;
1311 1.1 skrll }
1312 1.1 skrll
1313 1.1 skrll free (buffer);
1314 1.1 skrll free (data_buffer);
1315 1.1 skrll data_buffer = NULL;
1316 1.1 skrll }
1317 1.1 skrll
1318 1.1 skrll /* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */
1319 1.1 skrll
1320 1.1 skrll static void
1321 1.1 skrll print_timestamp (void)
1322 1.1 skrll {
1323 1.1 skrll const time_t now = time (NULL);
1324 1.1 skrll struct tm * timestamp;
1325 1.1 skrll char stampstr[MAX_DATELEN];
1326 1.1 skrll
1327 1.1 skrll /* Any portable way to obtain subsecond values??? */
1328 1.1 skrll timestamp = localtime (&now);
1329 1.1 skrll strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1330 1.1 skrll fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr);
1331 1.1 skrll }
1332 1.1 skrll
1333 1.1 skrll static void
1334 1.1 skrll print_single_option (char * opt, int *pos)
1335 1.1 skrll {
1336 1.1 skrll int opt_len = strlen (opt);
1337 1.1 skrll
1338 1.1 skrll if ((*pos + opt_len) < paper_width)
1339 1.1 skrll {
1340 1.1 skrll fprintf (list_file, _("%s "), opt);
1341 1.1 skrll *pos = *pos + opt_len;
1342 1.1 skrll }
1343 1.1 skrll else
1344 1.1 skrll {
1345 1.1 skrll fprintf (list_file, _("\n\t%s "), opt);
1346 1.1 skrll *pos = opt_len;
1347 1.1 skrll }
1348 1.1 skrll }
1349 1.1 skrll
1350 1.1 skrll /* Print options passed to as. */
1351 1.1 skrll
1352 1.1 skrll static void
1353 1.1 skrll print_options (char ** argv)
1354 1.1 skrll {
1355 1.1 skrll const char *field_name = _("\n options passed\t: ");
1356 1.1 skrll int pos = strlen (field_name);
1357 1.1 skrll char **p;
1358 1.1 skrll
1359 1.1 skrll fputs (field_name, list_file);
1360 1.1 skrll for (p = &argv[1]; *p != NULL; p++)
1361 1.1 skrll if (**p == '-')
1362 1.1 skrll {
1363 1.1 skrll /* Ignore these. */
1364 1.1 skrll if (strcmp (*p, "-o") == 0)
1365 1.1 skrll {
1366 1.1 skrll if (p[1] != NULL)
1367 1.1 skrll p++;
1368 1.1 skrll continue;
1369 1.1 skrll }
1370 1.1 skrll if (strcmp (*p, "-v") == 0)
1371 1.1 skrll continue;
1372 1.1 skrll
1373 1.1 skrll print_single_option (*p, &pos);
1374 1.1 skrll }
1375 1.1 skrll }
1376 1.1 skrll
1377 1.1 skrll /* Print a first section with basic info like file names, as version,
1378 1.1 skrll options passed, target, and timestamp.
1379 1.1 skrll The format of this section is as follows:
1380 1.1 skrll
1381 1.1 skrll AS VERSION
1382 1.1 skrll
1383 1.1 skrll fieldname TAB ':' fieldcontents
1384 1.1 skrll { TAB fieldcontents-cont } */
1385 1.1 skrll
1386 1.1 skrll static void
1387 1.1 skrll listing_general_info (char ** argv)
1388 1.1 skrll {
1389 1.1 skrll /* Print the stuff on the first line. */
1390 1.1 skrll eject = 1;
1391 1.1.1.2 christos listing_page (NULL);
1392 1.1 skrll
1393 1.1 skrll fprintf (list_file,
1394 1.1 skrll _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1395 1.1 skrll VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1396 1.1 skrll print_options (argv);
1397 1.1 skrll fprintf (list_file, _("\n input file \t: %s"), fn);
1398 1.1 skrll fprintf (list_file, _("\n output file \t: %s"), out_file_name);
1399 1.1 skrll fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL);
1400 1.1 skrll print_timestamp ();
1401 1.1 skrll }
1402 1.1 skrll
1403 1.1 skrll void
1404 1.1 skrll listing_print (char *name, char **argv)
1405 1.1 skrll {
1406 1.1 skrll int using_stdout;
1407 1.1 skrll
1408 1.1 skrll title = "";
1409 1.1 skrll subtitle = "";
1410 1.1 skrll
1411 1.1 skrll if (name == NULL)
1412 1.1 skrll {
1413 1.1 skrll list_file = stdout;
1414 1.1 skrll using_stdout = 1;
1415 1.1 skrll }
1416 1.1 skrll else
1417 1.1 skrll {
1418 1.1 skrll list_file = fopen (name, FOPEN_WT);
1419 1.1 skrll if (list_file != NULL)
1420 1.1 skrll using_stdout = 0;
1421 1.1 skrll else
1422 1.1 skrll {
1423 1.1 skrll as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1424 1.1 skrll list_file = stdout;
1425 1.1 skrll using_stdout = 1;
1426 1.1 skrll }
1427 1.1 skrll }
1428 1.1 skrll
1429 1.1 skrll if (listing & LISTING_NOFORM)
1430 1.1 skrll paper_height = 0;
1431 1.1 skrll
1432 1.1 skrll if (listing & LISTING_GENERAL)
1433 1.1 skrll listing_general_info (argv);
1434 1.1 skrll
1435 1.1 skrll if (listing & LISTING_LISTING)
1436 1.1 skrll listing_listing (name);
1437 1.1 skrll
1438 1.1 skrll if (listing & LISTING_SYMBOLS)
1439 1.1 skrll list_symbol_table ();
1440 1.1 skrll
1441 1.1 skrll if (! using_stdout)
1442 1.1 skrll {
1443 1.1 skrll if (fclose (list_file) == EOF)
1444 1.1 skrll as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1445 1.1 skrll }
1446 1.1 skrll
1447 1.1 skrll if (last_open_file)
1448 1.1 skrll fclose (last_open_file);
1449 1.1 skrll }
1450 1.1 skrll
1451 1.1 skrll void
1452 1.1 skrll listing_file (const char *name)
1453 1.1 skrll {
1454 1.1 skrll fn = name;
1455 1.1 skrll }
1456 1.1 skrll
1457 1.1 skrll void
1458 1.1 skrll listing_eject (int ignore ATTRIBUTE_UNUSED)
1459 1.1 skrll {
1460 1.1 skrll if (listing)
1461 1.1 skrll listing_tail->edict = EDICT_EJECT;
1462 1.1 skrll }
1463 1.1 skrll
1464 1.1 skrll /* Turn listing on or off. An argument of 0 means to turn off
1465 1.1 skrll listing. An argument of 1 means to turn on listing. An argument
1466 1.1 skrll of 2 means to turn off listing, but as of the next line; that is,
1467 1.1 skrll the current line should be listed, but the next line should not. */
1468 1.1 skrll
1469 1.1 skrll void
1470 1.1 skrll listing_list (int on)
1471 1.1 skrll {
1472 1.1 skrll if (listing)
1473 1.1 skrll {
1474 1.1 skrll switch (on)
1475 1.1 skrll {
1476 1.1 skrll case 0:
1477 1.1 skrll if (listing_tail->edict == EDICT_LIST)
1478 1.1 skrll listing_tail->edict = EDICT_NONE;
1479 1.1 skrll else
1480 1.1 skrll listing_tail->edict = EDICT_NOLIST;
1481 1.1 skrll break;
1482 1.1 skrll case 1:
1483 1.1 skrll if (listing_tail->edict == EDICT_NOLIST
1484 1.1 skrll || listing_tail->edict == EDICT_NOLIST_NEXT)
1485 1.1 skrll listing_tail->edict = EDICT_NONE;
1486 1.1 skrll else
1487 1.1 skrll listing_tail->edict = EDICT_LIST;
1488 1.1 skrll break;
1489 1.1 skrll case 2:
1490 1.1 skrll listing_tail->edict = EDICT_NOLIST_NEXT;
1491 1.1 skrll break;
1492 1.1 skrll default:
1493 1.1 skrll abort ();
1494 1.1 skrll }
1495 1.1 skrll }
1496 1.1 skrll }
1497 1.1 skrll
1498 1.1 skrll void
1499 1.1 skrll listing_psize (int width_only)
1500 1.1 skrll {
1501 1.1 skrll if (! width_only)
1502 1.1 skrll {
1503 1.1 skrll paper_height = get_absolute_expression ();
1504 1.1 skrll
1505 1.1 skrll if (paper_height < 0 || paper_height > 1000)
1506 1.1 skrll {
1507 1.1 skrll paper_height = 0;
1508 1.1 skrll as_warn (_("strange paper height, set to no form"));
1509 1.1 skrll }
1510 1.1 skrll
1511 1.1 skrll if (*input_line_pointer != ',')
1512 1.1 skrll {
1513 1.1 skrll demand_empty_rest_of_line ();
1514 1.1 skrll return;
1515 1.1 skrll }
1516 1.1 skrll
1517 1.1 skrll ++input_line_pointer;
1518 1.1 skrll }
1519 1.1 skrll
1520 1.1.1.8 christos {
1521 1.1.1.8 christos expressionS exp;
1522 1.1.1.8 christos
1523 1.1.1.8 christos (void) expression_and_evaluate (& exp);
1524 1.1.1.8 christos
1525 1.1.1.8 christos if (exp.X_op == O_constant)
1526 1.1.1.8 christos {
1527 1.1.1.8 christos offsetT new_width = exp.X_add_number;
1528 1.1.1.8 christos
1529 1.1.1.8 christos if (new_width > 7)
1530 1.1.1.8 christos paper_width = new_width;
1531 1.1.1.8 christos else
1532 1.1.1.8 christos as_bad (_("new paper width is too small"));
1533 1.1.1.8 christos }
1534 1.1.1.8 christos else if (exp.X_op != O_absent)
1535 1.1.1.8 christos as_bad (_("bad or irreducible expression for paper width"));
1536 1.1.1.8 christos else
1537 1.1.1.8 christos as_bad (_("missing expression for paper width"));
1538 1.1.1.8 christos }
1539 1.1 skrll
1540 1.1 skrll demand_empty_rest_of_line ();
1541 1.1 skrll }
1542 1.1 skrll
1543 1.1 skrll void
1544 1.1 skrll listing_nopage (int ignore ATTRIBUTE_UNUSED)
1545 1.1 skrll {
1546 1.1 skrll paper_height = 0;
1547 1.1 skrll }
1548 1.1 skrll
1549 1.1 skrll void
1550 1.1 skrll listing_title (int depth)
1551 1.1 skrll {
1552 1.1 skrll int quoted;
1553 1.1 skrll char *start;
1554 1.1 skrll char *ttl;
1555 1.1 skrll unsigned int length;
1556 1.1 skrll
1557 1.1 skrll SKIP_WHITESPACE ();
1558 1.1 skrll if (*input_line_pointer != '\"')
1559 1.1 skrll quoted = 0;
1560 1.1 skrll else
1561 1.1 skrll {
1562 1.1 skrll quoted = 1;
1563 1.1 skrll ++input_line_pointer;
1564 1.1 skrll }
1565 1.1 skrll
1566 1.1 skrll start = input_line_pointer;
1567 1.1 skrll
1568 1.1 skrll while (*input_line_pointer)
1569 1.1 skrll {
1570 1.1 skrll if (quoted
1571 1.1 skrll ? *input_line_pointer == '\"'
1572 1.1 skrll : is_end_of_line[(unsigned char) *input_line_pointer])
1573 1.1 skrll {
1574 1.1 skrll if (listing)
1575 1.1 skrll {
1576 1.1 skrll length = input_line_pointer - start;
1577 1.1.1.5 christos ttl = xmemdup0 (start, length);
1578 1.1 skrll listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1579 1.1 skrll listing_tail->edict_arg = ttl;
1580 1.1 skrll }
1581 1.1 skrll if (quoted)
1582 1.1 skrll input_line_pointer++;
1583 1.1 skrll demand_empty_rest_of_line ();
1584 1.1 skrll return;
1585 1.1 skrll }
1586 1.1 skrll else if (*input_line_pointer == '\n')
1587 1.1 skrll {
1588 1.1 skrll as_bad (_("new line in title"));
1589 1.1 skrll demand_empty_rest_of_line ();
1590 1.1 skrll return;
1591 1.1 skrll }
1592 1.1 skrll else
1593 1.1 skrll {
1594 1.1 skrll input_line_pointer++;
1595 1.1 skrll }
1596 1.1 skrll }
1597 1.1 skrll }
1598 1.1 skrll
1599 1.1 skrll void
1600 1.1 skrll listing_source_line (unsigned int line)
1601 1.1 skrll {
1602 1.1 skrll if (listing)
1603 1.1 skrll {
1604 1.1 skrll new_frag ();
1605 1.1 skrll listing_tail->hll_line = line;
1606 1.1 skrll new_frag ();
1607 1.1 skrll }
1608 1.1 skrll }
1609 1.1 skrll
1610 1.1 skrll void
1611 1.1 skrll listing_source_file (const char *file)
1612 1.1 skrll {
1613 1.1 skrll if (listing)
1614 1.1 skrll listing_tail->hll_file = file_info (file);
1615 1.1 skrll }
1616 1.1 skrll
1617 1.1 skrll #else
1618 1.1 skrll
1619 1.1 skrll /* Dummy functions for when compiled without listing enabled. */
1620 1.1 skrll
1621 1.1 skrll void
1622 1.1 skrll listing_list (int on)
1623 1.1 skrll {
1624 1.1 skrll s_ignore (0);
1625 1.1 skrll }
1626 1.1 skrll
1627 1.1 skrll void
1628 1.1 skrll listing_eject (int ignore)
1629 1.1 skrll {
1630 1.1 skrll s_ignore (0);
1631 1.1 skrll }
1632 1.1 skrll
1633 1.1 skrll void
1634 1.1 skrll listing_psize (int ignore)
1635 1.1 skrll {
1636 1.1 skrll s_ignore (0);
1637 1.1 skrll }
1638 1.1 skrll
1639 1.1 skrll void
1640 1.1 skrll listing_nopage (int ignore)
1641 1.1 skrll {
1642 1.1 skrll s_ignore (0);
1643 1.1 skrll }
1644 1.1 skrll
1645 1.1 skrll void
1646 1.1 skrll listing_title (int depth)
1647 1.1 skrll {
1648 1.1 skrll s_ignore (0);
1649 1.1 skrll }
1650 1.1 skrll
1651 1.1 skrll void
1652 1.1 skrll listing_file (const char *name)
1653 1.1 skrll {
1654 1.1 skrll }
1655 1.1 skrll
1656 1.1 skrll void
1657 1.1 skrll listing_newline (char *name)
1658 1.1 skrll {
1659 1.1 skrll }
1660 1.1 skrll
1661 1.1 skrll void
1662 1.1 skrll listing_source_line (unsigned int n)
1663 1.1 skrll {
1664 1.1 skrll }
1665 1.1 skrll
1666 1.1 skrll void
1667 1.1 skrll listing_source_file (const char *n)
1668 1.1 skrll {
1669 1.1 skrll }
1670 1.1 skrll
1671 1.1 skrll #endif
1672