listing.c revision 1.2
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 { 692 char buf1[30]; 693 sprintf_vma (buf1, val); 694 strcpy (buf, "00000000"); 695 strcpy (buf + 8 - strlen (buf1), buf1); 696 } 697#endif 698 else 699 abort (); 700 701 if (!got_some) 702 { 703 fprintf (list_file, "DEFINED SYMBOLS\n"); 704 on_page++; 705 got_some = 1; 706 } 707 708 fprintf (list_file, "%20s:%-5d %s:%s %s\n", 709 ptr->sy_frag->line->file->filename, 710 ptr->sy_frag->line->line, 711 segment_name (S_GET_SEGMENT (ptr)), 712 buf, S_GET_NAME (ptr)); 713 714 on_page++; 715 listing_page (0); 716 } 717 } 718 719 } 720 if (!got_some) 721 { 722 fprintf (list_file, "NO DEFINED SYMBOLS\n"); 723 on_page++; 724 } 725 fprintf (list_file, "\n"); 726 on_page++; 727 listing_page (0); 728 729 got_some = 0; 730 731 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 732 { 733 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) 734 { 735 if (ptr->sy_frag->line == 0 736#ifdef S_IS_REGISTER 737 && !S_IS_REGISTER (ptr) 738#endif 739 && S_GET_SEGMENT (ptr) != reg_section) 740 { 741 if (!got_some) 742 { 743 got_some = 1; 744 fprintf (list_file, "UNDEFINED SYMBOLS\n"); 745 on_page++; 746 listing_page (0); 747 } 748 fprintf (list_file, "%s\n", S_GET_NAME (ptr)); 749 on_page++; 750 listing_page (0); 751 } 752 } 753 } 754 if (!got_some) 755 { 756 fprintf (list_file, "NO UNDEFINED SYMBOLS\n"); 757 on_page++; 758 listing_page (0); 759 } 760} 761 762static void 763print_source (current_file, list, buffer, width) 764 file_info_type *current_file; 765 list_info_type *list; 766 char *buffer; 767 unsigned int width; 768{ 769 if (current_file->file) 770 { 771 while (current_file->linenum < list->hll_line 772 && !current_file->at_end) 773 { 774 char *p = buffer_line (current_file, buffer, width); 775 fprintf (list_file, "%4d:%-13s **** %s\n", current_file->linenum, 776 current_file->filename, p); 777 on_page++; 778 listing_page (list); 779 } 780 } 781} 782 783/* Sometimes the user doesn't want to be bothered by the debugging 784 records inserted by the compiler, see if the line is suspicious */ 785 786static int 787debugging_pseudo (line) 788 char *line; 789{ 790 while (isspace (*line)) 791 line++; 792 793 if (*line != '.') 794 return 0; 795 796 line++; 797 798 if (strncmp (line, "def", 3) == 0) 799 return 1; 800 if (strncmp (line, "val", 3) == 0) 801 return 1; 802 if (strncmp (line, "scl", 3) == 0) 803 return 1; 804 if (strncmp (line, "line", 4) == 0) 805 return 1; 806 if (strncmp (line, "endef", 5) == 0) 807 return 1; 808 if (strncmp (line, "ln", 2) == 0) 809 return 1; 810 if (strncmp (line, "type", 4) == 0) 811 return 1; 812 if (strncmp (line, "size", 4) == 0) 813 return 1; 814 if (strncmp (line, "dim", 3) == 0) 815 return 1; 816 if (strncmp (line, "tag", 3) == 0) 817 return 1; 818 819 if (strncmp (line, "stabs", 5) == 0) 820 return 1; 821 if (strncmp (line, "stabn", 5) == 0) 822 return 1; 823 824 return 0; 825 826} 827 828static void 829listing_listing (name) 830 char *name; 831{ 832 list_info_type *list = head; 833 file_info_type *current_hll_file = (file_info_type *) NULL; 834 char *message; 835 char *buffer; 836 char *p; 837 int show_listing = 1; 838 unsigned int width; 839 840 buffer = xmalloc (LISTING_RHS_WIDTH); 841 eject = 1; 842 list = head; 843 844 while (list != (list_info_type *) NULL && 0) 845 { 846 if (list->next) 847 list->frag = list->next->frag; 848 list = list->next; 849 850 } 851 852 list = head->next; 853 854 855 while (list) 856 { 857 width = LISTING_RHS_WIDTH > paper_width ? paper_width : 858 LISTING_RHS_WIDTH; 859 860 switch (list->edict) 861 { 862 case EDICT_LIST: 863 show_listing++; 864 break; 865 case EDICT_NOLIST: 866 show_listing--; 867 break; 868 case EDICT_EJECT: 869 break; 870 case EDICT_NONE: 871 break; 872 case EDICT_TITLE: 873 title = list->edict_arg; 874 break; 875 case EDICT_SBTTL: 876 subtitle = list->edict_arg; 877 break; 878 default: 879 abort (); 880 } 881 882 if (show_listing > 0) 883 { 884 /* Scan down the list and print all the stuff which can be done 885 with this line (or lines). */ 886 message = 0; 887 888 if (list->hll_file) 889 { 890 current_hll_file = list->hll_file; 891 } 892 893 if (current_hll_file && list->hll_line && listing & LISTING_HLL) 894 { 895 print_source (current_hll_file, list, buffer, width); 896 } 897 898 while (list->file->file 899 && list->file->linenum < list->line 900 && !list->file->at_end) 901 { 902 p = buffer_line (list->file, buffer, width); 903 904 if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p))) 905 { 906 print_lines (list, p, calc_hex (list)); 907 } 908 } 909 910 if (list->edict == EDICT_EJECT) 911 { 912 eject = 1; 913 } 914 } 915 else 916 { 917 while (list->file->file 918 && list->file->linenum < list->line 919 && !list->file->at_end) 920 p = buffer_line (list->file, buffer, width); 921 } 922 923 list = list->next; 924 } 925 free (buffer); 926} 927 928void 929listing_print (name) 930 char *name; 931{ 932 int using_stdout; 933 file_info_type *fi; 934 935 title = ""; 936 subtitle = ""; 937 938 if (name == NULL) 939 { 940 list_file = stdout; 941 using_stdout = 1; 942 } 943 else 944 { 945 list_file = fopen (name, "w"); 946 if (list_file != NULL) 947 using_stdout = 0; 948 else 949 { 950 as_perror ("can't open list file: %s", name); 951 list_file = stdout; 952 using_stdout = 1; 953 } 954 } 955 956 if (listing & LISTING_NOFORM) 957 { 958 paper_height = 0; 959 } 960 961 if (listing & LISTING_LISTING) 962 { 963 listing_listing (name); 964 } 965 966 if (listing & LISTING_SYMBOLS) 967 { 968 list_symbol_table (); 969 } 970 971 if (! using_stdout) 972 { 973 if (fclose (list_file) == EOF) 974 as_perror ("error closing list file: %s", name); 975 } 976 977 for (fi = file_info_head; fi != NULL; fi = fi->next) 978 { 979 if (fi->file != NULL) 980 { 981 fclose (fi->file); 982 fi->file = NULL; 983 } 984 } 985} 986 987 988void 989listing_file (name) 990 const char *name; 991{ 992 fn = name; 993} 994 995void 996listing_eject (ignore) 997 int ignore; 998{ 999 if (listing) 1000 listing_tail->edict = EDICT_EJECT; 1001} 1002 1003void 1004listing_flags (ignore) 1005 int ignore; 1006{ 1007 while ((*input_line_pointer++) && (*input_line_pointer != '\n')) 1008 input_line_pointer++; 1009 1010} 1011 1012void 1013listing_list (on) 1014 int on; 1015{ 1016 if (listing) 1017 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; 1018} 1019 1020 1021void 1022listing_psize (width_only) 1023 int width_only; 1024{ 1025 if (! width_only) 1026 { 1027 paper_height = get_absolute_expression (); 1028 1029 if (paper_height < 0 || paper_height > 1000) 1030 { 1031 paper_height = 0; 1032 as_warn ("strange paper height, set to no form"); 1033 } 1034 1035 if (*input_line_pointer != ',') 1036 { 1037 demand_empty_rest_of_line (); 1038 return; 1039 } 1040 1041 ++input_line_pointer; 1042 } 1043 1044 paper_width = get_absolute_expression (); 1045 1046 demand_empty_rest_of_line (); 1047} 1048 1049void 1050listing_nopage (ignore) 1051 int ignore; 1052{ 1053 paper_height = 0; 1054} 1055 1056void 1057listing_title (depth) 1058 int depth; 1059{ 1060 int quoted; 1061 char *start; 1062 char *ttl; 1063 unsigned int length; 1064 1065 SKIP_WHITESPACE (); 1066 if (*input_line_pointer != '\"') 1067 quoted = 0; 1068 else 1069 { 1070 quoted = 1; 1071 ++input_line_pointer; 1072 } 1073 1074 start = input_line_pointer; 1075 1076 while (*input_line_pointer) 1077 { 1078 if (quoted 1079 ? *input_line_pointer == '\"' 1080 : is_end_of_line[(unsigned char) *input_line_pointer]) 1081 { 1082 if (listing) 1083 { 1084 length = input_line_pointer - start; 1085 ttl = xmalloc (length + 1); 1086 memcpy (ttl, start, length); 1087 ttl[length] = 0; 1088 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; 1089 listing_tail->edict_arg = ttl; 1090 } 1091 if (quoted) 1092 input_line_pointer++; 1093 demand_empty_rest_of_line (); 1094 return; 1095 } 1096 else if (*input_line_pointer == '\n') 1097 { 1098 as_bad ("New line in title"); 1099 demand_empty_rest_of_line (); 1100 return; 1101 } 1102 else 1103 { 1104 input_line_pointer++; 1105 } 1106 } 1107} 1108 1109 1110 1111void 1112listing_source_line (line) 1113 unsigned int line; 1114{ 1115 if (listing) 1116 { 1117 new_frag (); 1118 listing_tail->hll_line = line; 1119 new_frag (); 1120 } 1121} 1122 1123void 1124listing_source_file (file) 1125 const char *file; 1126{ 1127 if (listing) 1128 listing_tail->hll_file = file_info (file); 1129} 1130 1131 1132 1133#else 1134 1135 1136/* Dummy functions for when compiled without listing enabled */ 1137 1138void 1139listing_flags (ignore) 1140 int ignore; 1141{ 1142 s_ignore (0); 1143} 1144 1145void 1146listing_list (on) 1147 int on; 1148{ 1149 s_ignore (0); 1150} 1151 1152void 1153listing_eject (ignore) 1154 int ignore; 1155{ 1156 s_ignore (0); 1157} 1158 1159void 1160listing_psize (ignore) 1161 int ignore; 1162{ 1163 s_ignore (0); 1164} 1165 1166void 1167listing_nopage (ignore) 1168 int ignore; 1169{ 1170 s_ignore (0); 1171} 1172 1173void 1174listing_title (depth) 1175 int depth; 1176{ 1177 s_ignore (0); 1178} 1179 1180void 1181listing_file (name) 1182 const char *name; 1183{ 1184 1185} 1186 1187void 1188listing_newline (name) 1189 char *name; 1190{ 1191 1192} 1193 1194void 1195listing_source_line (n) 1196 unsigned int n; 1197{ 1198 1199} 1200void 1201listing_source_file (n) 1202 const char *n; 1203{ 1204 1205} 1206 1207#endif 1208