listing.c revision 1.1
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 (now_seg == absolute_section) 306 return; 307 308 as_where (&file, &line); 309 if (line != last_line || (last_file && file && strcmp(file, last_file))) 310 { 311 last_line = line; 312 last_file = file; 313 new_frag (); 314 315 new = (list_info_type *) xmalloc (sizeof (list_info_type)); 316 new->frag = frag_now; 317 new->line = line; 318 new->file = file_info (file); 319 320 if (listing_tail) 321 { 322 listing_tail->next = new; 323 } 324 else 325 { 326 head = new; 327 } 328 listing_tail = new; 329 new->next = (list_info_type *) NULL; 330 new->message = (char *) NULL; 331 new->edict = EDICT_NONE; 332 new->hll_file = (file_info_type *) NULL; 333 new->hll_line = 0; 334 new_frag (); 335 } 336} 337 338/* Attach all current frags to the previous line instead of the 339 current line. This is called by the MIPS backend when it discovers 340 that it needs to add some NOP instructions; the added NOP 341 instructions should go with the instruction that has the delay, not 342 with the new instruction. */ 343 344void 345listing_prev_line () 346{ 347 list_info_type *l; 348 fragS *f; 349 350 if (head == (list_info_type *) NULL 351 || head == listing_tail) 352 return; 353 354 new_frag (); 355 356 for (l = head; l->next != listing_tail; l = l->next) 357 ; 358 359 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next) 360 if (f->line == listing_tail) 361 f->line = l; 362 363 listing_tail->frag = frag_now; 364 new_frag (); 365} 366 367/* 368 This function returns the next source line from the file supplied, 369 truncated to size. It appends a fake line to the end of each input 370 file to make 371*/ 372 373static char * 374buffer_line (file, line, size) 375 file_info_type * file; 376 char *line; 377 unsigned int size; 378{ 379 unsigned int count = 0; 380 int c; 381 382 char *p = line; 383 384 /* If we couldn't open the file, return an empty line */ 385 if (file->file == (FILE *) NULL || file->at_end) 386 { 387 return ""; 388 } 389 390 if (file->linenum == 0) 391 rewind (file->file); 392 393 c = fgetc (file->file); 394 395 size -= 1; /* leave room for null */ 396 397 while (c != EOF && c != '\n') 398 { 399 if (count < size) 400 *p++ = c; 401 count++; 402 403 c = fgetc (file->file); 404 405 } 406 if (c == EOF) 407 { 408 file->at_end = 1; 409 *p++ = '.'; 410 *p++ = '.'; 411 *p++ = '.'; 412 } 413 file->linenum++; 414 *p++ = 0; 415 return line; 416} 417 418 419static const char *fn; 420 421static unsigned int eject; /* Eject pending */ 422static unsigned int page; /* Current page number */ 423static char *title; /* current title */ 424static char *subtitle; /* current subtitle */ 425static unsigned int on_page; /* number of lines printed on current page */ 426 427 428static void 429listing_page (list) 430 list_info_type *list; 431{ 432 /* Grope around, see if we can see a title or subtitle edict coming up 433 soon (we look down 10 lines of the page and see if it's there)*/ 434 if ((eject || (on_page >= paper_height)) && paper_height != 0) 435 { 436 unsigned int c = 10; 437 int had_title = 0; 438 int had_subtitle = 0; 439 440 page++; 441 442 while (c != 0 && list) 443 { 444 if (list->edict == EDICT_SBTTL && !had_subtitle) 445 { 446 had_subtitle = 1; 447 subtitle = list->edict_arg; 448 } 449 if (list->edict == EDICT_TITLE && !had_title) 450 { 451 had_title = 1; 452 title = list->edict_arg; 453 } 454 list = list->next; 455 c--; 456 } 457 458 459 if (page > 1) 460 { 461 fprintf (list_file, "\f"); 462 } 463 464 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); 465 fprintf (list_file, "%s\n", title); 466 fprintf (list_file, "%s\n", subtitle); 467 on_page = 3; 468 eject = 0; 469 } 470} 471 472 473static unsigned int 474calc_hex (list) 475 list_info_type * list; 476{ 477 list_info_type *first = list; 478 unsigned int address = (unsigned int) ~0; 479 480 fragS *frag; 481 fragS *frag_ptr; 482 483 unsigned int byte_in_frag; 484 485 486 /* Find first frag which says it belongs to this line */ 487 frag = list->frag; 488 while (frag && frag->line != list) 489 frag = frag->fr_next; 490 491 frag_ptr = frag; 492 493 data_buffer_size = 0; 494 495 /* Dump all the frags which belong to this line */ 496 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) 497 { 498 /* Print as many bytes from the fixed part as is sensible */ 499 byte_in_frag = 0; 500 while (byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof (data_buffer) - 10) 501 { 502 if (address == ~0) 503 { 504 address = frag_ptr->fr_address; 505 } 506 507 sprintf (data_buffer + data_buffer_size, 508 "%02X", 509 (frag_ptr->fr_literal[byte_in_frag]) & 0xff); 510 data_buffer_size += 2; 511 byte_in_frag++; 512 } 513 { 514 unsigned int var_rep_max = byte_in_frag; 515 unsigned int var_rep_idx = byte_in_frag; 516 517 /* Print as many bytes from the variable part as is sensible */ 518 while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset 519 && data_buffer_size < sizeof (data_buffer) - 10) 520 { 521 if (address == ~0) 522 { 523 address = frag_ptr->fr_address; 524 } 525 sprintf (data_buffer + data_buffer_size, 526 "%02X", 527 (frag_ptr->fr_literal[var_rep_idx]) & 0xff); 528#if 0 529 data_buffer[data_buffer_size++] = '*'; 530 data_buffer[data_buffer_size++] = '*'; 531#endif 532 data_buffer_size += 2; 533 534 var_rep_idx++; 535 byte_in_frag++; 536 537 if (var_rep_idx >= frag_ptr->fr_var) 538 var_rep_idx = var_rep_max; 539 } 540 } 541 542 frag_ptr = frag_ptr->fr_next; 543 } 544 data_buffer[data_buffer_size++] = 0; 545 return address; 546} 547 548 549 550 551 552 553static void 554print_lines (list, string, address) 555 list_info_type *list; 556 char *string; 557 unsigned int address; 558{ 559 unsigned int idx; 560 unsigned int nchars; 561 unsigned int lines; 562 unsigned int byte_in_word = 0; 563 char *src = data_buffer; 564 565 /* Print the stuff on the first line */ 566 listing_page (list); 567 nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH; 568 /* Print the hex for the first line */ 569 if (address == ~0) 570 { 571 fprintf (list_file, "% 4d ", list->line); 572 for (idx = 0; idx < nchars; idx++) 573 fprintf (list_file, " "); 574 575 fprintf (list_file, "\t%s\n", string ? string : ""); 576 on_page++; 577 listing_page (0); 578 579 } 580 else 581 { 582 if (had_errors ()) 583 { 584 fprintf (list_file, "% 4d ???? ", list->line); 585 } 586 else 587 { 588 fprintf (list_file, "% 4d %04x ", list->line, address); 589 } 590 591 /* And the data to go along with it */ 592 idx = 0; 593 594 while (*src && idx < nchars) 595 { 596 fprintf (list_file, "%c%c", src[0], src[1]); 597 src += 2; 598 byte_in_word++; 599 if (byte_in_word == LISTING_WORD_SIZE) 600 { 601 fprintf (list_file, " "); 602 idx++; 603 byte_in_word = 0; 604 } 605 idx += 2; 606 } 607 608 for (; idx < nchars; idx++) 609 fprintf (list_file, " "); 610 611 fprintf (list_file, "\t%s\n", string ? string : ""); 612 on_page++; 613 listing_page (list); 614 if (list->message) 615 { 616 fprintf (list_file, "**** %s\n", list->message); 617 listing_page (list); 618 on_page++; 619 } 620 621 for (lines = 0; 622 lines < LISTING_LHS_CONT_LINES 623 && *src; 624 lines++) 625 { 626 nchars = ((LISTING_WORD_SIZE * 2) + 1) * LISTING_LHS_WIDTH_SECOND - 1; 627 idx = 0; 628 /* Print any more lines of data, but more compactly */ 629 fprintf (list_file, "% 4d ", list->line); 630 631 while (*src && idx < nchars) 632 { 633 fprintf (list_file, "%c%c", src[0], src[1]); 634 src += 2; 635 idx += 2; 636 byte_in_word++; 637 if (byte_in_word == LISTING_WORD_SIZE) 638 { 639 fprintf (list_file, " "); 640 idx++; 641 byte_in_word = 0; 642 } 643 } 644 645 fprintf (list_file, "\n"); 646 on_page++; 647 listing_page (list); 648 649 } 650 651 652 } 653} 654 655 656static void 657list_symbol_table () 658{ 659 extern symbolS *symbol_rootP; 660 int got_some = 0; 661 662 symbolS *ptr; 663 eject = 1; 664 listing_page (0); 665 666 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 667 { 668 if (ptr->sy_frag->line) 669 { 670 if (S_GET_NAME (ptr)) 671 { 672 char buf[30], fmt[8]; 673 valueT val = S_GET_VALUE (ptr); 674 675 /* @@ Note that this is dependent on the compilation options, 676 not solely on the target characteristics. */ 677 if (sizeof (val) == 4 && sizeof (int) == 4) 678 sprintf (buf, "%08lx", (unsigned long) val); 679 else if (sizeof (val) <= sizeof (unsigned long)) 680 { 681 sprintf (fmt, "%%0%lulx", 682 (unsigned long) (sizeof (val) * 2)); 683 sprintf (buf, fmt, (unsigned long) val); 684 } 685#if defined (BFD64) 686 else if (sizeof (val) > 4) 687 { 688 char buf1[30]; 689 sprintf_vma (buf1, val); 690 strcpy (buf, "00000000"); 691 strcpy (buf + 8 - strlen (buf1), buf1); 692 } 693#endif 694 else 695 abort (); 696 697 if (!got_some) 698 { 699 fprintf (list_file, "DEFINED SYMBOLS\n"); 700 on_page++; 701 got_some = 1; 702 } 703 704 fprintf (list_file, "%20s:%-5d %s:%s %s\n", 705 ptr->sy_frag->line->file->filename, 706 ptr->sy_frag->line->line, 707 segment_name (S_GET_SEGMENT (ptr)), 708 buf, S_GET_NAME (ptr)); 709 710 on_page++; 711 listing_page (0); 712 } 713 } 714 715 } 716 if (!got_some) 717 { 718 fprintf (list_file, "NO DEFINED SYMBOLS\n"); 719 on_page++; 720 } 721 fprintf (list_file, "\n"); 722 on_page++; 723 listing_page (0); 724 725 got_some = 0; 726 727 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 728 { 729 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) 730 { 731 if (ptr->sy_frag->line == 0 732#ifdef S_IS_REGISTER 733 && !S_IS_REGISTER (ptr) 734#endif 735 && S_GET_SEGMENT (ptr) != reg_section) 736 { 737 if (!got_some) 738 { 739 got_some = 1; 740 fprintf (list_file, "UNDEFINED SYMBOLS\n"); 741 on_page++; 742 listing_page (0); 743 } 744 fprintf (list_file, "%s\n", S_GET_NAME (ptr)); 745 on_page++; 746 listing_page (0); 747 } 748 } 749 } 750 if (!got_some) 751 { 752 fprintf (list_file, "NO UNDEFINED SYMBOLS\n"); 753 on_page++; 754 listing_page (0); 755 } 756} 757 758static void 759print_source (current_file, list, buffer, width) 760 file_info_type *current_file; 761 list_info_type *list; 762 char *buffer; 763 unsigned int width; 764{ 765 if (current_file->file) 766 { 767 while (current_file->linenum < list->hll_line 768 && !current_file->at_end) 769 { 770 char *p = buffer_line (current_file, buffer, width); 771 fprintf (list_file, "%4d:%-13s **** %s\n", current_file->linenum, 772 current_file->filename, p); 773 on_page++; 774 listing_page (list); 775 } 776 } 777} 778 779/* Sometimes the user doesn't want to be bothered by the debugging 780 records inserted by the compiler, see if the line is suspicious */ 781 782static int 783debugging_pseudo (line) 784 char *line; 785{ 786 while (isspace (*line)) 787 line++; 788 789 if (*line != '.') 790 return 0; 791 792 line++; 793 794 if (strncmp (line, "def", 3) == 0) 795 return 1; 796 if (strncmp (line, "val", 3) == 0) 797 return 1; 798 if (strncmp (line, "scl", 3) == 0) 799 return 1; 800 if (strncmp (line, "line", 4) == 0) 801 return 1; 802 if (strncmp (line, "endef", 5) == 0) 803 return 1; 804 if (strncmp (line, "ln", 2) == 0) 805 return 1; 806 if (strncmp (line, "type", 4) == 0) 807 return 1; 808 if (strncmp (line, "size", 4) == 0) 809 return 1; 810 if (strncmp (line, "dim", 3) == 0) 811 return 1; 812 if (strncmp (line, "tag", 3) == 0) 813 return 1; 814 815 if (strncmp (line, "stabs", 5) == 0) 816 return 1; 817 if (strncmp (line, "stabn", 5) == 0) 818 return 1; 819 820 return 0; 821 822} 823 824static void 825listing_listing (name) 826 char *name; 827{ 828 list_info_type *list = head; 829 file_info_type *current_hll_file = (file_info_type *) NULL; 830 char *message; 831 char *buffer; 832 char *p; 833 int show_listing = 1; 834 unsigned int width; 835 836 buffer = xmalloc (LISTING_RHS_WIDTH); 837 eject = 1; 838 list = head; 839 840 while (list != (list_info_type *) NULL && 0) 841 { 842 if (list->next) 843 list->frag = list->next->frag; 844 list = list->next; 845 846 } 847 848 list = head->next; 849 850 851 while (list) 852 { 853 width = LISTING_RHS_WIDTH > paper_width ? paper_width : 854 LISTING_RHS_WIDTH; 855 856 switch (list->edict) 857 { 858 case EDICT_LIST: 859 show_listing++; 860 break; 861 case EDICT_NOLIST: 862 show_listing--; 863 break; 864 case EDICT_EJECT: 865 break; 866 case EDICT_NONE: 867 break; 868 case EDICT_TITLE: 869 title = list->edict_arg; 870 break; 871 case EDICT_SBTTL: 872 subtitle = list->edict_arg; 873 break; 874 default: 875 abort (); 876 } 877 878 if (show_listing > 0) 879 { 880 /* Scan down the list and print all the stuff which can be done 881 with this line (or lines). */ 882 message = 0; 883 884 if (list->hll_file) 885 { 886 current_hll_file = list->hll_file; 887 } 888 889 if (current_hll_file && list->hll_line && listing & LISTING_HLL) 890 { 891 print_source (current_hll_file, list, buffer, width); 892 } 893 894 while (list->file->file 895 && list->file->linenum < list->line 896 && !list->file->at_end) 897 { 898 p = buffer_line (list->file, buffer, width); 899 900 if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p))) 901 { 902 print_lines (list, p, calc_hex (list)); 903 } 904 } 905 906 if (list->edict == EDICT_EJECT) 907 { 908 eject = 1; 909 } 910 } 911 else 912 { 913 while (list->file->file 914 && list->file->linenum < list->line 915 && !list->file->at_end) 916 p = buffer_line (list->file, buffer, width); 917 } 918 919 list = list->next; 920 } 921 free (buffer); 922} 923 924void 925listing_print (name) 926 char *name; 927{ 928 title = ""; 929 subtitle = ""; 930 931 if (name == NULL) 932 list_file = stdout; 933 else 934 { 935 list_file = fopen (name, "w"); 936 if (list_file == NULL) 937 { 938 as_perror ("can't open list file: %s", name); 939 list_file = stdout; 940 } 941 } 942 943 if (listing & LISTING_NOFORM) 944 { 945 paper_height = 0; 946 } 947 948 if (listing & LISTING_LISTING) 949 { 950 listing_listing (name); 951 952 } 953 if (listing & LISTING_SYMBOLS) 954 { 955 list_symbol_table (); 956 } 957} 958 959 960void 961listing_file (name) 962 const char *name; 963{ 964 fn = name; 965} 966 967void 968listing_eject (ignore) 969 int ignore; 970{ 971 listing_tail->edict = EDICT_EJECT; 972} 973 974void 975listing_flags (ignore) 976 int ignore; 977{ 978 while ((*input_line_pointer++) && (*input_line_pointer != '\n')) 979 input_line_pointer++; 980 981} 982 983void 984listing_list (on) 985 int on; 986{ 987 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; 988} 989 990 991void 992listing_psize (width_only) 993 int width_only; 994{ 995 if (! width_only) 996 { 997 paper_height = get_absolute_expression (); 998 999 if (paper_height < 0 || paper_height > 1000) 1000 { 1001 paper_height = 0; 1002 as_warn ("strange paper height, set to no form"); 1003 } 1004 1005 if (*input_line_pointer != ',') 1006 { 1007 demand_empty_rest_of_line (); 1008 return; 1009 } 1010 1011 ++input_line_pointer; 1012 } 1013 1014 paper_width = get_absolute_expression (); 1015 1016 demand_empty_rest_of_line (); 1017} 1018 1019void 1020listing_nopage (ignore) 1021 int ignore; 1022{ 1023 paper_height = 0; 1024} 1025 1026void 1027listing_title (depth) 1028 int depth; 1029{ 1030 int quoted; 1031 char *start; 1032 char *ttl; 1033 unsigned int length; 1034 1035 SKIP_WHITESPACE (); 1036 if (*input_line_pointer != '\"') 1037 quoted = 0; 1038 else 1039 { 1040 quoted = 1; 1041 ++input_line_pointer; 1042 } 1043 1044 start = input_line_pointer; 1045 1046 while (*input_line_pointer) 1047 { 1048 if (quoted 1049 ? *input_line_pointer == '\"' 1050 : is_end_of_line[(unsigned char) *input_line_pointer]) 1051 { 1052 length = input_line_pointer - start; 1053 ttl = xmalloc (length + 1); 1054 memcpy (ttl, start, length); 1055 ttl[length] = 0; 1056 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; 1057 listing_tail->edict_arg = ttl; 1058 if (quoted) 1059 input_line_pointer++; 1060 demand_empty_rest_of_line (); 1061 return; 1062 } 1063 else if (*input_line_pointer == '\n') 1064 { 1065 as_bad ("New line in title"); 1066 demand_empty_rest_of_line (); 1067 return; 1068 } 1069 else 1070 { 1071 input_line_pointer++; 1072 } 1073 } 1074} 1075 1076 1077 1078void 1079listing_source_line (line) 1080 unsigned int line; 1081{ 1082 new_frag (); 1083 listing_tail->hll_line = line; 1084 new_frag (); 1085 1086} 1087 1088void 1089listing_source_file (file) 1090 const char *file; 1091{ 1092 if (listing_tail) 1093 listing_tail->hll_file = file_info (file); 1094} 1095 1096 1097 1098#else 1099 1100 1101/* Dummy functions for when compiled without listing enabled */ 1102 1103void 1104listing_flags (ignore) 1105 int ignore; 1106{ 1107 s_ignore (0); 1108} 1109 1110void 1111listing_list (on) 1112 int on; 1113{ 1114 s_ignore (0); 1115} 1116 1117void 1118listing_eject (ignore) 1119 int ignore; 1120{ 1121 s_ignore (0); 1122} 1123 1124void 1125listing_psize (ignore) 1126 int ignore; 1127{ 1128 s_ignore (0); 1129} 1130 1131void 1132listing_nopage (ignore) 1133 int ignore; 1134{ 1135 s_ignore (0); 1136} 1137 1138void 1139listing_title (depth) 1140 int depth; 1141{ 1142 s_ignore (0); 1143} 1144 1145void 1146listing_file (name) 1147 const char *name; 1148{ 1149 1150} 1151 1152void 1153listing_newline (name) 1154 char *name; 1155{ 1156 1157} 1158 1159void 1160listing_source_line (n) 1161 unsigned int n; 1162{ 1163 1164} 1165void 1166listing_source_file (n) 1167 const char *n; 1168{ 1169 1170} 1171 1172#endif 1173