File: | src/gnu/usr.bin/binutils-2.17/gas/listing.c |
Warning: | line 467, column 29 Access to field 'pos' results in a dereference of a null pointer (loaded from variable 'last_open_file_info') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* listing.c - maintain assembly listings | |||
2 | Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, | |||
3 | 2001, 2002, 2003, 2005 | |||
4 | Free Software Foundation, Inc. | |||
5 | ||||
6 | This file is part of GAS, the GNU Assembler. | |||
7 | ||||
8 | GAS is free software; you can redistribute it and/or modify | |||
9 | it under the terms of the GNU General Public License as published by | |||
10 | the Free Software Foundation; either version 2, or (at your option) | |||
11 | any later version. | |||
12 | ||||
13 | GAS is distributed in the hope that it will be useful, | |||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
16 | GNU General Public License for more details. | |||
17 | ||||
18 | You should have received a copy of the GNU General Public License | |||
19 | along with GAS; see the file COPYING. If not, write to the Free | |||
20 | Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA | |||
21 | 02110-1301, USA. */ | |||
22 | ||||
23 | /* Contributed by Steve Chamberlain <sac@cygnus.com> | |||
24 | ||||
25 | A listing page looks like: | |||
26 | ||||
27 | LISTING_HEADER sourcefilename pagenumber | |||
28 | TITLE LINE | |||
29 | SUBTITLE LINE | |||
30 | linenumber address data source | |||
31 | linenumber address data source | |||
32 | linenumber address data source | |||
33 | linenumber address data source | |||
34 | ||||
35 | If not overridden, the listing commands are: | |||
36 | ||||
37 | .title "stuff" | |||
38 | Put "stuff" onto the title line | |||
39 | .sbttl "stuff" | |||
40 | Put stuff onto the subtitle line | |||
41 | ||||
42 | If these commands come within 10 lines of the top of the page, they | |||
43 | will affect the page they are on, as well as any subsequent page | |||
44 | ||||
45 | .eject | |||
46 | Thow a page | |||
47 | .list | |||
48 | Increment the enable listing counter | |||
49 | .nolist | |||
50 | Decrement the enable listing counter | |||
51 | ||||
52 | .psize Y[,X] | |||
53 | Set the paper size to X wide and Y high. Setting a psize Y of | |||
54 | zero will suppress form feeds except where demanded by .eject | |||
55 | ||||
56 | If the counter goes below zero, listing is suppressed. | |||
57 | ||||
58 | Listings are a maintained by read calling various listing_<foo> | |||
59 | functions. What happens most is that the macro NO_LISTING is not | |||
60 | defined (from the Makefile), then the macro LISTING_NEWLINE expands | |||
61 | into a call to listing_newline. The call is done from read.c, every | |||
62 | time it sees a newline, and -l is on the command line. | |||
63 | ||||
64 | The function listing_newline remembers the frag associated with the | |||
65 | newline, and creates a new frag - note that this is wasteful, but not | |||
66 | a big deal, since listing slows things down a lot anyway. The | |||
67 | function also remembers when the filename changes. | |||
68 | ||||
69 | When all the input has finished, and gas has had a chance to settle | |||
70 | down, the listing is output. This is done by running down the list of | |||
71 | frag/source file records, and opening the files as needed and printing | |||
72 | out the bytes and chars associated with them. | |||
73 | ||||
74 | The only things which the architecture can change about the listing | |||
75 | are defined in these macros: | |||
76 | ||||
77 | LISTING_HEADER The name of the architecture | |||
78 | LISTING_WORD_SIZE The make of the number of bytes in a word, this determines | |||
79 | the clumping of the output data. eg a value of | |||
80 | 2 makes words look like 1234 5678, whilst 1 | |||
81 | would make the same value look like 12 34 56 | |||
82 | 78 | |||
83 | LISTING_LHS_WIDTH Number of words of above size for the lhs | |||
84 | ||||
85 | LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs | |||
86 | for the second line | |||
87 | ||||
88 | LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation | |||
89 | LISTING_RHS_WIDTH Number of chars from the input file to print | |||
90 | on a line. */ | |||
91 | ||||
92 | #include "as.h" | |||
93 | #include "obstack.h" | |||
94 | #include "safe-ctype.h" | |||
95 | #include "input-file.h" | |||
96 | #include "subsegs.h" | |||
97 | ||||
98 | #ifndef NO_LISTING | |||
99 | ||||
100 | #ifndef LISTING_HEADER"GAS LISTING" | |||
101 | #define LISTING_HEADER"GAS LISTING" "GAS LISTING" | |||
102 | #endif | |||
103 | #ifndef LISTING_WORD_SIZE4 | |||
104 | #define LISTING_WORD_SIZE4 4 | |||
105 | #endif | |||
106 | #ifndef LISTING_LHS_WIDTH((4) > 4 ? 1 : 4 / (4)) | |||
107 | #define LISTING_LHS_WIDTH((4) > 4 ? 1 : 4 / (4)) ((LISTING_WORD_SIZE4) > 4 ? 1 : 4 / (LISTING_WORD_SIZE4)) | |||
108 | #endif | |||
109 | #ifndef LISTING_LHS_WIDTH_SECOND((4) > 4 ? 1 : 4 / (4)) | |||
110 | #define LISTING_LHS_WIDTH_SECOND((4) > 4 ? 1 : 4 / (4)) LISTING_LHS_WIDTH((4) > 4 ? 1 : 4 / (4)) | |||
111 | #endif | |||
112 | #ifndef LISTING_RHS_WIDTH100 | |||
113 | #define LISTING_RHS_WIDTH100 100 | |||
114 | #endif | |||
115 | #ifndef LISTING_LHS_CONT_LINES4 | |||
116 | #define LISTING_LHS_CONT_LINES4 4 | |||
117 | #endif | |||
118 | ||||
119 | /* This structure remembers which .s were used. */ | |||
120 | typedef struct file_info_struct | |||
121 | { | |||
122 | struct file_info_struct * next; | |||
123 | char * filename; | |||
124 | long pos; | |||
125 | unsigned int linenum; | |||
126 | int at_end; | |||
127 | } file_info_type; | |||
128 | ||||
129 | /* This structure remembers which line from which file goes into which | |||
130 | frag. */ | |||
131 | struct list_info_struct | |||
132 | { | |||
133 | /* Frag which this line of source is nearest to. */ | |||
134 | fragS *frag; | |||
135 | ||||
136 | /* The actual line in the source file. */ | |||
137 | unsigned int line; | |||
138 | ||||
139 | /* Pointer to the file info struct for the file which this line | |||
140 | belongs to. */ | |||
141 | file_info_type *file; | |||
142 | ||||
143 | /* The expanded text of any macro that may have been executing. */ | |||
144 | char *line_contents; | |||
145 | ||||
146 | /* Next in list. */ | |||
147 | struct list_info_struct *next; | |||
148 | ||||
149 | /* Pointer to the file info struct for the high level language | |||
150 | source line that belongs here. */ | |||
151 | file_info_type *hll_file; | |||
152 | ||||
153 | /* High level language source line. */ | |||
154 | unsigned int hll_line; | |||
155 | ||||
156 | /* Pointer to any error message associated with this line. */ | |||
157 | char *message; | |||
158 | ||||
159 | enum | |||
160 | { | |||
161 | EDICT_NONE, | |||
162 | EDICT_SBTTL, | |||
163 | EDICT_TITLE, | |||
164 | EDICT_NOLIST, | |||
165 | EDICT_LIST, | |||
166 | EDICT_NOLIST_NEXT, | |||
167 | EDICT_EJECT | |||
168 | } edict; | |||
169 | char *edict_arg; | |||
170 | ||||
171 | /* Nonzero if this line is to be omitted because it contains | |||
172 | debugging information. This can become a flags field if we come | |||
173 | up with more information to store here. */ | |||
174 | int debugging; | |||
175 | }; | |||
176 | ||||
177 | typedef struct list_info_struct list_info_type; | |||
178 | ||||
179 | int listing_lhs_width = LISTING_LHS_WIDTH((4) > 4 ? 1 : 4 / (4)); | |||
180 | int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND((4) > 4 ? 1 : 4 / (4)); | |||
181 | int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES4; | |||
182 | int listing_rhs_width = LISTING_RHS_WIDTH100; | |||
183 | ||||
184 | struct list_info_struct * listing_tail; | |||
185 | ||||
186 | static file_info_type * file_info_head; | |||
187 | static file_info_type * last_open_file_info; | |||
188 | static FILE * last_open_file; | |||
189 | static struct list_info_struct * head; | |||
190 | static int paper_width = 200; | |||
191 | static int paper_height = 60; | |||
192 | ||||
193 | extern int listing; | |||
194 | ||||
195 | /* File to output listings to. */ | |||
196 | static FILE *list_file; | |||
197 | ||||
198 | /* This static array is used to keep the text of data to be printed | |||
199 | before the start of the line. */ | |||
200 | ||||
201 | #define MAX_BYTES(((4 * 2) + 1) * listing_lhs_width + ((((4 * 2) + 1) * listing_lhs_width_second ) * listing_lhs_cont_lines) + 20) \ | |||
202 | (((LISTING_WORD_SIZE4 * 2) + 1) * listing_lhs_width \ | |||
203 | + ((((LISTING_WORD_SIZE4 * 2) + 1) * listing_lhs_width_second) \ | |||
204 | * listing_lhs_cont_lines) \ | |||
205 | + 20) | |||
206 | ||||
207 | static char *data_buffer; | |||
208 | ||||
209 | /* Prototypes. */ | |||
210 | static void listing_message (const char *, const char *); | |||
211 | static file_info_type *file_info (const char *); | |||
212 | static void new_frag (void); | |||
213 | static char *buffer_line (file_info_type *, char *, unsigned int); | |||
214 | static void listing_page (list_info_type *); | |||
215 | static unsigned int calc_hex (list_info_type *); | |||
216 | static void print_lines (list_info_type *, unsigned int, char *, unsigned int); | |||
217 | static void list_symbol_table (void); | |||
218 | static void print_source (file_info_type *, list_info_type *, char *, unsigned int); | |||
219 | static int debugging_pseudo (list_info_type *, const char *); | |||
220 | static void listing_listing (char *); | |||
221 | ||||
222 | static void | |||
223 | listing_message (const char *name, const char *message) | |||
224 | { | |||
225 | if (listing_tail != (list_info_type *) NULL((void*)0)) | |||
226 | { | |||
227 | unsigned int l = strlen (name) + strlen (message) + 1; | |||
228 | char *n = (char *) xmalloc (l); | |||
229 | strcpy (n, name); | |||
230 | strcat (n, message); | |||
231 | listing_tail->message = n; | |||
232 | } | |||
233 | } | |||
234 | ||||
235 | void | |||
236 | listing_warning (const char *message) | |||
237 | { | |||
238 | listing_message (_("Warning:")("Warning:"), message); | |||
239 | } | |||
240 | ||||
241 | void | |||
242 | listing_error (const char *message) | |||
243 | { | |||
244 | listing_message (_("Error:")("Error:"), message); | |||
245 | } | |||
246 | ||||
247 | static file_info_type * | |||
248 | file_info (const char *file_name) | |||
249 | { | |||
250 | /* Find an entry with this file name. */ | |||
251 | file_info_type *p = file_info_head; | |||
252 | ||||
253 | while (p != (file_info_type *) NULL((void*)0)) | |||
254 | { | |||
255 | if (strcmp (p->filename, file_name) == 0) | |||
256 | return p; | |||
257 | p = p->next; | |||
258 | } | |||
259 | ||||
260 | /* Make new entry. */ | |||
261 | p = xmalloc (sizeof (file_info_type)); | |||
262 | p->next = file_info_head; | |||
263 | file_info_head = p; | |||
264 | p->filename = xstrdup (file_name); | |||
265 | p->pos = 0; | |||
266 | p->linenum = 0; | |||
267 | p->at_end = 0; | |||
268 | ||||
269 | return p; | |||
270 | } | |||
271 | ||||
272 | static void | |||
273 | new_frag (void) | |||
274 | { | |||
275 | frag_wane (frag_now); | |||
276 | frag_new (0); | |||
277 | } | |||
278 | ||||
279 | void | |||
280 | listing_newline (char *ps) | |||
281 | { | |||
282 | char *file; | |||
283 | unsigned int line; | |||
284 | static unsigned int last_line = 0xffff; | |||
285 | static char *last_file = NULL((void*)0); | |||
286 | list_info_type *new = NULL((void*)0); | |||
287 | ||||
288 | if (listing == 0) | |||
289 | return; | |||
290 | ||||
291 | if (now_seg == absolute_section((asection *) &bfd_abs_section)) | |||
292 | return; | |||
293 | ||||
294 | #ifdef OBJ_ELF1 | |||
295 | /* In ELF, anything in a section beginning with .debug or .line is | |||
296 | considered to be debugging information. This includes the | |||
297 | statement which switches us into the debugging section, which we | |||
298 | can only set after we are already in the debugging section. */ | |||
299 | if ((listing & LISTING_NODEBUG16) != 0 | |||
300 | && listing_tail != NULL((void*)0) | |||
301 | && ! listing_tail->debugging) | |||
302 | { | |||
303 | const char *segname; | |||
304 | ||||
305 | segname = segment_name (now_seg)((now_seg)->name + 0); | |||
306 | if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 | |||
307 | || strncmp (segname, ".line", sizeof ".line" - 1) == 0) | |||
308 | listing_tail->debugging = 1; | |||
309 | } | |||
310 | #endif | |||
311 | ||||
312 | as_where (&file, &line); | |||
313 | if (ps == NULL((void*)0)) | |||
314 | { | |||
315 | if (line == last_line | |||
316 | && !(last_file && file && strcmp (file, last_file))) | |||
317 | return; | |||
318 | ||||
319 | new = (list_info_type *) xmalloc (sizeof (list_info_type)); | |||
320 | ||||
321 | /* Detect if we are reading from stdin by examining the file | |||
322 | name returned by as_where(). | |||
323 | ||||
324 | [FIXME: We rely upon the name in the strcmp below being the | |||
325 | same as the one used by input_scrub_new_file(), if that is | |||
326 | not true, then this code will fail]. | |||
327 | ||||
328 | If we are reading from stdin, then we need to save each input | |||
329 | line here (assuming of course that we actually have a line of | |||
330 | input to read), so that it can be displayed in the listing | |||
331 | that is produced at the end of the assembly. */ | |||
332 | if (strcmp (file, _("{standard input}")("{standard input}")) == 0 | |||
333 | && input_line_pointer != NULL((void*)0)) | |||
334 | { | |||
335 | char *copy; | |||
336 | int len; | |||
337 | int seen_quote = 0; | |||
338 | ||||
339 | for (copy = input_line_pointer - 1; | |||
340 | *copy && (seen_quote | |||
341 | || (! is_end_of_line [(unsigned char) *copy])); | |||
342 | copy++) | |||
343 | if (*copy == '"' && copy[-1] != '\\') | |||
344 | seen_quote = ! seen_quote; | |||
345 | ||||
346 | len = (copy - input_line_pointer) + 2; | |||
347 | ||||
348 | copy = xmalloc (len); | |||
349 | ||||
350 | if (copy != NULL((void*)0)) | |||
351 | { | |||
352 | char *src = input_line_pointer - 1; | |||
353 | char *dest = copy; | |||
354 | ||||
355 | while (--len) | |||
356 | { | |||
357 | unsigned char c = *src++; | |||
358 | ||||
359 | /* Omit control characters in the listing. */ | |||
360 | if (!ISCNTRL (c)(_sch_istable[(c) & 0xff] & (unsigned short)(_sch_iscntrl ))) | |||
361 | *dest++ = c; | |||
362 | } | |||
363 | ||||
364 | *dest = 0; | |||
365 | } | |||
366 | ||||
367 | new->line_contents = copy; | |||
368 | } | |||
369 | else | |||
370 | new->line_contents = NULL((void*)0); | |||
371 | } | |||
372 | else | |||
373 | { | |||
374 | new = xmalloc (sizeof (list_info_type)); | |||
375 | new->line_contents = ps; | |||
376 | } | |||
377 | ||||
378 | last_line = line; | |||
379 | last_file = file; | |||
380 | ||||
381 | new_frag (); | |||
382 | ||||
383 | if (listing_tail) | |||
384 | listing_tail->next = new; | |||
385 | else | |||
386 | head = new; | |||
387 | ||||
388 | listing_tail = new; | |||
389 | ||||
390 | new->frag = frag_now; | |||
391 | new->line = line; | |||
392 | new->file = file_info (file); | |||
393 | new->next = (list_info_type *) NULL((void*)0); | |||
394 | new->message = (char *) NULL((void*)0); | |||
395 | new->edict = EDICT_NONE; | |||
396 | new->hll_file = (file_info_type *) NULL((void*)0); | |||
397 | new->hll_line = 0; | |||
398 | new->debugging = 0; | |||
399 | ||||
400 | new_frag (); | |||
401 | ||||
402 | #ifdef OBJ_ELF1 | |||
403 | /* In ELF, anything in a section beginning with .debug or .line is | |||
404 | considered to be debugging information. */ | |||
405 | if ((listing & LISTING_NODEBUG16) != 0) | |||
406 | { | |||
407 | const char *segname; | |||
408 | ||||
409 | segname = segment_name (now_seg)((now_seg)->name + 0); | |||
410 | if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 | |||
411 | || strncmp (segname, ".line", sizeof ".line" - 1) == 0) | |||
412 | new->debugging = 1; | |||
413 | } | |||
414 | #endif | |||
415 | } | |||
416 | ||||
417 | /* Attach all current frags to the previous line instead of the | |||
418 | current line. This is called by the MIPS backend when it discovers | |||
419 | that it needs to add some NOP instructions; the added NOP | |||
420 | instructions should go with the instruction that has the delay, not | |||
421 | with the new instruction. */ | |||
422 | ||||
423 | void | |||
424 | listing_prev_line (void) | |||
425 | { | |||
426 | list_info_type *l; | |||
427 | fragS *f; | |||
428 | ||||
429 | if (head == (list_info_type *) NULL((void*)0) | |||
430 | || head == listing_tail) | |||
431 | return; | |||
432 | ||||
433 | new_frag (); | |||
434 | ||||
435 | for (l = head; l->next != listing_tail; l = l->next) | |||
436 | ; | |||
437 | ||||
438 | for (f = frchain_now->frch_root; f != (fragS *) NULL((void*)0); f = f->fr_next) | |||
439 | if (f->line == listing_tail) | |||
440 | f->line = l; | |||
441 | ||||
442 | listing_tail->frag = frag_now; | |||
443 | new_frag (); | |||
444 | } | |||
445 | ||||
446 | /* This function returns the next source line from the file supplied, | |||
447 | truncated to size. It appends a fake line to the end of each input | |||
448 | file to make. */ | |||
449 | ||||
450 | static char * | |||
451 | buffer_line (file_info_type *file, char *line, unsigned int size) | |||
452 | { | |||
453 | unsigned int count = 0; | |||
454 | int c; | |||
455 | ||||
456 | char *p = line; | |||
457 | ||||
458 | /* If we couldn't open the file, return an empty line. */ | |||
459 | if (file->at_end
| |||
460 | return ""; | |||
461 | ||||
462 | /* Check the cache and see if we last used this file. */ | |||
463 | if (!last_open_file_info || file != last_open_file_info) | |||
464 | { | |||
465 | if (last_open_file) | |||
466 | { | |||
467 | last_open_file_info->pos = ftell (last_open_file); | |||
| ||||
468 | fclose (last_open_file); | |||
469 | } | |||
470 | ||||
471 | last_open_file_info = file; | |||
472 | last_open_file = fopen (file->filename, FOPEN_RT"r"); | |||
473 | if (last_open_file == NULL((void*)0)) | |||
474 | { | |||
475 | file->at_end = 1; | |||
476 | return ""; | |||
477 | } | |||
478 | ||||
479 | /* Seek to where we were last time this file was open. */ | |||
480 | if (file->pos) | |||
481 | fseek (last_open_file, file->pos, SEEK_SET0); | |||
482 | } | |||
483 | ||||
484 | c = fgetc (last_open_file); | |||
485 | ||||
486 | /* Leave room for null. */ | |||
487 | size -= 1; | |||
488 | ||||
489 | while (c != EOF(-1) && c != '\n') | |||
490 | { | |||
491 | if (count < size) | |||
492 | *p++ = c; | |||
493 | count++; | |||
494 | ||||
495 | c = fgetc (last_open_file); | |||
496 | ||||
497 | } | |||
498 | if (c == EOF(-1)) | |||
499 | { | |||
500 | file->at_end = 1; | |||
501 | if (count + 2 < size) | |||
502 | { | |||
503 | *p++ = '.'; | |||
504 | *p++ = '.'; | |||
505 | *p++ = '.'; | |||
506 | } | |||
507 | } | |||
508 | file->linenum++; | |||
509 | *p++ = 0; | |||
510 | return line; | |||
511 | } | |||
512 | ||||
513 | static const char *fn; | |||
514 | ||||
515 | static unsigned int eject; /* Eject pending */ | |||
516 | static unsigned int page; /* Current page number */ | |||
517 | static char *title; /* Current title */ | |||
518 | static char *subtitle; /* Current subtitle */ | |||
519 | static unsigned int on_page; /* Number of lines printed on current page */ | |||
520 | ||||
521 | static void | |||
522 | listing_page (list_info_type *list) | |||
523 | { | |||
524 | /* Grope around, see if we can see a title or subtitle edict coming up | |||
525 | soon. (we look down 10 lines of the page and see if it's there) */ | |||
526 | if ((eject || (on_page >= (unsigned int) paper_height)) | |||
527 | && paper_height != 0) | |||
528 | { | |||
529 | unsigned int c = 10; | |||
530 | int had_title = 0; | |||
531 | int had_subtitle = 0; | |||
532 | ||||
533 | page++; | |||
534 | ||||
535 | while (c != 0 && list) | |||
536 | { | |||
537 | if (list->edict == EDICT_SBTTL && !had_subtitle) | |||
538 | { | |||
539 | had_subtitle = 1; | |||
540 | subtitle = list->edict_arg; | |||
541 | } | |||
542 | if (list->edict == EDICT_TITLE && !had_title) | |||
543 | { | |||
544 | had_title = 1; | |||
545 | title = list->edict_arg; | |||
546 | } | |||
547 | list = list->next; | |||
548 | c--; | |||
549 | } | |||
550 | ||||
551 | if (page > 1) | |||
552 | { | |||
553 | fprintf (list_file, "\f"); | |||
554 | } | |||
555 | ||||
556 | fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER"GAS LISTING", fn, page); | |||
557 | fprintf (list_file, "%s\n", title); | |||
558 | fprintf (list_file, "%s\n", subtitle); | |||
559 | on_page = 3; | |||
560 | eject = 0; | |||
561 | } | |||
562 | } | |||
563 | ||||
564 | static unsigned int | |||
565 | calc_hex (list_info_type *list) | |||
566 | { | |||
567 | int data_buffer_size; | |||
568 | list_info_type *first = list; | |||
569 | unsigned int address = ~(unsigned int) 0; | |||
570 | fragS *frag; | |||
571 | fragS *frag_ptr; | |||
572 | unsigned int octet_in_frag; | |||
573 | ||||
574 | /* Find first frag which says it belongs to this line. */ | |||
575 | frag = list->frag; | |||
576 | while (frag && frag->line != list) | |||
577 | frag = frag->fr_next; | |||
578 | ||||
579 | frag_ptr = frag; | |||
580 | ||||
581 | data_buffer_size = 0; | |||
582 | ||||
583 | /* Dump all the frags which belong to this line. */ | |||
584 | while (frag_ptr != (fragS *) NULL((void*)0) && frag_ptr->line == first) | |||
585 | { | |||
586 | /* Print as many bytes from the fixed part as is sensible. */ | |||
587 | octet_in_frag = 0; | |||
588 | while ((offsetT) octet_in_frag < frag_ptr->fr_fix | |||
589 | && data_buffer_size < MAX_BYTES(((4 * 2) + 1) * listing_lhs_width + ((((4 * 2) + 1) * listing_lhs_width_second ) * listing_lhs_cont_lines) + 20) - 3) | |||
590 | { | |||
591 | if (address == ~(unsigned int) 0) | |||
592 | address = frag_ptr->fr_address / OCTETS_PER_BYTE(1<<0); | |||
593 | ||||
594 | sprintf (data_buffer + data_buffer_size, | |||
595 | "%02X", | |||
596 | (frag_ptr->fr_literal[octet_in_frag]) & 0xff); | |||
597 | data_buffer_size += 2; | |||
598 | octet_in_frag++; | |||
599 | } | |||
600 | if (frag_ptr->fr_type == rs_fill) | |||
601 | { | |||
602 | unsigned int var_rep_max = octet_in_frag; | |||
603 | unsigned int var_rep_idx = octet_in_frag; | |||
604 | ||||
605 | /* Print as many bytes from the variable part as is sensible. */ | |||
606 | while (((offsetT) octet_in_frag | |||
607 | < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)) | |||
608 | && data_buffer_size < MAX_BYTES(((4 * 2) + 1) * listing_lhs_width + ((((4 * 2) + 1) * listing_lhs_width_second ) * listing_lhs_cont_lines) + 20) - 3) | |||
609 | { | |||
610 | if (address == ~(unsigned int) 0) | |||
611 | address = frag_ptr->fr_address / OCTETS_PER_BYTE(1<<0); | |||
612 | ||||
613 | sprintf (data_buffer + data_buffer_size, | |||
614 | "%02X", | |||
615 | (frag_ptr->fr_literal[var_rep_idx]) & 0xff); | |||
616 | data_buffer_size += 2; | |||
617 | ||||
618 | var_rep_idx++; | |||
619 | octet_in_frag++; | |||
620 | ||||
621 | if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) | |||
622 | var_rep_idx = var_rep_max; | |||
623 | } | |||
624 | } | |||
625 | ||||
626 | frag_ptr = frag_ptr->fr_next; | |||
627 | } | |||
628 | data_buffer[data_buffer_size] = '\0'; | |||
629 | return address; | |||
630 | } | |||
631 | ||||
632 | static void | |||
633 | print_lines (list_info_type *list, unsigned int lineno, | |||
634 | char *string, unsigned int address) | |||
635 | { | |||
636 | unsigned int idx; | |||
637 | unsigned int nchars; | |||
638 | unsigned int lines; | |||
639 | unsigned int octet_in_word = 0; | |||
640 | char *src = data_buffer; | |||
641 | int cur; | |||
642 | ||||
643 | /* Print the stuff on the first line. */ | |||
644 | listing_page (list); | |||
645 | nchars = (LISTING_WORD_SIZE4 * 2 + 1) * listing_lhs_width; | |||
646 | ||||
647 | /* Print the hex for the first line. */ | |||
648 | if (address == ~(unsigned int) 0) | |||
649 | { | |||
650 | fprintf (list_file, "% 4d ", lineno); | |||
651 | for (idx = 0; idx < nchars; idx++) | |||
652 | fprintf (list_file, " "); | |||
653 | ||||
654 | fprintf (list_file, "\t%s\n", string ? string : ""); | |||
655 | ||||
656 | on_page++; | |||
657 | ||||
658 | listing_page (0); | |||
659 | ||||
660 | return; | |||
661 | } | |||
662 | ||||
663 | if (had_errors ()) | |||
664 | fprintf (list_file, "% 4d ???? ", lineno); | |||
665 | else | |||
666 | fprintf (list_file, "% 4d %04x ", lineno, address); | |||
667 | ||||
668 | /* And the data to go along with it. */ | |||
669 | idx = 0; | |||
670 | cur = 0; | |||
671 | while (src[cur] && idx < nchars) | |||
672 | { | |||
673 | int offset; | |||
674 | offset = cur; | |||
675 | fprintf (list_file, "%c%c", src[offset], src[offset + 1]); | |||
676 | cur += 2; | |||
677 | octet_in_word++; | |||
678 | ||||
679 | if (octet_in_word == LISTING_WORD_SIZE4) | |||
680 | { | |||
681 | fprintf (list_file, " "); | |||
682 | idx++; | |||
683 | octet_in_word = 0; | |||
684 | } | |||
685 | ||||
686 | idx += 2; | |||
687 | } | |||
688 | ||||
689 | for (; idx < nchars; idx++) | |||
690 | fprintf (list_file, " "); | |||
691 | ||||
692 | fprintf (list_file, "\t%s\n", string ? string : ""); | |||
693 | on_page++; | |||
694 | listing_page (list); | |||
695 | ||||
696 | if (list->message) | |||
697 | { | |||
698 | fprintf (list_file, "**** %s\n", list->message); | |||
699 | listing_page (list); | |||
700 | on_page++; | |||
701 | } | |||
702 | ||||
703 | for (lines = 0; | |||
704 | lines < (unsigned int) listing_lhs_cont_lines | |||
705 | && src[cur]; | |||
706 | lines++) | |||
707 | { | |||
708 | nchars = ((LISTING_WORD_SIZE4 * 2) + 1) * listing_lhs_width_second - 1; | |||
709 | idx = 0; | |||
710 | ||||
711 | /* Print any more lines of data, but more compactly. */ | |||
712 | fprintf (list_file, "% 4d ", lineno); | |||
713 | ||||
714 | while (src[cur] && idx < nchars) | |||
715 | { | |||
716 | int offset; | |||
717 | offset = cur; | |||
718 | fprintf (list_file, "%c%c", src[offset], src[offset + 1]); | |||
719 | cur += 2; | |||
720 | idx += 2; | |||
721 | octet_in_word++; | |||
722 | ||||
723 | if (octet_in_word == LISTING_WORD_SIZE4) | |||
724 | { | |||
725 | fprintf (list_file, " "); | |||
726 | idx++; | |||
727 | octet_in_word = 0; | |||
728 | } | |||
729 | } | |||
730 | ||||
731 | fprintf (list_file, "\n"); | |||
732 | on_page++; | |||
733 | listing_page (list); | |||
734 | } | |||
735 | } | |||
736 | ||||
737 | static void | |||
738 | list_symbol_table (void) | |||
739 | { | |||
740 | extern symbolS *symbol_rootP; | |||
741 | int got_some = 0; | |||
742 | ||||
743 | symbolS *ptr; | |||
744 | eject = 1; | |||
745 | listing_page (0); | |||
746 | ||||
747 | for (ptr = symbol_rootP; ptr != (symbolS *) NULL((void*)0); ptr = symbol_next (ptr)) | |||
748 | { | |||
749 | if (SEG_NORMAL (S_GET_SEGMENT (ptr))( (S_GET_SEGMENT (ptr)) != ((asection *) &bfd_abs_section ) && (S_GET_SEGMENT (ptr)) != ((asection *) &bfd_und_section ) && (S_GET_SEGMENT (ptr)) != reg_section && ( S_GET_SEGMENT (ptr)) != expr_section) | |||
750 | || S_GET_SEGMENT (ptr) == absolute_section((asection *) &bfd_abs_section)) | |||
751 | { | |||
752 | /* Don't report section symbols. They are not interesting. */ | |||
753 | if (symbol_section_p (ptr)) | |||
754 | continue; | |||
755 | ||||
756 | if (S_GET_NAME (ptr)) | |||
757 | { | |||
758 | char buf[30], fmt[8]; | |||
759 | valueT val = S_GET_VALUE (ptr); | |||
760 | ||||
761 | /* @@ Note that this is dependent on the compilation options, | |||
762 | not solely on the target characteristics. */ | |||
763 | if (sizeof (val) == 4 && sizeof (int) == 4) | |||
764 | sprintf (buf, "%08lx", (unsigned long) val); | |||
765 | else if (sizeof (val) <= sizeof (unsigned long)) | |||
766 | { | |||
767 | sprintf (fmt, "%%0%lulx", | |||
768 | (unsigned long) (sizeof (val) * 2)); | |||
769 | sprintf (buf, fmt, (unsigned long) val); | |||
770 | } | |||
771 | #if defined (BFD64) | |||
772 | else if (sizeof (val) > 4) | |||
773 | sprintf_vma (buf, val)sprintf (buf, "%016lx", val); | |||
774 | #endif | |||
775 | else | |||
776 | abort ()as_abort ("/usr/src/gnu/usr.bin/binutils-2.17/gas/listing.c", 776, __PRETTY_FUNCTION__); | |||
777 | ||||
778 | if (!got_some) | |||
779 | { | |||
780 | fprintf (list_file, "DEFINED SYMBOLS\n"); | |||
781 | on_page++; | |||
782 | got_some = 1; | |||
783 | } | |||
784 | ||||
785 | if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line) | |||
786 | { | |||
787 | fprintf (list_file, "%20s:%-5d %s:%s %s\n", | |||
788 | symbol_get_frag (ptr)->line->file->filename, | |||
789 | symbol_get_frag (ptr)->line->line, | |||
790 | segment_name (S_GET_SEGMENT (ptr))((S_GET_SEGMENT (ptr))->name + 0), | |||
791 | buf, S_GET_NAME (ptr)); | |||
792 | } | |||
793 | else | |||
794 | { | |||
795 | fprintf (list_file, "%33s:%s %s\n", | |||
796 | segment_name (S_GET_SEGMENT (ptr))((S_GET_SEGMENT (ptr))->name + 0), | |||
797 | buf, S_GET_NAME (ptr)); | |||
798 | } | |||
799 | ||||
800 | on_page++; | |||
801 | listing_page (0); | |||
802 | } | |||
803 | } | |||
804 | ||||
805 | } | |||
806 | if (!got_some) | |||
807 | { | |||
808 | fprintf (list_file, "NO DEFINED SYMBOLS\n"); | |||
809 | on_page++; | |||
810 | } | |||
811 | fprintf (list_file, "\n"); | |||
812 | on_page++; | |||
813 | listing_page (0); | |||
814 | ||||
815 | got_some = 0; | |||
816 | ||||
817 | for (ptr = symbol_rootP; ptr != (symbolS *) NULL((void*)0); ptr = symbol_next (ptr)) | |||
818 | { | |||
819 | if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) | |||
820 | { | |||
821 | if (S_GET_SEGMENT (ptr) == undefined_section((asection *) &bfd_und_section)) | |||
822 | { | |||
823 | if (!got_some) | |||
824 | { | |||
825 | got_some = 1; | |||
826 | fprintf (list_file, "UNDEFINED SYMBOLS\n"); | |||
827 | on_page++; | |||
828 | listing_page (0); | |||
829 | } | |||
830 | fprintf (list_file, "%s\n", S_GET_NAME (ptr)); | |||
831 | on_page++; | |||
832 | listing_page (0); | |||
833 | } | |||
834 | } | |||
835 | } | |||
836 | if (!got_some) | |||
837 | { | |||
838 | fprintf (list_file, "NO UNDEFINED SYMBOLS\n"); | |||
839 | on_page++; | |||
840 | listing_page (0); | |||
841 | } | |||
842 | } | |||
843 | ||||
844 | static void | |||
845 | print_source (file_info_type *current_file, list_info_type *list, | |||
846 | char *buffer, unsigned int width) | |||
847 | { | |||
848 | if (!current_file->at_end) | |||
849 | { | |||
850 | while (current_file->linenum < list->hll_line | |||
851 | && !current_file->at_end) | |||
852 | { | |||
853 | char *p = buffer_line (current_file, buffer, width); | |||
854 | ||||
855 | fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum, | |||
856 | current_file->filename, p); | |||
857 | on_page++; | |||
858 | listing_page (list); | |||
859 | } | |||
860 | } | |||
861 | } | |||
862 | ||||
863 | /* Sometimes the user doesn't want to be bothered by the debugging | |||
864 | records inserted by the compiler, see if the line is suspicious. */ | |||
865 | ||||
866 | static int | |||
867 | debugging_pseudo (list_info_type *list, const char *line) | |||
868 | { | |||
869 | static int in_debug; | |||
870 | int was_debug; | |||
871 | ||||
872 | if (list->debugging) | |||
873 | { | |||
874 | in_debug = 1; | |||
875 | return 1; | |||
876 | } | |||
877 | ||||
878 | was_debug = in_debug; | |||
879 | in_debug = 0; | |||
880 | ||||
881 | while (ISSPACE (*line)(_sch_istable[(*line) & 0xff] & (unsigned short)(_sch_isspace ))) | |||
882 | line++; | |||
883 | ||||
884 | if (*line != '.') | |||
885 | { | |||
886 | #ifdef OBJ_ELF1 | |||
887 | /* The ELF compiler sometimes emits blank lines after switching | |||
888 | out of a debugging section. If the next line drops us back | |||
889 | into debugging information, then don't print the blank line. | |||
890 | This is a hack for a particular compiler behaviour, not a | |||
891 | general case. */ | |||
892 | if (was_debug | |||
893 | && *line == '\0' | |||
894 | && list->next != NULL((void*)0) | |||
895 | && list->next->debugging) | |||
896 | { | |||
897 | in_debug = 1; | |||
898 | return 1; | |||
899 | } | |||
900 | #endif | |||
901 | ||||
902 | return 0; | |||
903 | } | |||
904 | ||||
905 | line++; | |||
906 | ||||
907 | if (strncmp (line, "def", 3) == 0) | |||
908 | return 1; | |||
909 | if (strncmp (line, "val", 3) == 0) | |||
910 | return 1; | |||
911 | if (strncmp (line, "scl", 3) == 0) | |||
912 | return 1; | |||
913 | if (strncmp (line, "line", 4) == 0) | |||
914 | return 1; | |||
915 | if (strncmp (line, "endef", 5) == 0) | |||
916 | return 1; | |||
917 | if (strncmp (line, "ln", 2) == 0) | |||
918 | return 1; | |||
919 | if (strncmp (line, "type", 4) == 0) | |||
920 | return 1; | |||
921 | if (strncmp (line, "size", 4) == 0) | |||
922 | return 1; | |||
923 | if (strncmp (line, "dim", 3) == 0) | |||
924 | return 1; | |||
925 | if (strncmp (line, "tag", 3) == 0) | |||
926 | return 1; | |||
927 | if (strncmp (line, "stabs", 5) == 0) | |||
928 | return 1; | |||
929 | if (strncmp (line, "stabn", 5) == 0) | |||
930 | return 1; | |||
931 | ||||
932 | return 0; | |||
933 | } | |||
934 | ||||
935 | static void | |||
936 | listing_listing (char *name ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
937 | { | |||
938 | list_info_type *list = head; | |||
939 | file_info_type *current_hll_file = (file_info_type *) NULL((void*)0); | |||
940 | char *message; | |||
941 | char *buffer; | |||
942 | char *p; | |||
943 | int show_listing = 1; | |||
944 | unsigned int width; | |||
945 | ||||
946 | buffer = xmalloc (listing_rhs_width); | |||
947 | data_buffer = xmalloc (MAX_BYTES(((4 * 2) + 1) * listing_lhs_width + ((((4 * 2) + 1) * listing_lhs_width_second ) * listing_lhs_cont_lines) + 20)); | |||
948 | eject = 1; | |||
949 | list = head; | |||
950 | ||||
951 | while (list != (list_info_type *) NULL((void*)0) && 0) | |||
952 | { | |||
953 | if (list->next) | |||
954 | list->frag = list->next->frag; | |||
955 | list = list->next; | |||
956 | } | |||
957 | ||||
958 | list = head->next; | |||
959 | ||||
960 | while (list) | |||
961 | { | |||
962 | unsigned int list_line; | |||
963 | ||||
964 | width = listing_rhs_width > paper_width ? paper_width : | |||
965 | listing_rhs_width; | |||
966 | ||||
967 | list_line = list->line; | |||
968 | switch (list->edict) | |||
969 | { | |||
970 | case EDICT_LIST: | |||
971 | /* Skip all lines up to the current. */ | |||
972 | list_line--; | |||
973 | break; | |||
974 | case EDICT_NOLIST: | |||
975 | show_listing--; | |||
976 | break; | |||
977 | case EDICT_NOLIST_NEXT: | |||
978 | if (show_listing == 0) | |||
979 | list_line--; | |||
980 | break; | |||
981 | case EDICT_EJECT: | |||
982 | break; | |||
983 | case EDICT_NONE: | |||
984 | break; | |||
985 | case EDICT_TITLE: | |||
986 | title = list->edict_arg; | |||
987 | break; | |||
988 | case EDICT_SBTTL: | |||
989 | subtitle = list->edict_arg; | |||
990 | break; | |||
991 | default: | |||
992 | abort ()as_abort ("/usr/src/gnu/usr.bin/binutils-2.17/gas/listing.c", 992, __PRETTY_FUNCTION__); | |||
993 | } | |||
994 | ||||
995 | if (show_listing
| |||
996 | { | |||
997 | while (list->file->linenum < list_line | |||
998 | && !list->file->at_end) | |||
999 | p = buffer_line (list->file, buffer, width); | |||
1000 | } | |||
1001 | ||||
1002 | if (list->edict == EDICT_LIST | |||
1003 | || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0)) | |||
1004 | { | |||
1005 | /* Enable listing for the single line that caused the enable. */ | |||
1006 | list_line++; | |||
1007 | show_listing++; | |||
1008 | } | |||
1009 | ||||
1010 | if (show_listing > 0) | |||
1011 | { | |||
1012 | /* Scan down the list and print all the stuff which can be done | |||
1013 | with this line (or lines). */ | |||
1014 | message = 0; | |||
1015 | ||||
1016 | if (list->hll_file) | |||
1017 | current_hll_file = list->hll_file; | |||
1018 | ||||
1019 | if (current_hll_file && list->hll_line && (listing & LISTING_HLL8)) | |||
1020 | print_source (current_hll_file, list, buffer, width); | |||
1021 | ||||
1022 | if (list->line_contents) | |||
1023 | { | |||
1024 | if (!((listing & LISTING_NODEBUG16) | |||
1025 | && debugging_pseudo (list, list->line_contents))) | |||
1026 | print_lines (list, | |||
1027 | list->file->linenum == 0 ? list->line : list->file->linenum, | |||
1028 | list->line_contents, calc_hex (list)); | |||
1029 | ||||
1030 | free (list->line_contents); | |||
1031 | list->line_contents = NULL((void*)0); | |||
1032 | } | |||
1033 | else | |||
1034 | { | |||
1035 | while (list->file->linenum < list_line | |||
1036 | && !list->file->at_end) | |||
1037 | { | |||
1038 | unsigned int address; | |||
1039 | ||||
1040 | p = buffer_line (list->file, buffer, width); | |||
1041 | ||||
1042 | if (list->file->linenum < list_line) | |||
1043 | address = ~(unsigned int) 0; | |||
1044 | else | |||
1045 | address = calc_hex (list); | |||
1046 | ||||
1047 | if (!((listing & LISTING_NODEBUG16) | |||
1048 | && debugging_pseudo (list, p))) | |||
1049 | print_lines (list, list->file->linenum, p, address); | |||
1050 | } | |||
1051 | } | |||
1052 | ||||
1053 | if (list->edict == EDICT_EJECT) | |||
1054 | eject = 1; | |||
1055 | } | |||
1056 | ||||
1057 | if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1) | |||
1058 | --show_listing; | |||
1059 | ||||
1060 | list = list->next; | |||
1061 | } | |||
1062 | ||||
1063 | free (buffer); | |||
1064 | free (data_buffer); | |||
1065 | data_buffer = NULL((void*)0); | |||
1066 | } | |||
1067 | ||||
1068 | void | |||
1069 | listing_print (char *name) | |||
1070 | { | |||
1071 | int using_stdout; | |||
1072 | ||||
1073 | title = ""; | |||
1074 | subtitle = ""; | |||
1075 | ||||
1076 | if (name == NULL((void*)0)) | |||
| ||||
1077 | { | |||
1078 | list_file = stdout(&__sF[1]); | |||
1079 | using_stdout = 1; | |||
1080 | } | |||
1081 | else | |||
1082 | { | |||
1083 | list_file = fopen (name, FOPEN_WT"w"); | |||
1084 | if (list_file != NULL((void*)0)) | |||
1085 | using_stdout = 0; | |||
1086 | else | |||
1087 | { | |||
1088 | bfd_set_error (bfd_error_system_call); | |||
1089 | as_perror (_("can't open list file: %s")("can't open list file: %s"), name); | |||
1090 | list_file = stdout(&__sF[1]); | |||
1091 | using_stdout = 1; | |||
1092 | } | |||
1093 | } | |||
1094 | ||||
1095 | if (listing & LISTING_NOFORM4) | |||
1096 | paper_height = 0; | |||
1097 | ||||
1098 | if (listing & LISTING_LISTING1) | |||
1099 | listing_listing (name); | |||
1100 | ||||
1101 | if (listing & LISTING_SYMBOLS2) | |||
1102 | list_symbol_table (); | |||
1103 | ||||
1104 | if (! using_stdout) | |||
1105 | { | |||
1106 | if (fclose (list_file) == EOF(-1)) | |||
1107 | { | |||
1108 | bfd_set_error (bfd_error_system_call); | |||
1109 | as_perror (_("error closing list file: %s")("error closing list file: %s"), name); | |||
1110 | } | |||
1111 | } | |||
1112 | ||||
1113 | if (last_open_file) | |||
1114 | fclose (last_open_file); | |||
1115 | } | |||
1116 | ||||
1117 | void | |||
1118 | listing_file (const char *name) | |||
1119 | { | |||
1120 | fn = name; | |||
1121 | } | |||
1122 | ||||
1123 | void | |||
1124 | listing_eject (int ignore ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
1125 | { | |||
1126 | if (listing) | |||
1127 | listing_tail->edict = EDICT_EJECT; | |||
1128 | } | |||
1129 | ||||
1130 | void | |||
1131 | listing_flags (int ignore ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
1132 | { | |||
1133 | while ((*input_line_pointer++) && (*input_line_pointer != '\n')) | |||
1134 | input_line_pointer++; | |||
1135 | ||||
1136 | } | |||
1137 | ||||
1138 | /* Turn listing on or off. An argument of 0 means to turn off | |||
1139 | listing. An argument of 1 means to turn on listing. An argument | |||
1140 | of 2 means to turn off listing, but as of the next line; that is, | |||
1141 | the current line should be listed, but the next line should not. */ | |||
1142 | ||||
1143 | void | |||
1144 | listing_list (int on) | |||
1145 | { | |||
1146 | if (listing) | |||
1147 | { | |||
1148 | switch (on) | |||
1149 | { | |||
1150 | case 0: | |||
1151 | if (listing_tail->edict == EDICT_LIST) | |||
1152 | listing_tail->edict = EDICT_NONE; | |||
1153 | else | |||
1154 | listing_tail->edict = EDICT_NOLIST; | |||
1155 | break; | |||
1156 | case 1: | |||
1157 | if (listing_tail->edict == EDICT_NOLIST | |||
1158 | || listing_tail->edict == EDICT_NOLIST_NEXT) | |||
1159 | listing_tail->edict = EDICT_NONE; | |||
1160 | else | |||
1161 | listing_tail->edict = EDICT_LIST; | |||
1162 | break; | |||
1163 | case 2: | |||
1164 | listing_tail->edict = EDICT_NOLIST_NEXT; | |||
1165 | break; | |||
1166 | default: | |||
1167 | abort ()as_abort ("/usr/src/gnu/usr.bin/binutils-2.17/gas/listing.c", 1167, __PRETTY_FUNCTION__); | |||
1168 | } | |||
1169 | } | |||
1170 | } | |||
1171 | ||||
1172 | void | |||
1173 | listing_psize (int width_only) | |||
1174 | { | |||
1175 | if (! width_only) | |||
1176 | { | |||
1177 | paper_height = get_absolute_expression (); | |||
1178 | ||||
1179 | if (paper_height < 0 || paper_height > 1000) | |||
1180 | { | |||
1181 | paper_height = 0; | |||
1182 | as_warn (_("strange paper height, set to no form")("strange paper height, set to no form")); | |||
1183 | } | |||
1184 | ||||
1185 | if (*input_line_pointer != ',') | |||
1186 | { | |||
1187 | demand_empty_rest_of_line (); | |||
1188 | return; | |||
1189 | } | |||
1190 | ||||
1191 | ++input_line_pointer; | |||
1192 | } | |||
1193 | ||||
1194 | paper_width = get_absolute_expression (); | |||
1195 | ||||
1196 | demand_empty_rest_of_line (); | |||
1197 | } | |||
1198 | ||||
1199 | void | |||
1200 | listing_nopage (int ignore ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
1201 | { | |||
1202 | paper_height = 0; | |||
1203 | } | |||
1204 | ||||
1205 | void | |||
1206 | listing_title (int depth) | |||
1207 | { | |||
1208 | int quoted; | |||
1209 | char *start; | |||
1210 | char *ttl; | |||
1211 | unsigned int length; | |||
1212 | ||||
1213 | SKIP_WHITESPACE ()((*input_line_pointer == ' ') ? ++input_line_pointer : 0); | |||
1214 | if (*input_line_pointer != '\"') | |||
1215 | quoted = 0; | |||
1216 | else | |||
1217 | { | |||
1218 | quoted = 1; | |||
1219 | ++input_line_pointer; | |||
1220 | } | |||
1221 | ||||
1222 | start = input_line_pointer; | |||
1223 | ||||
1224 | while (*input_line_pointer) | |||
1225 | { | |||
1226 | if (quoted | |||
1227 | ? *input_line_pointer == '\"' | |||
1228 | : is_end_of_line[(unsigned char) *input_line_pointer]) | |||
1229 | { | |||
1230 | if (listing) | |||
1231 | { | |||
1232 | length = input_line_pointer - start; | |||
1233 | ttl = xmalloc (length + 1); | |||
1234 | memcpy (ttl, start, length); | |||
1235 | ttl[length] = 0; | |||
1236 | listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; | |||
1237 | listing_tail->edict_arg = ttl; | |||
1238 | } | |||
1239 | if (quoted) | |||
1240 | input_line_pointer++; | |||
1241 | demand_empty_rest_of_line (); | |||
1242 | return; | |||
1243 | } | |||
1244 | else if (*input_line_pointer == '\n') | |||
1245 | { | |||
1246 | as_bad (_("new line in title")("new line in title")); | |||
1247 | demand_empty_rest_of_line (); | |||
1248 | return; | |||
1249 | } | |||
1250 | else | |||
1251 | { | |||
1252 | input_line_pointer++; | |||
1253 | } | |||
1254 | } | |||
1255 | } | |||
1256 | ||||
1257 | void | |||
1258 | listing_source_line (unsigned int line) | |||
1259 | { | |||
1260 | if (listing) | |||
1261 | { | |||
1262 | new_frag (); | |||
1263 | listing_tail->hll_line = line; | |||
1264 | new_frag (); | |||
1265 | } | |||
1266 | } | |||
1267 | ||||
1268 | void | |||
1269 | listing_source_file (const char *file) | |||
1270 | { | |||
1271 | if (listing) | |||
1272 | listing_tail->hll_file = file_info (file); | |||
1273 | } | |||
1274 | ||||
1275 | #else | |||
1276 | ||||
1277 | /* Dummy functions for when compiled without listing enabled. */ | |||
1278 | ||||
1279 | void | |||
1280 | listing_flags (int ignore) | |||
1281 | { | |||
1282 | s_ignore (0); | |||
1283 | } | |||
1284 | ||||
1285 | void | |||
1286 | listing_list (int on) | |||
1287 | { | |||
1288 | s_ignore (0); | |||
1289 | } | |||
1290 | ||||
1291 | void | |||
1292 | listing_eject (int ignore) | |||
1293 | { | |||
1294 | s_ignore (0); | |||
1295 | } | |||
1296 | ||||
1297 | void | |||
1298 | listing_psize (int ignore) | |||
1299 | { | |||
1300 | s_ignore (0); | |||
1301 | } | |||
1302 | ||||
1303 | void | |||
1304 | listing_nopage (int ignore) | |||
1305 | { | |||
1306 | s_ignore (0); | |||
1307 | } | |||
1308 | ||||
1309 | void | |||
1310 | listing_title (int depth) | |||
1311 | { | |||
1312 | s_ignore (0); | |||
1313 | } | |||
1314 | ||||
1315 | void | |||
1316 | listing_file (const char *name) | |||
1317 | { | |||
1318 | } | |||
1319 | ||||
1320 | void | |||
1321 | listing_newline (char *name) | |||
1322 | { | |||
1323 | } | |||
1324 | ||||
1325 | void | |||
1326 | listing_source_line (unsigned int n) | |||
1327 | { | |||
1328 | } | |||
1329 | ||||
1330 | void | |||
1331 | listing_source_file (const char *n) | |||
1332 | { | |||
1333 | } | |||
1334 | ||||
1335 | #endif |