listing.c revision 1.1.1.5.12.1 1 1.1 skrll /* listing.c - maintain assembly listings
2 1.1.1.5.12.1 pgoyette Copyright (C) 1991-2018 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.5.12.1 pgoyette 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 skrll if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
322 1.1 skrll || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
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.5.12.1 pgoyette /* PR 21977 - use the physical file name not the logical one unless high
328 1.1.1.5.12.1 pgoyette level source files are being included in the listing. */
329 1.1.1.5.12.1 pgoyette if (listing & LISTING_HLL)
330 1.1.1.5.12.1 pgoyette file = as_where (&line);
331 1.1.1.5.12.1 pgoyette else
332 1.1.1.5.12.1 pgoyette file = as_where_physical (&line);
333 1.1.1.5.12.1 pgoyette
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 skrll if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
437 1.1 skrll || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
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 skrll /* Leave room for null. */
512 1.1 skrll size -= 1;
513 1.1 skrll
514 1.1.1.2 christos c = fgetc (last_open_file);
515 1.1.1.2 christos
516 1.1.1.2 christos while (c != EOF && c != '\n' && c != '\r')
517 1.1 skrll {
518 1.1 skrll if (count < size)
519 1.1 skrll *p++ = c;
520 1.1 skrll count++;
521 1.1 skrll
522 1.1 skrll c = fgetc (last_open_file);
523 1.1.1.2 christos }
524 1.1 skrll
525 1.1.1.2 christos /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
526 1.1.1.2 christos is followed by '\r', swallow that as well. */
527 1.1.1.2 christos if (c == '\r' || c == '\n')
528 1.1.1.2 christos {
529 1.1.1.2 christos int next = fgetc (last_open_file);
530 1.1.1.2 christos
531 1.1.1.2 christos if ((c == '\r' && next != '\n')
532 1.1.1.2 christos || (c == '\n' && next != '\r'))
533 1.1.1.2 christos ungetc (next, last_open_file);
534 1.1 skrll }
535 1.1.1.2 christos
536 1.1 skrll if (c == EOF)
537 1.1 skrll {
538 1.1 skrll file->at_end = 1;
539 1.1 skrll if (count + 2 < size)
540 1.1 skrll {
541 1.1 skrll *p++ = '.';
542 1.1 skrll *p++ = '.';
543 1.1 skrll *p++ = '.';
544 1.1 skrll }
545 1.1 skrll }
546 1.1 skrll file->linenum++;
547 1.1 skrll *p++ = 0;
548 1.1 skrll return line;
549 1.1 skrll }
550 1.1 skrll
551 1.1.1.2 christos
552 1.1.1.2 christos /* This function rewinds the requested file back to the line requested,
553 1.1.1.2 christos reads it in again into the buffer provided and then restores the file
554 1.1.1.5 christos back to its original location. */
555 1.1.1.2 christos
556 1.1.1.5 christos static void
557 1.1.1.2 christos rebuffer_line (file_info_type * file,
558 1.1.1.2 christos unsigned int linenum,
559 1.1.1.2 christos char * buffer,
560 1.1.1.2 christos unsigned int size)
561 1.1.1.2 christos {
562 1.1.1.2 christos unsigned int count = 0;
563 1.1.1.4 christos unsigned int current_line;
564 1.1.1.2 christos char * p = buffer;
565 1.1.1.2 christos long pos;
566 1.1.1.4 christos long pos2;
567 1.1.1.2 christos int c;
568 1.1.1.4 christos bfd_boolean found = FALSE;
569 1.1.1.2 christos
570 1.1.1.2 christos /* Sanity checks. */
571 1.1.1.4 christos if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum)
572 1.1.1.5 christos return;
573 1.1.1.2 christos
574 1.1.1.2 christos /* Check the cache and see if we last used this file. */
575 1.1.1.2 christos if (last_open_file_info == NULL || file != last_open_file_info)
576 1.1.1.2 christos {
577 1.1.1.2 christos if (last_open_file)
578 1.1.1.2 christos {
579 1.1.1.2 christos last_open_file_info->pos = ftell (last_open_file);
580 1.1.1.2 christos fclose (last_open_file);
581 1.1.1.2 christos }
582 1.1.1.2 christos
583 1.1.1.2 christos /* Open the file in the binary mode so that ftell above can
584 1.1.1.2 christos return a reliable value that we can feed to fseek below. */
585 1.1.1.2 christos last_open_file_info = file;
586 1.1.1.2 christos last_open_file = fopen (file->filename, FOPEN_RB);
587 1.1.1.2 christos if (last_open_file == NULL)
588 1.1.1.2 christos {
589 1.1.1.2 christos file->at_end = 1;
590 1.1.1.5 christos return;
591 1.1.1.2 christos }
592 1.1.1.2 christos
593 1.1.1.2 christos /* Seek to where we were last time this file was open. */
594 1.1.1.2 christos if (file->pos)
595 1.1.1.2 christos fseek (last_open_file, file->pos, SEEK_SET);
596 1.1.1.2 christos }
597 1.1.1.2 christos
598 1.1.1.2 christos /* Remember where we are in the current file. */
599 1.1.1.4 christos pos2 = pos = ftell (last_open_file);
600 1.1.1.4 christos if (pos < 3)
601 1.1.1.5 christos return;
602 1.1.1.4 christos current_line = file->linenum;
603 1.1.1.2 christos
604 1.1.1.4 christos /* Leave room for the nul at the end of the buffer. */
605 1.1.1.4 christos size -= 1;
606 1.1.1.4 christos buffer[size] = 0;
607 1.1.1.2 christos
608 1.1.1.4 christos /* Increment the current line count by one.
609 1.1.1.4 christos This is to allow for the fact that we are searching for the
610 1.1.1.4 christos start of a previous line, but we do this by detecting end-of-line
611 1.1.1.4 christos character(s) not start-of-line characters. */
612 1.1.1.4 christos ++ current_line;
613 1.1.1.4 christos
614 1.1.1.4 christos while (pos2 > 0 && ! found)
615 1.1.1.2 christos {
616 1.1.1.4 christos char * ptr;
617 1.1.1.4 christos
618 1.1.1.4 christos /* Move backwards through the file, looking for earlier lines. */
619 1.1.1.4 christos pos2 = (long) size > pos2 ? 0 : pos2 - size;
620 1.1.1.4 christos fseek (last_open_file, pos2, SEEK_SET);
621 1.1.1.4 christos
622 1.1.1.4 christos /* Our caller has kindly provided us with a buffer, so we use it. */
623 1.1.1.4 christos if (fread (buffer, 1, size, last_open_file) != size)
624 1.1.1.2 christos {
625 1.1.1.4 christos as_warn (_("unable to rebuffer file: %s\n"), file->filename);
626 1.1.1.5 christos return;
627 1.1.1.2 christos }
628 1.1.1.2 christos
629 1.1.1.4 christos for (ptr = buffer + size; ptr >= buffer; -- ptr)
630 1.1.1.2 christos {
631 1.1.1.4 christos if (*ptr == '\n')
632 1.1.1.4 christos {
633 1.1.1.4 christos -- current_line;
634 1.1.1.2 christos
635 1.1.1.4 christos if (current_line == linenum)
636 1.1.1.4 christos {
637 1.1.1.4 christos /* We have found the start of the line we seek. */
638 1.1.1.4 christos found = TRUE;
639 1.1.1.4 christos
640 1.1.1.4 christos /* FIXME: We could skip the read-in-the-line code
641 1.1.1.4 christos below if we know that we already have the whole
642 1.1.1.4 christos line in the buffer. */
643 1.1.1.4 christos
644 1.1.1.4 christos /* Advance pos2 to the newline character we have just located. */
645 1.1.1.4 christos pos2 += (ptr - buffer);
646 1.1.1.4 christos
647 1.1.1.4 christos /* Skip the newline and, if present, the carriage return. */
648 1.1.1.4 christos if (ptr + 1 == buffer + size)
649 1.1.1.4 christos {
650 1.1.1.4 christos ++pos2;
651 1.1.1.4 christos if (fgetc (last_open_file) == '\r')
652 1.1.1.4 christos ++ pos2;
653 1.1.1.4 christos }
654 1.1.1.4 christos else
655 1.1.1.4 christos pos2 += (ptr[1] == '\r' ? 2 : 1);
656 1.1.1.4 christos
657 1.1.1.4 christos /* Move the file pointer to this location. */
658 1.1.1.4 christos fseek (last_open_file, pos2, SEEK_SET);
659 1.1.1.4 christos break;
660 1.1.1.4 christos }
661 1.1.1.4 christos }
662 1.1.1.2 christos }
663 1.1.1.2 christos }
664 1.1.1.2 christos
665 1.1.1.2 christos /* Read in the line. */
666 1.1.1.2 christos c = fgetc (last_open_file);
667 1.1.1.2 christos
668 1.1.1.2 christos while (c != EOF && c != '\n' && c != '\r')
669 1.1.1.2 christos {
670 1.1.1.2 christos if (count < size)
671 1.1.1.2 christos *p++ = c;
672 1.1.1.2 christos count++;
673 1.1.1.2 christos
674 1.1.1.2 christos c = fgetc (last_open_file);
675 1.1.1.2 christos }
676 1.1.1.2 christos
677 1.1.1.2 christos /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
678 1.1.1.2 christos is followed by '\r', swallow that as well. */
679 1.1.1.2 christos if (c == '\r' || c == '\n')
680 1.1.1.2 christos {
681 1.1.1.2 christos int next = fgetc (last_open_file);
682 1.1.1.2 christos
683 1.1.1.2 christos if ((c == '\r' && next != '\n')
684 1.1.1.2 christos || (c == '\n' && next != '\r'))
685 1.1.1.2 christos ungetc (next, last_open_file);
686 1.1.1.2 christos }
687 1.1.1.2 christos
688 1.1.1.2 christos /* Terminate the line. */
689 1.1.1.2 christos *p++ = 0;
690 1.1.1.2 christos
691 1.1.1.2 christos /* Reset the file position. */
692 1.1.1.2 christos fseek (last_open_file, pos, SEEK_SET);
693 1.1.1.2 christos }
694 1.1.1.2 christos
695 1.1 skrll static const char *fn;
696 1.1.1.5 christos static unsigned int eject; /* Eject pending. */
697 1.1.1.5 christos static unsigned int page; /* Current page number. */
698 1.1.1.5 christos static const char *title; /* Current title. */
699 1.1.1.5 christos static const char *subtitle; /* Current subtitle. */
700 1.1.1.5 christos static unsigned int on_page; /* Number of lines printed on current page. */
701 1.1 skrll
702 1.1 skrll static void
703 1.1 skrll listing_page (list_info_type *list)
704 1.1 skrll {
705 1.1 skrll /* Grope around, see if we can see a title or subtitle edict coming up
706 1.1 skrll soon. (we look down 10 lines of the page and see if it's there) */
707 1.1 skrll if ((eject || (on_page >= (unsigned int) paper_height))
708 1.1 skrll && paper_height != 0)
709 1.1 skrll {
710 1.1 skrll unsigned int c = 10;
711 1.1 skrll int had_title = 0;
712 1.1 skrll int had_subtitle = 0;
713 1.1 skrll
714 1.1 skrll page++;
715 1.1 skrll
716 1.1 skrll while (c != 0 && list)
717 1.1 skrll {
718 1.1 skrll if (list->edict == EDICT_SBTTL && !had_subtitle)
719 1.1 skrll {
720 1.1 skrll had_subtitle = 1;
721 1.1 skrll subtitle = list->edict_arg;
722 1.1 skrll }
723 1.1 skrll if (list->edict == EDICT_TITLE && !had_title)
724 1.1 skrll {
725 1.1 skrll had_title = 1;
726 1.1 skrll title = list->edict_arg;
727 1.1 skrll }
728 1.1 skrll list = list->next;
729 1.1 skrll c--;
730 1.1 skrll }
731 1.1 skrll
732 1.1 skrll if (page > 1)
733 1.1 skrll {
734 1.1 skrll fprintf (list_file, "\f");
735 1.1 skrll }
736 1.1 skrll
737 1.1 skrll fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
738 1.1 skrll fprintf (list_file, "%s\n", title);
739 1.1 skrll fprintf (list_file, "%s\n", subtitle);
740 1.1 skrll on_page = 3;
741 1.1 skrll eject = 0;
742 1.1 skrll }
743 1.1 skrll }
744 1.1 skrll
745 1.1.1.2 christos /* Print a line into the list_file. Update the line count
746 1.1.1.2 christos and if necessary start a new page. */
747 1.1.1.2 christos
748 1.1.1.2 christos static void
749 1.1.1.2 christos emit_line (list_info_type * list, const char * format, ...)
750 1.1.1.2 christos {
751 1.1.1.2 christos va_list args;
752 1.1.1.2 christos
753 1.1.1.2 christos va_start (args, format);
754 1.1.1.2 christos
755 1.1.1.2 christos vfprintf (list_file, format, args);
756 1.1.1.2 christos on_page++;
757 1.1.1.2 christos listing_page (list);
758 1.1.1.2 christos
759 1.1.1.2 christos va_end (args);
760 1.1.1.2 christos }
761 1.1.1.2 christos
762 1.1 skrll static unsigned int
763 1.1 skrll calc_hex (list_info_type *list)
764 1.1 skrll {
765 1.1 skrll int data_buffer_size;
766 1.1 skrll list_info_type *first = list;
767 1.1 skrll unsigned int address = ~(unsigned int) 0;
768 1.1 skrll fragS *frag;
769 1.1 skrll fragS *frag_ptr;
770 1.1 skrll unsigned int octet_in_frag;
771 1.1 skrll
772 1.1 skrll /* Find first frag which says it belongs to this line. */
773 1.1 skrll frag = list->frag;
774 1.1 skrll while (frag && frag->line != list)
775 1.1 skrll frag = frag->fr_next;
776 1.1 skrll
777 1.1 skrll frag_ptr = frag;
778 1.1 skrll
779 1.1 skrll data_buffer_size = 0;
780 1.1 skrll
781 1.1 skrll /* Dump all the frags which belong to this line. */
782 1.1 skrll while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
783 1.1 skrll {
784 1.1 skrll /* Print as many bytes from the fixed part as is sensible. */
785 1.1 skrll octet_in_frag = 0;
786 1.1 skrll while ((offsetT) octet_in_frag < frag_ptr->fr_fix
787 1.1 skrll && data_buffer_size < MAX_BYTES - 3)
788 1.1 skrll {
789 1.1 skrll if (address == ~(unsigned int) 0)
790 1.1 skrll address = frag_ptr->fr_address / OCTETS_PER_BYTE;
791 1.1 skrll
792 1.1 skrll sprintf (data_buffer + data_buffer_size,
793 1.1 skrll "%02X",
794 1.1 skrll (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
795 1.1 skrll data_buffer_size += 2;
796 1.1 skrll octet_in_frag++;
797 1.1 skrll }
798 1.1 skrll if (frag_ptr->fr_type == rs_fill)
799 1.1 skrll {
800 1.1 skrll unsigned int var_rep_max = octet_in_frag;
801 1.1 skrll unsigned int var_rep_idx = octet_in_frag;
802 1.1 skrll
803 1.1 skrll /* Print as many bytes from the variable part as is sensible. */
804 1.1 skrll while (((offsetT) octet_in_frag
805 1.1 skrll < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
806 1.1 skrll && data_buffer_size < MAX_BYTES - 3)
807 1.1 skrll {
808 1.1 skrll if (address == ~(unsigned int) 0)
809 1.1 skrll address = frag_ptr->fr_address / OCTETS_PER_BYTE;
810 1.1 skrll
811 1.1 skrll sprintf (data_buffer + data_buffer_size,
812 1.1 skrll "%02X",
813 1.1 skrll (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
814 1.1 skrll data_buffer_size += 2;
815 1.1 skrll
816 1.1 skrll var_rep_idx++;
817 1.1 skrll octet_in_frag++;
818 1.1 skrll
819 1.1 skrll if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
820 1.1 skrll var_rep_idx = var_rep_max;
821 1.1 skrll }
822 1.1 skrll }
823 1.1 skrll
824 1.1 skrll frag_ptr = frag_ptr->fr_next;
825 1.1 skrll }
826 1.1 skrll data_buffer[data_buffer_size] = '\0';
827 1.1 skrll return address;
828 1.1 skrll }
829 1.1 skrll
830 1.1 skrll static void
831 1.1 skrll print_lines (list_info_type *list, unsigned int lineno,
832 1.1.1.5 christos const char *string, unsigned int address)
833 1.1 skrll {
834 1.1 skrll unsigned int idx;
835 1.1 skrll unsigned int nchars;
836 1.1 skrll unsigned int lines;
837 1.1 skrll unsigned int octet_in_word = 0;
838 1.1 skrll char *src = data_buffer;
839 1.1 skrll int cur;
840 1.1.1.3 christos struct list_message *msg;
841 1.1 skrll
842 1.1 skrll /* Print the stuff on the first line. */
843 1.1 skrll listing_page (list);
844 1.1 skrll nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
845 1.1 skrll
846 1.1 skrll /* Print the hex for the first line. */
847 1.1 skrll if (address == ~(unsigned int) 0)
848 1.1 skrll {
849 1.1 skrll fprintf (list_file, "% 4d ", lineno);
850 1.1 skrll for (idx = 0; idx < nchars; idx++)
851 1.1 skrll fprintf (list_file, " ");
852 1.1 skrll
853 1.1.1.2 christos emit_line (NULL, "\t%s\n", string ? string : "");
854 1.1 skrll return;
855 1.1 skrll }
856 1.1 skrll
857 1.1 skrll if (had_errors ())
858 1.1 skrll fprintf (list_file, "% 4d ???? ", lineno);
859 1.1 skrll else
860 1.1 skrll fprintf (list_file, "% 4d %04x ", lineno, address);
861 1.1 skrll
862 1.1 skrll /* And the data to go along with it. */
863 1.1 skrll idx = 0;
864 1.1 skrll cur = 0;
865 1.1 skrll while (src[cur] && idx < nchars)
866 1.1 skrll {
867 1.1 skrll int offset;
868 1.1 skrll offset = cur;
869 1.1 skrll fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
870 1.1 skrll cur += 2;
871 1.1 skrll octet_in_word++;
872 1.1 skrll
873 1.1 skrll if (octet_in_word == LISTING_WORD_SIZE)
874 1.1 skrll {
875 1.1 skrll fprintf (list_file, " ");
876 1.1 skrll idx++;
877 1.1 skrll octet_in_word = 0;
878 1.1 skrll }
879 1.1 skrll
880 1.1 skrll idx += 2;
881 1.1 skrll }
882 1.1 skrll
883 1.1 skrll for (; idx < nchars; idx++)
884 1.1 skrll fprintf (list_file, " ");
885 1.1 skrll
886 1.1.1.2 christos emit_line (list, "\t%s\n", string ? string : "");
887 1.1 skrll
888 1.1.1.3 christos for (msg = list->messages; msg; msg = msg->next)
889 1.1.1.3 christos emit_line (list, "**** %s\n", msg->message);
890 1.1 skrll
891 1.1 skrll for (lines = 0;
892 1.1 skrll lines < (unsigned int) listing_lhs_cont_lines
893 1.1 skrll && src[cur];
894 1.1 skrll lines++)
895 1.1 skrll {
896 1.1 skrll nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
897 1.1 skrll idx = 0;
898 1.1 skrll
899 1.1 skrll /* Print any more lines of data, but more compactly. */
900 1.1 skrll fprintf (list_file, "% 4d ", lineno);
901 1.1 skrll
902 1.1 skrll while (src[cur] && idx < nchars)
903 1.1 skrll {
904 1.1 skrll int offset;
905 1.1 skrll offset = cur;
906 1.1 skrll fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
907 1.1 skrll cur += 2;
908 1.1 skrll idx += 2;
909 1.1 skrll octet_in_word++;
910 1.1 skrll
911 1.1 skrll if (octet_in_word == LISTING_WORD_SIZE)
912 1.1 skrll {
913 1.1 skrll fprintf (list_file, " ");
914 1.1 skrll idx++;
915 1.1 skrll octet_in_word = 0;
916 1.1 skrll }
917 1.1 skrll }
918 1.1 skrll
919 1.1.1.2 christos emit_line (list, "\n");
920 1.1 skrll }
921 1.1 skrll }
922 1.1 skrll
923 1.1 skrll static void
924 1.1 skrll list_symbol_table (void)
925 1.1 skrll {
926 1.1 skrll extern symbolS *symbol_rootP;
927 1.1 skrll int got_some = 0;
928 1.1 skrll
929 1.1 skrll symbolS *ptr;
930 1.1 skrll eject = 1;
931 1.1.1.2 christos listing_page (NULL);
932 1.1 skrll
933 1.1 skrll for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
934 1.1 skrll {
935 1.1 skrll if (SEG_NORMAL (S_GET_SEGMENT (ptr))
936 1.1 skrll || S_GET_SEGMENT (ptr) == absolute_section)
937 1.1 skrll {
938 1.1 skrll /* Don't report section symbols. They are not interesting. */
939 1.1 skrll if (symbol_section_p (ptr))
940 1.1 skrll continue;
941 1.1 skrll
942 1.1 skrll if (S_GET_NAME (ptr))
943 1.1 skrll {
944 1.1 skrll char buf[30], fmt[8];
945 1.1 skrll valueT val = S_GET_VALUE (ptr);
946 1.1 skrll
947 1.1 skrll /* @@ Note that this is dependent on the compilation options,
948 1.1 skrll not solely on the target characteristics. */
949 1.1 skrll if (sizeof (val) == 4 && sizeof (int) == 4)
950 1.1 skrll sprintf (buf, "%08lx", (unsigned long) val);
951 1.1 skrll else if (sizeof (val) <= sizeof (unsigned long))
952 1.1 skrll {
953 1.1 skrll sprintf (fmt, "%%0%lulx",
954 1.1 skrll (unsigned long) (sizeof (val) * 2));
955 1.1 skrll sprintf (buf, fmt, (unsigned long) val);
956 1.1 skrll }
957 1.1 skrll #if defined (BFD64)
958 1.1 skrll else if (sizeof (val) > 4)
959 1.1 skrll sprintf_vma (buf, val);
960 1.1 skrll #endif
961 1.1 skrll else
962 1.1 skrll abort ();
963 1.1 skrll
964 1.1 skrll if (!got_some)
965 1.1 skrll {
966 1.1 skrll fprintf (list_file, "DEFINED SYMBOLS\n");
967 1.1 skrll on_page++;
968 1.1 skrll got_some = 1;
969 1.1 skrll }
970 1.1 skrll
971 1.1 skrll if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
972 1.1 skrll {
973 1.1 skrll fprintf (list_file, "%20s:%-5d %s:%s %s\n",
974 1.1 skrll symbol_get_frag (ptr)->line->file->filename,
975 1.1 skrll symbol_get_frag (ptr)->line->line,
976 1.1 skrll segment_name (S_GET_SEGMENT (ptr)),
977 1.1 skrll buf, S_GET_NAME (ptr));
978 1.1 skrll }
979 1.1 skrll else
980 1.1 skrll {
981 1.1 skrll fprintf (list_file, "%33s:%s %s\n",
982 1.1 skrll segment_name (S_GET_SEGMENT (ptr)),
983 1.1 skrll buf, S_GET_NAME (ptr));
984 1.1 skrll }
985 1.1 skrll
986 1.1 skrll on_page++;
987 1.1.1.2 christos listing_page (NULL);
988 1.1 skrll }
989 1.1 skrll }
990 1.1 skrll
991 1.1 skrll }
992 1.1 skrll if (!got_some)
993 1.1 skrll {
994 1.1 skrll fprintf (list_file, "NO DEFINED SYMBOLS\n");
995 1.1 skrll on_page++;
996 1.1 skrll }
997 1.1.1.2 christos emit_line (NULL, "\n");
998 1.1 skrll
999 1.1 skrll got_some = 0;
1000 1.1 skrll
1001 1.1 skrll for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
1002 1.1 skrll {
1003 1.1 skrll if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
1004 1.1 skrll {
1005 1.1 skrll if (S_GET_SEGMENT (ptr) == undefined_section)
1006 1.1 skrll {
1007 1.1 skrll if (!got_some)
1008 1.1 skrll {
1009 1.1 skrll got_some = 1;
1010 1.1.1.2 christos
1011 1.1.1.2 christos emit_line (NULL, "UNDEFINED SYMBOLS\n");
1012 1.1 skrll }
1013 1.1.1.2 christos
1014 1.1.1.2 christos emit_line (NULL, "%s\n", S_GET_NAME (ptr));
1015 1.1 skrll }
1016 1.1 skrll }
1017 1.1 skrll }
1018 1.1.1.2 christos
1019 1.1 skrll if (!got_some)
1020 1.1.1.2 christos emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
1021 1.1 skrll }
1022 1.1 skrll
1023 1.1.1.2 christos typedef struct cached_line
1024 1.1 skrll {
1025 1.1.1.2 christos file_info_type * file;
1026 1.1.1.2 christos unsigned int line;
1027 1.1.1.2 christos char buffer [LISTING_RHS_WIDTH];
1028 1.1.1.2 christos } cached_line;
1029 1.1.1.2 christos
1030 1.1.1.2 christos static void
1031 1.1.1.2 christos print_source (file_info_type * current_file,
1032 1.1.1.2 christos list_info_type * list,
1033 1.1.1.2 christos unsigned int width)
1034 1.1.1.2 christos {
1035 1.1.1.2 christos #define NUM_CACHE_LINES 3
1036 1.1.1.2 christos static cached_line cached_lines[NUM_CACHE_LINES];
1037 1.1.1.2 christos static int next_free_line = 0;
1038 1.1.1.2 christos cached_line * cache = NULL;
1039 1.1.1.2 christos
1040 1.1.1.2 christos if (current_file->linenum > list->hll_line
1041 1.1.1.2 christos && list->hll_line > 0)
1042 1.1.1.2 christos {
1043 1.1.1.2 christos /* This can happen with modern optimizing compilers. The source
1044 1.1.1.2 christos lines from the high level language input program are split up
1045 1.1.1.2 christos and interleaved, meaning the line number we want to display
1046 1.1.1.2 christos (list->hll_line) can have already been displayed. We have
1047 1.1.1.2 christos three choices:
1048 1.1.1.2 christos
1049 1.1.1.2 christos a. Do nothing, since we have already displayed the source
1050 1.1.1.2 christos line. This was the old behaviour.
1051 1.1.1.2 christos
1052 1.1.1.2 christos b. Display the particular line requested again, but only
1053 1.1.1.2 christos that line. This is the new behaviour.
1054 1.1.1.2 christos
1055 1.1.1.2 christos c. Display the particular line requested again and reset
1056 1.1.1.2 christos the current_file->line_num value so that we redisplay
1057 1.1.1.2 christos all the following lines as well the next time we
1058 1.1.1.2 christos encounter a larger line number. */
1059 1.1.1.2 christos int i;
1060 1.1.1.2 christos
1061 1.1.1.2 christos /* Check the cache, maybe we already have the line saved. */
1062 1.1.1.2 christos for (i = 0; i < NUM_CACHE_LINES; i++)
1063 1.1.1.2 christos if (cached_lines[i].file == current_file
1064 1.1.1.2 christos && cached_lines[i].line == list->hll_line)
1065 1.1.1.2 christos {
1066 1.1.1.2 christos cache = cached_lines + i;
1067 1.1.1.2 christos break;
1068 1.1.1.2 christos }
1069 1.1.1.2 christos
1070 1.1.1.2 christos if (i == NUM_CACHE_LINES)
1071 1.1.1.2 christos {
1072 1.1.1.2 christos cache = cached_lines + next_free_line;
1073 1.1.1.2 christos next_free_line ++;
1074 1.1.1.2 christos if (next_free_line == NUM_CACHE_LINES)
1075 1.1.1.2 christos next_free_line = 0;
1076 1.1.1.2 christos
1077 1.1.1.2 christos cache->file = current_file;
1078 1.1.1.2 christos cache->line = list->hll_line;
1079 1.1.1.2 christos cache->buffer[0] = 0;
1080 1.1.1.2 christos rebuffer_line (current_file, cache->line, cache->buffer, width);
1081 1.1.1.2 christos }
1082 1.1.1.2 christos
1083 1.1.1.2 christos emit_line (list, "%4u:%-13s **** %s\n",
1084 1.1.1.2 christos cache->line, cache->file->filename, cache->buffer);
1085 1.1.1.2 christos return;
1086 1.1.1.2 christos }
1087 1.1.1.2 christos
1088 1.1 skrll if (!current_file->at_end)
1089 1.1 skrll {
1090 1.1.1.2 christos int num_lines_shown = 0;
1091 1.1.1.2 christos
1092 1.1 skrll while (current_file->linenum < list->hll_line
1093 1.1 skrll && !current_file->at_end)
1094 1.1 skrll {
1095 1.1.1.5 christos const char *p;
1096 1.1.1.2 christos
1097 1.1.1.2 christos cache = cached_lines + next_free_line;
1098 1.1.1.2 christos cache->file = current_file;
1099 1.1.1.2 christos cache->line = current_file->linenum + 1;
1100 1.1.1.2 christos cache->buffer[0] = 0;
1101 1.1.1.2 christos p = buffer_line (current_file, cache->buffer, width);
1102 1.1.1.2 christos
1103 1.1.1.2 christos /* Cache optimization: If printing a group of lines
1104 1.1.1.2 christos cache the first and last lines in the group. */
1105 1.1.1.2 christos if (num_lines_shown == 0)
1106 1.1.1.2 christos {
1107 1.1.1.2 christos next_free_line ++;
1108 1.1.1.2 christos if (next_free_line == NUM_CACHE_LINES)
1109 1.1.1.2 christos next_free_line = 0;
1110 1.1.1.2 christos }
1111 1.1 skrll
1112 1.1.1.2 christos emit_line (list, "%4u:%-13s **** %s\n",
1113 1.1.1.2 christos cache->line, cache->file->filename, p);
1114 1.1.1.2 christos num_lines_shown ++;
1115 1.1 skrll }
1116 1.1 skrll }
1117 1.1 skrll }
1118 1.1 skrll
1119 1.1 skrll /* Sometimes the user doesn't want to be bothered by the debugging
1120 1.1 skrll records inserted by the compiler, see if the line is suspicious. */
1121 1.1 skrll
1122 1.1 skrll static int
1123 1.1 skrll debugging_pseudo (list_info_type *list, const char *line)
1124 1.1 skrll {
1125 1.1.1.2 christos #ifdef OBJ_ELF
1126 1.1 skrll static int in_debug;
1127 1.1 skrll int was_debug;
1128 1.1.1.2 christos #endif
1129 1.1 skrll
1130 1.1 skrll if (list->debugging)
1131 1.1 skrll {
1132 1.1.1.2 christos #ifdef OBJ_ELF
1133 1.1 skrll in_debug = 1;
1134 1.1.1.2 christos #endif
1135 1.1 skrll return 1;
1136 1.1 skrll }
1137 1.1.1.2 christos #ifdef OBJ_ELF
1138 1.1 skrll was_debug = in_debug;
1139 1.1 skrll in_debug = 0;
1140 1.1.1.2 christos #endif
1141 1.1 skrll
1142 1.1 skrll while (ISSPACE (*line))
1143 1.1 skrll line++;
1144 1.1 skrll
1145 1.1 skrll if (*line != '.')
1146 1.1 skrll {
1147 1.1 skrll #ifdef OBJ_ELF
1148 1.1 skrll /* The ELF compiler sometimes emits blank lines after switching
1149 1.1 skrll out of a debugging section. If the next line drops us back
1150 1.1 skrll into debugging information, then don't print the blank line.
1151 1.1 skrll This is a hack for a particular compiler behaviour, not a
1152 1.1 skrll general case. */
1153 1.1 skrll if (was_debug
1154 1.1 skrll && *line == '\0'
1155 1.1 skrll && list->next != NULL
1156 1.1 skrll && list->next->debugging)
1157 1.1 skrll {
1158 1.1 skrll in_debug = 1;
1159 1.1 skrll return 1;
1160 1.1 skrll }
1161 1.1 skrll #endif
1162 1.1 skrll
1163 1.1 skrll return 0;
1164 1.1 skrll }
1165 1.1 skrll
1166 1.1 skrll line++;
1167 1.1 skrll
1168 1.1 skrll if (strncmp (line, "def", 3) == 0)
1169 1.1 skrll return 1;
1170 1.1 skrll if (strncmp (line, "val", 3) == 0)
1171 1.1 skrll return 1;
1172 1.1 skrll if (strncmp (line, "scl", 3) == 0)
1173 1.1 skrll return 1;
1174 1.1 skrll if (strncmp (line, "line", 4) == 0)
1175 1.1 skrll return 1;
1176 1.1 skrll if (strncmp (line, "endef", 5) == 0)
1177 1.1 skrll return 1;
1178 1.1 skrll if (strncmp (line, "ln", 2) == 0)
1179 1.1 skrll return 1;
1180 1.1 skrll if (strncmp (line, "type", 4) == 0)
1181 1.1 skrll return 1;
1182 1.1 skrll if (strncmp (line, "size", 4) == 0)
1183 1.1 skrll return 1;
1184 1.1 skrll if (strncmp (line, "dim", 3) == 0)
1185 1.1 skrll return 1;
1186 1.1 skrll if (strncmp (line, "tag", 3) == 0)
1187 1.1 skrll return 1;
1188 1.1 skrll if (strncmp (line, "stabs", 5) == 0)
1189 1.1 skrll return 1;
1190 1.1 skrll if (strncmp (line, "stabn", 5) == 0)
1191 1.1 skrll return 1;
1192 1.1 skrll
1193 1.1 skrll return 0;
1194 1.1 skrll }
1195 1.1 skrll
1196 1.1 skrll static void
1197 1.1 skrll listing_listing (char *name ATTRIBUTE_UNUSED)
1198 1.1 skrll {
1199 1.1 skrll list_info_type *list = head;
1200 1.1 skrll file_info_type *current_hll_file = (file_info_type *) NULL;
1201 1.1 skrll char *buffer;
1202 1.1.1.5 christos const char *p;
1203 1.1 skrll int show_listing = 1;
1204 1.1 skrll unsigned int width;
1205 1.1 skrll
1206 1.1.1.5 christos buffer = XNEWVEC (char, listing_rhs_width);
1207 1.1.1.5 christos data_buffer = XNEWVEC (char, MAX_BYTES);
1208 1.1 skrll eject = 1;
1209 1.1 skrll list = head->next;
1210 1.1 skrll
1211 1.1 skrll while (list)
1212 1.1 skrll {
1213 1.1 skrll unsigned int list_line;
1214 1.1 skrll
1215 1.1 skrll width = listing_rhs_width > paper_width ? paper_width :
1216 1.1 skrll listing_rhs_width;
1217 1.1 skrll
1218 1.1 skrll list_line = list->line;
1219 1.1 skrll switch (list->edict)
1220 1.1 skrll {
1221 1.1 skrll case EDICT_LIST:
1222 1.1 skrll /* Skip all lines up to the current. */
1223 1.1 skrll list_line--;
1224 1.1 skrll break;
1225 1.1 skrll case EDICT_NOLIST:
1226 1.1 skrll show_listing--;
1227 1.1 skrll break;
1228 1.1 skrll case EDICT_NOLIST_NEXT:
1229 1.1 skrll if (show_listing == 0)
1230 1.1 skrll list_line--;
1231 1.1 skrll break;
1232 1.1 skrll case EDICT_EJECT:
1233 1.1 skrll break;
1234 1.1 skrll case EDICT_NONE:
1235 1.1 skrll break;
1236 1.1 skrll case EDICT_TITLE:
1237 1.1 skrll title = list->edict_arg;
1238 1.1 skrll break;
1239 1.1 skrll case EDICT_SBTTL:
1240 1.1 skrll subtitle = list->edict_arg;
1241 1.1 skrll break;
1242 1.1 skrll default:
1243 1.1 skrll abort ();
1244 1.1 skrll }
1245 1.1 skrll
1246 1.1 skrll if (show_listing <= 0)
1247 1.1 skrll {
1248 1.1 skrll while (list->file->linenum < list_line
1249 1.1 skrll && !list->file->at_end)
1250 1.1 skrll p = buffer_line (list->file, buffer, width);
1251 1.1 skrll }
1252 1.1 skrll
1253 1.1 skrll if (list->edict == EDICT_LIST
1254 1.1 skrll || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1255 1.1 skrll {
1256 1.1 skrll /* Enable listing for the single line that caused the enable. */
1257 1.1 skrll list_line++;
1258 1.1 skrll show_listing++;
1259 1.1 skrll }
1260 1.1 skrll
1261 1.1 skrll if (show_listing > 0)
1262 1.1 skrll {
1263 1.1 skrll /* Scan down the list and print all the stuff which can be done
1264 1.1 skrll with this line (or lines). */
1265 1.1 skrll if (list->hll_file)
1266 1.1 skrll current_hll_file = list->hll_file;
1267 1.1 skrll
1268 1.1 skrll if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1269 1.1.1.2 christos print_source (current_hll_file, list, width);
1270 1.1 skrll
1271 1.1 skrll if (list->line_contents)
1272 1.1 skrll {
1273 1.1 skrll if (!((listing & LISTING_NODEBUG)
1274 1.1 skrll && debugging_pseudo (list, list->line_contents)))
1275 1.1 skrll print_lines (list,
1276 1.1 skrll list->file->linenum == 0 ? list->line : list->file->linenum,
1277 1.1 skrll list->line_contents, calc_hex (list));
1278 1.1 skrll
1279 1.1 skrll free (list->line_contents);
1280 1.1 skrll list->line_contents = NULL;
1281 1.1 skrll }
1282 1.1 skrll else
1283 1.1 skrll {
1284 1.1 skrll while (list->file->linenum < list_line
1285 1.1 skrll && !list->file->at_end)
1286 1.1 skrll {
1287 1.1 skrll unsigned int address;
1288 1.1 skrll
1289 1.1 skrll p = buffer_line (list->file, buffer, width);
1290 1.1 skrll
1291 1.1 skrll if (list->file->linenum < list_line)
1292 1.1 skrll address = ~(unsigned int) 0;
1293 1.1 skrll else
1294 1.1 skrll address = calc_hex (list);
1295 1.1 skrll
1296 1.1 skrll if (!((listing & LISTING_NODEBUG)
1297 1.1 skrll && debugging_pseudo (list, p)))
1298 1.1 skrll print_lines (list, list->file->linenum, p, address);
1299 1.1 skrll }
1300 1.1 skrll }
1301 1.1 skrll
1302 1.1 skrll if (list->edict == EDICT_EJECT)
1303 1.1 skrll eject = 1;
1304 1.1 skrll }
1305 1.1 skrll
1306 1.1 skrll if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1307 1.1 skrll --show_listing;
1308 1.1 skrll
1309 1.1 skrll list = list->next;
1310 1.1 skrll }
1311 1.1 skrll
1312 1.1 skrll free (buffer);
1313 1.1 skrll free (data_buffer);
1314 1.1 skrll data_buffer = NULL;
1315 1.1 skrll }
1316 1.1 skrll
1317 1.1 skrll /* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */
1318 1.1 skrll
1319 1.1 skrll static void
1320 1.1 skrll print_timestamp (void)
1321 1.1 skrll {
1322 1.1 skrll const time_t now = time (NULL);
1323 1.1 skrll struct tm * timestamp;
1324 1.1 skrll char stampstr[MAX_DATELEN];
1325 1.1 skrll
1326 1.1 skrll /* Any portable way to obtain subsecond values??? */
1327 1.1 skrll timestamp = localtime (&now);
1328 1.1 skrll strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1329 1.1 skrll fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr);
1330 1.1 skrll }
1331 1.1 skrll
1332 1.1 skrll static void
1333 1.1 skrll print_single_option (char * opt, int *pos)
1334 1.1 skrll {
1335 1.1 skrll int opt_len = strlen (opt);
1336 1.1 skrll
1337 1.1 skrll if ((*pos + opt_len) < paper_width)
1338 1.1 skrll {
1339 1.1 skrll fprintf (list_file, _("%s "), opt);
1340 1.1 skrll *pos = *pos + opt_len;
1341 1.1 skrll }
1342 1.1 skrll else
1343 1.1 skrll {
1344 1.1 skrll fprintf (list_file, _("\n\t%s "), opt);
1345 1.1 skrll *pos = opt_len;
1346 1.1 skrll }
1347 1.1 skrll }
1348 1.1 skrll
1349 1.1 skrll /* Print options passed to as. */
1350 1.1 skrll
1351 1.1 skrll static void
1352 1.1 skrll print_options (char ** argv)
1353 1.1 skrll {
1354 1.1 skrll const char *field_name = _("\n options passed\t: ");
1355 1.1 skrll int pos = strlen (field_name);
1356 1.1 skrll char **p;
1357 1.1 skrll
1358 1.1 skrll fputs (field_name, list_file);
1359 1.1 skrll for (p = &argv[1]; *p != NULL; p++)
1360 1.1 skrll if (**p == '-')
1361 1.1 skrll {
1362 1.1 skrll /* Ignore these. */
1363 1.1 skrll if (strcmp (*p, "-o") == 0)
1364 1.1 skrll {
1365 1.1 skrll if (p[1] != NULL)
1366 1.1 skrll p++;
1367 1.1 skrll continue;
1368 1.1 skrll }
1369 1.1 skrll if (strcmp (*p, "-v") == 0)
1370 1.1 skrll continue;
1371 1.1 skrll
1372 1.1 skrll print_single_option (*p, &pos);
1373 1.1 skrll }
1374 1.1 skrll }
1375 1.1 skrll
1376 1.1 skrll /* Print a first section with basic info like file names, as version,
1377 1.1 skrll options passed, target, and timestamp.
1378 1.1 skrll The format of this section is as follows:
1379 1.1 skrll
1380 1.1 skrll AS VERSION
1381 1.1 skrll
1382 1.1 skrll fieldname TAB ':' fieldcontents
1383 1.1 skrll { TAB fieldcontents-cont } */
1384 1.1 skrll
1385 1.1 skrll static void
1386 1.1 skrll listing_general_info (char ** argv)
1387 1.1 skrll {
1388 1.1 skrll /* Print the stuff on the first line. */
1389 1.1 skrll eject = 1;
1390 1.1.1.2 christos listing_page (NULL);
1391 1.1 skrll
1392 1.1 skrll fprintf (list_file,
1393 1.1 skrll _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1394 1.1 skrll VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1395 1.1 skrll print_options (argv);
1396 1.1 skrll fprintf (list_file, _("\n input file \t: %s"), fn);
1397 1.1 skrll fprintf (list_file, _("\n output file \t: %s"), out_file_name);
1398 1.1 skrll fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL);
1399 1.1 skrll print_timestamp ();
1400 1.1 skrll }
1401 1.1 skrll
1402 1.1 skrll void
1403 1.1 skrll listing_print (char *name, char **argv)
1404 1.1 skrll {
1405 1.1 skrll int using_stdout;
1406 1.1 skrll
1407 1.1 skrll title = "";
1408 1.1 skrll subtitle = "";
1409 1.1 skrll
1410 1.1 skrll if (name == NULL)
1411 1.1 skrll {
1412 1.1 skrll list_file = stdout;
1413 1.1 skrll using_stdout = 1;
1414 1.1 skrll }
1415 1.1 skrll else
1416 1.1 skrll {
1417 1.1 skrll list_file = fopen (name, FOPEN_WT);
1418 1.1 skrll if (list_file != NULL)
1419 1.1 skrll using_stdout = 0;
1420 1.1 skrll else
1421 1.1 skrll {
1422 1.1 skrll as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1423 1.1 skrll list_file = stdout;
1424 1.1 skrll using_stdout = 1;
1425 1.1 skrll }
1426 1.1 skrll }
1427 1.1 skrll
1428 1.1 skrll if (listing & LISTING_NOFORM)
1429 1.1 skrll paper_height = 0;
1430 1.1 skrll
1431 1.1 skrll if (listing & LISTING_GENERAL)
1432 1.1 skrll listing_general_info (argv);
1433 1.1 skrll
1434 1.1 skrll if (listing & LISTING_LISTING)
1435 1.1 skrll listing_listing (name);
1436 1.1 skrll
1437 1.1 skrll if (listing & LISTING_SYMBOLS)
1438 1.1 skrll list_symbol_table ();
1439 1.1 skrll
1440 1.1 skrll if (! using_stdout)
1441 1.1 skrll {
1442 1.1 skrll if (fclose (list_file) == EOF)
1443 1.1 skrll as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1444 1.1 skrll }
1445 1.1 skrll
1446 1.1 skrll if (last_open_file)
1447 1.1 skrll fclose (last_open_file);
1448 1.1 skrll }
1449 1.1 skrll
1450 1.1 skrll void
1451 1.1 skrll listing_file (const char *name)
1452 1.1 skrll {
1453 1.1 skrll fn = name;
1454 1.1 skrll }
1455 1.1 skrll
1456 1.1 skrll void
1457 1.1 skrll listing_eject (int ignore ATTRIBUTE_UNUSED)
1458 1.1 skrll {
1459 1.1 skrll if (listing)
1460 1.1 skrll listing_tail->edict = EDICT_EJECT;
1461 1.1 skrll }
1462 1.1 skrll
1463 1.1 skrll /* Turn listing on or off. An argument of 0 means to turn off
1464 1.1 skrll listing. An argument of 1 means to turn on listing. An argument
1465 1.1 skrll of 2 means to turn off listing, but as of the next line; that is,
1466 1.1 skrll the current line should be listed, but the next line should not. */
1467 1.1 skrll
1468 1.1 skrll void
1469 1.1 skrll listing_list (int on)
1470 1.1 skrll {
1471 1.1 skrll if (listing)
1472 1.1 skrll {
1473 1.1 skrll switch (on)
1474 1.1 skrll {
1475 1.1 skrll case 0:
1476 1.1 skrll if (listing_tail->edict == EDICT_LIST)
1477 1.1 skrll listing_tail->edict = EDICT_NONE;
1478 1.1 skrll else
1479 1.1 skrll listing_tail->edict = EDICT_NOLIST;
1480 1.1 skrll break;
1481 1.1 skrll case 1:
1482 1.1 skrll if (listing_tail->edict == EDICT_NOLIST
1483 1.1 skrll || listing_tail->edict == EDICT_NOLIST_NEXT)
1484 1.1 skrll listing_tail->edict = EDICT_NONE;
1485 1.1 skrll else
1486 1.1 skrll listing_tail->edict = EDICT_LIST;
1487 1.1 skrll break;
1488 1.1 skrll case 2:
1489 1.1 skrll listing_tail->edict = EDICT_NOLIST_NEXT;
1490 1.1 skrll break;
1491 1.1 skrll default:
1492 1.1 skrll abort ();
1493 1.1 skrll }
1494 1.1 skrll }
1495 1.1 skrll }
1496 1.1 skrll
1497 1.1 skrll void
1498 1.1 skrll listing_psize (int width_only)
1499 1.1 skrll {
1500 1.1 skrll if (! width_only)
1501 1.1 skrll {
1502 1.1 skrll paper_height = get_absolute_expression ();
1503 1.1 skrll
1504 1.1 skrll if (paper_height < 0 || paper_height > 1000)
1505 1.1 skrll {
1506 1.1 skrll paper_height = 0;
1507 1.1 skrll as_warn (_("strange paper height, set to no form"));
1508 1.1 skrll }
1509 1.1 skrll
1510 1.1 skrll if (*input_line_pointer != ',')
1511 1.1 skrll {
1512 1.1 skrll demand_empty_rest_of_line ();
1513 1.1 skrll return;
1514 1.1 skrll }
1515 1.1 skrll
1516 1.1 skrll ++input_line_pointer;
1517 1.1 skrll }
1518 1.1 skrll
1519 1.1 skrll paper_width = get_absolute_expression ();
1520 1.1 skrll
1521 1.1 skrll demand_empty_rest_of_line ();
1522 1.1 skrll }
1523 1.1 skrll
1524 1.1 skrll void
1525 1.1 skrll listing_nopage (int ignore ATTRIBUTE_UNUSED)
1526 1.1 skrll {
1527 1.1 skrll paper_height = 0;
1528 1.1 skrll }
1529 1.1 skrll
1530 1.1 skrll void
1531 1.1 skrll listing_title (int depth)
1532 1.1 skrll {
1533 1.1 skrll int quoted;
1534 1.1 skrll char *start;
1535 1.1 skrll char *ttl;
1536 1.1 skrll unsigned int length;
1537 1.1 skrll
1538 1.1 skrll SKIP_WHITESPACE ();
1539 1.1 skrll if (*input_line_pointer != '\"')
1540 1.1 skrll quoted = 0;
1541 1.1 skrll else
1542 1.1 skrll {
1543 1.1 skrll quoted = 1;
1544 1.1 skrll ++input_line_pointer;
1545 1.1 skrll }
1546 1.1 skrll
1547 1.1 skrll start = input_line_pointer;
1548 1.1 skrll
1549 1.1 skrll while (*input_line_pointer)
1550 1.1 skrll {
1551 1.1 skrll if (quoted
1552 1.1 skrll ? *input_line_pointer == '\"'
1553 1.1 skrll : is_end_of_line[(unsigned char) *input_line_pointer])
1554 1.1 skrll {
1555 1.1 skrll if (listing)
1556 1.1 skrll {
1557 1.1 skrll length = input_line_pointer - start;
1558 1.1.1.5 christos ttl = xmemdup0 (start, length);
1559 1.1 skrll listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1560 1.1 skrll listing_tail->edict_arg = ttl;
1561 1.1 skrll }
1562 1.1 skrll if (quoted)
1563 1.1 skrll input_line_pointer++;
1564 1.1 skrll demand_empty_rest_of_line ();
1565 1.1 skrll return;
1566 1.1 skrll }
1567 1.1 skrll else if (*input_line_pointer == '\n')
1568 1.1 skrll {
1569 1.1 skrll as_bad (_("new line in title"));
1570 1.1 skrll demand_empty_rest_of_line ();
1571 1.1 skrll return;
1572 1.1 skrll }
1573 1.1 skrll else
1574 1.1 skrll {
1575 1.1 skrll input_line_pointer++;
1576 1.1 skrll }
1577 1.1 skrll }
1578 1.1 skrll }
1579 1.1 skrll
1580 1.1 skrll void
1581 1.1 skrll listing_source_line (unsigned int line)
1582 1.1 skrll {
1583 1.1 skrll if (listing)
1584 1.1 skrll {
1585 1.1 skrll new_frag ();
1586 1.1 skrll listing_tail->hll_line = line;
1587 1.1 skrll new_frag ();
1588 1.1 skrll }
1589 1.1 skrll }
1590 1.1 skrll
1591 1.1 skrll void
1592 1.1 skrll listing_source_file (const char *file)
1593 1.1 skrll {
1594 1.1 skrll if (listing)
1595 1.1 skrll listing_tail->hll_file = file_info (file);
1596 1.1 skrll }
1597 1.1 skrll
1598 1.1 skrll #else
1599 1.1 skrll
1600 1.1 skrll /* Dummy functions for when compiled without listing enabled. */
1601 1.1 skrll
1602 1.1 skrll void
1603 1.1 skrll listing_list (int on)
1604 1.1 skrll {
1605 1.1 skrll s_ignore (0);
1606 1.1 skrll }
1607 1.1 skrll
1608 1.1 skrll void
1609 1.1 skrll listing_eject (int ignore)
1610 1.1 skrll {
1611 1.1 skrll s_ignore (0);
1612 1.1 skrll }
1613 1.1 skrll
1614 1.1 skrll void
1615 1.1 skrll listing_psize (int ignore)
1616 1.1 skrll {
1617 1.1 skrll s_ignore (0);
1618 1.1 skrll }
1619 1.1 skrll
1620 1.1 skrll void
1621 1.1 skrll listing_nopage (int ignore)
1622 1.1 skrll {
1623 1.1 skrll s_ignore (0);
1624 1.1 skrll }
1625 1.1 skrll
1626 1.1 skrll void
1627 1.1 skrll listing_title (int depth)
1628 1.1 skrll {
1629 1.1 skrll s_ignore (0);
1630 1.1 skrll }
1631 1.1 skrll
1632 1.1 skrll void
1633 1.1 skrll listing_file (const char *name)
1634 1.1 skrll {
1635 1.1 skrll }
1636 1.1 skrll
1637 1.1 skrll void
1638 1.1 skrll listing_newline (char *name)
1639 1.1 skrll {
1640 1.1 skrll }
1641 1.1 skrll
1642 1.1 skrll void
1643 1.1 skrll listing_source_line (unsigned int n)
1644 1.1 skrll {
1645 1.1 skrll }
1646 1.1 skrll
1647 1.1 skrll void
1648 1.1 skrll listing_source_file (const char *n)
1649 1.1 skrll {
1650 1.1 skrll }
1651 1.1 skrll
1652 1.1 skrll #endif
1653