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