This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: ld -o behaviour


Hi Ben,

:    Note - there is still a problem if the user decides to call their
:    executable 'utput' since "gcc -output foo.c" will collide with the
:    -output linker switch...
: 
: Yes, you're right.  In this case, I think it would be reasonable to only
: accept --output (and not the single-dash version).  What do you think?

Well, if we were going to do that, then we might as well do the same
for -omagic and not rename it.

Something like the patch below.

Preferences anyone ?

Cheers
	Nick

2000-12-27  Nick Clifton  <nickc@redhat.com>

	* lexsup.c (struct ld_option): Add new enum value:
	EXACTLY_TWO_DASHES.
	(ld_options[]): Change -omagic, -output and -oformat options
	to be EXACTLY_TWO_DASHES.
	(OUTPUT_COUNT): Use ARRAY_SIZE.
	(parse_args): Change parameter 'argc' to unsigned.
	Place EXACTLY_TWO_DASHES options into new really_longopts
	array.
	If getopt_long_only fails, try calling getopt_long using the
	really_longopts array.
	(help): Print a double dash for both EXACTLY_TWO_DASHES and
	TWO_DASHES options.

	* ldlex.h: Fix prototype of parse_args.

	* ld.texinfo: Document that long options starting with 'o'
	must be preceeded by two dashes.  Change example of a single
	dashed long option from -oformat to -trace-symbol.

Index: lexsup.c
===================================================================
RCS file: /cvs/src//src/ld/lexsup.c,v
retrieving revision 1.24
diff -p -r1.24 lexsup.c
*** lexsup.c	2000/12/12 20:53:00	1.24
--- lexsup.c	2000/12/28 01:59:27
*************** struct ld_option
*** 148,153 ****
--- 148,163 ----
      ONE_DASH,
      /* Use two dashes before long option name.  */
      TWO_DASHES,
+     /* Only accept two dashes before the long option name.
+        This is an overloading of the use of this enum, since originally it
+        was only intended to tell the --help display function how to display
+        the long option name.  This feature was added in order to resolve
+        the confusion about the -omagic command line switch.  Is it setting
+        the output file name to "magic" or is it setting the NMAGIC flag on
+        the output ?  It has been decided that it is setting the output file
+        name, and that if you want to set the NMAGIC flag you should use -N
+        or --omagic.  */
+     EXACTLY_TWO_DASHES,
      /* Don't mention this option in --help output.  */
      NO_HELP
    } control;
*************** static const struct ld_option ld_options
*** 200,208 ****
        'n', NULL, N_("Do not page align data"), TWO_DASHES },
    { {"omagic", no_argument, NULL, 'N'},
        'N', NULL, N_("Do not page align data, do not make text readonly"),
!       TWO_DASHES },
    { {"output", required_argument, NULL, 'o'},
!       'o', N_("FILE"), N_("Set output file name"), TWO_DASHES },
    { {NULL, required_argument, NULL, '\0'},
        'O', NULL, N_("Optimize output file"), ONE_DASH },
    { {"Qy", no_argument, NULL, OPTION_IGNORE},
--- 210,218 ----
        'n', NULL, N_("Do not page align data"), TWO_DASHES },
    { {"omagic", no_argument, NULL, 'N'},
        'N', NULL, N_("Do not page align data, do not make text readonly"),
!       EXACTLY_TWO_DASHES },
    { {"output", required_argument, NULL, 'o'},
!       'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES },
    { {NULL, required_argument, NULL, '\0'},
        'O', NULL, N_("Optimize output file"), ONE_DASH },
    { {"Qy", no_argument, NULL, OPTION_IGNORE},
*************** static const struct ld_option ld_options
*** 312,318 ****
    { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
        '\0', NULL, NULL, NO_HELP },
    { {"oformat", required_argument, NULL, OPTION_OFORMAT},
!       '\0', N_("TARGET"), N_("Specify target of output file"), TWO_DASHES },
    { {"qmagic", no_argument, NULL, OPTION_IGNORE},
        '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
    { {"relax", no_argument, NULL, OPTION_RELAX},
--- 322,328 ----
    { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
        '\0', NULL, NULL, NO_HELP },
    { {"oformat", required_argument, NULL, OPTION_OFORMAT},
!       '\0', N_("TARGET"), N_("Specify target of output file"), EXACTLY_TWO_DASHES },
    { {"qmagic", no_argument, NULL, OPTION_IGNORE},
        '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
    { {"relax", no_argument, NULL, OPTION_RELAX},
*************** static const struct ld_option ld_options
*** 382,388 ****
        '\0', N_("[=WORDS]"), N_("Modify problematic branches in last WORDS (1-10,\n\t\t\t\tdefault 5) words of a page"), TWO_DASHES }
  };
  
! #define OPTION_COUNT ((int) (sizeof ld_options / sizeof ld_options[0]))
  
  /* Test STRING for containing a string of digits that form a number
     between MIN and MAX.  The return value is the number or ERR.  */
--- 392,398 ----
        '\0', N_("[=WORDS]"), N_("Modify problematic branches in last WORDS (1-10,\n\t\t\t\tdefault 5) words of a page"), TWO_DASHES }
  };
  
! #define OPTION_COUNT ARRAY_SIZE (ld_options)
  
  /* Test STRING for containing a string of digits that form a number
     between MIN and MAX.  The return value is the number or ERR.  */
*************** is_num (string, min, max, err)
*** 413,426 ****
  
  void
  parse_args (argc, argv)
!      int argc;
       char **argv;
  {
!   int i, is, il;
    int ingroup = 0;
    char *default_dirlist = NULL;
    char shortopts[OPTION_COUNT * 3 + 2];
    struct option longopts[OPTION_COUNT + 1];
    int last_optind;
  
    /* Starting the short option string with '-' is for programs that
--- 423,438 ----
  
  void
  parse_args (argc, argv)
!      unsigned argc;
       char **argv;
  {
!   unsigned i;
!   int is, il, irl;
    int ingroup = 0;
    char *default_dirlist = NULL;
    char shortopts[OPTION_COUNT * 3 + 2];
    struct option longopts[OPTION_COUNT + 1];
+   struct option really_longopts[OPTION_COUNT + 1];
    int last_optind;
  
    /* Starting the short option string with '-' is for programs that
*************** parse_args (argc, argv)
*** 430,435 ****
--- 442,448 ----
    shortopts[0] = '-';
    is = 1;
    il = 0;
+   irl = 0;
    for (i = 0; i < OPTION_COUNT; i++)
      {
        if (ld_options[i].shortopt != '\0')
*************** parse_args (argc, argv)
*** 450,461 ****
  	}
        if (ld_options[i].opt.name != NULL)
  	{
! 	  longopts[il] = ld_options[i].opt;
! 	  ++il;
  	}
      }
    shortopts[is] = '\0';
    longopts[il].name = NULL;
  
    /* The -G option is ambiguous on different platforms.  Sometimes it
       specifies the largest data size to put into the small data
--- 463,483 ----
  	}
        if (ld_options[i].opt.name != NULL)
  	{
! 	  if (ld_options[i].control == EXACTLY_TWO_DASHES)
! 	    {
! 	      really_longopts[irl] = ld_options[i].opt;
! 	      ++irl;
! 	    }
! 	  else
! 	    {
! 	      longopts[il] = ld_options[i].opt;
! 	      ++il;
! 	    }
  	}
      }
    shortopts[is] = '\0';
    longopts[il].name = NULL;
+   really_longopts[irl].name = NULL;
  
    /* The -G option is ambiguous on different platforms.  Sometimes it
       specifies the largest data size to put into the small data
*************** parse_args (argc, argv)
*** 522,527 ****
--- 544,551 ----
        /* getopt_long_only is like getopt_long, but '-' as well as '--'
  	 can indicate a long option.  */
        optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
+       if (optc == -1)
+ 	optc = getopt_long (argc, argv, shortopts, really_longopts, &longind);
  
        if (optc == -1)
  	break;
*************** set_section_start (sect, valstr)
*** 1137,1143 ****
  static void
  help ()
  {
!   int i;
    const char **targets, **pp;
  
    printf (_("Usage: %s [options] file...\n"), program_name);
--- 1161,1167 ----
  static void
  help ()
  {
!   unsigned i;
    const char **targets, **pp;
  
    printf (_("Usage: %s [options] file...\n"), program_name);
*************** help ()
*** 1149,1155 ****
  	{
  	  boolean comma;
  	  int len;
! 	  int j;
  
  	  printf ("  ");
  
--- 1173,1179 ----
  	{
  	  boolean comma;
  	  int len;
! 	  unsigned j;
  
  	  printf ("  ");
  
*************** help ()
*** 1186,1198 ****
  	      if (ld_options[j].opt.name != NULL
  		  && ld_options[j].control != NO_HELP)
  		{
  		  printf ("%s-%s%s",
  			  comma ? ", " : "",
! 			  ld_options[j].control == TWO_DASHES ? "-" : "",
  			  ld_options[j].opt.name);
  		  len += ((comma ? 2 : 0)
  			  + 1
! 			  + (ld_options[j].control == TWO_DASHES ? 1 : 0)
  			  + strlen (ld_options[j].opt.name));
  		  if (ld_options[j].arg != NULL)
  		    {
--- 1210,1226 ----
  	      if (ld_options[j].opt.name != NULL
  		  && ld_options[j].control != NO_HELP)
  		{
+ 		  int two_dashes =
+ 		    (ld_options[j].control == TWO_DASHES
+ 		     || ld_options[j].control == EXACTLY_TWO_DASHES);
+ 		  
  		  printf ("%s-%s%s",
  			  comma ? ", " : "",
! 			  two_dashes ? "-" : "",
  			  ld_options[j].opt.name);
  		  len += ((comma ? 2 : 0)
  			  + 1
! 			  + (two_dashes ? 1 : 0)
  			  + strlen (ld_options[j].opt.name));
  		  if (ld_options[j].arg != NULL)
  		    {
Index: ldlex.h
===================================================================
RCS file: /cvs/src//src/ld/ldlex.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 ldlex.h
*** ldlex.h	1999/05/03 07:29:06	1.1.1.1
--- ldlex.h	2000/12/28 01:59:27
*************** extern void lex_unput PARAMS ((int));
*** 57,62 ****
  #ifndef yywrap
  extern int yywrap PARAMS ((void));
  #endif
! extern void parse_args PARAMS ((int, char **));
  
  #endif
--- 57,62 ----
  #ifndef yywrap
  extern int yywrap PARAMS ((void));
  #endif
! extern void parse_args PARAMS ((unsigned, char **));
  
  #endif

Index: ld.texinfo
===================================================================
RCS file: /cvs/src//src/ld/ld.texinfo,v
retrieving revision 1.30
diff -p -r1.30 ld.texinfo
*** ld.texinfo	2000/12/26 20:55:29	1.30
--- ld.texinfo	2000/12/28 01:59:27
*************** whitespace, or be given as separate argu
*** 219,231 ****
  option that requires them.
  
  For options whose names are multiple letters, either one dash or two can
! precede the option name; for example, @samp{-oformat} and
! @samp{--oformat} are equivalent.  Arguments to multiple-letter options
! must either be separated from the option name by an equals sign, or be
! given as separate arguments immediately following the option that
! requires them.  For example, @samp{--oformat srec} and
! @samp{--oformat=srec} are equivalent.  Unique abbreviations of the names
! of multiple-letter options are accepted.
  
  Note - if the linker is being invoked indirectly, via a compiler driver
  (eg @samp{gcc}) then all the linker command line options should be
--- 219,238 ----
  option that requires them.
  
  For options whose names are multiple letters, either one dash or two can
! precede the option name; for example, @samp{-trace-symbol} and
! @samp{--trace-symbol} are equivalent.  Note - there is one exception to
! this rule.  Multiple letter options that start with a lower case 'o' can
! only be preceeded by two dashes.  This is to reduce confusion with the
! @samp{-o} option.  So for example @samp{-omagic} sets the output file
! name to @samp{magic} whereas @samp{--omagic} sets the NMAGIC flag on the
! output.
! 
! Arguments to multiple-letter options must either be separated from the
! option name by an equals sign, or be given as separate arguments
! immediately following the option that requires them.  For example,
! @samp{--trace-symbol foo} and @samp{--trace-symbol=foo} are equivalent.
! Unique abbreviations of the names of multiple-letter options are
! accepted.
  
  Note - if the linker is being invoked indirectly, via a compiler driver
  (eg @samp{gcc}) then all the linker command line options should be

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]