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