public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Re: Proposal: convert function definitions to prototyped form
@ 2000-06-02  8:40 David Taylor
  2000-06-02 12:10 ` Kevin Buettner
  0 siblings, 1 reply; 57+ messages in thread
From: David Taylor @ 2000-06-02  8:40 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb

    Date: Fri, 2 Jun 2000 00:50:19 -0700
    From: Kevin Buettner <kevinb@cygnus.com>
[...]
	2) ``protoize'' fails to convert functions disabled by ifdefs for
	   the given platform.  OTOH, on some other platform(s), these
	   functions might not be disabled and would be converted.  E.g,
	   in breakpoint.c, on my GNU/Linux/x86 machine, protoize failed
	   to convert create_longjmp_breakpoint() which is protected by an
	   "#ifdef GET_LONGJMP_TARGET".

With any solution, either you're going to have to check the results or
you're going to have to hand convert some of the stuff.  It's a
tradeoff.  From what you say below, your script also requires some
later hand conversions.

Does your script produce substantially less that needs to be hand
converted?

	3) ``protoize'' screws up on PTR types.  E.g, in breakpoint.c, it
	   converted

		static int
		cover_target_enable_exception_callback (arg)
		     PTR arg;

	   to

		static int
		cover_target_enable_exception_callback (__builtin_va_list arg)

I consider this to be a more serious problem than the other complaints
you have.

	4) ``protoize'' does not reformat long argument lists.  The lists
	   end up entirely contained on one line.

So... adopt the same solution for it that you chose to adopt for your
script -- run indent on the output!

    For more information on protoize, see the "Running protoize" page:

	http://gcc.gnu.org/onlinedocs/gcc_2.html#SEC48

    and the "Caveats of using protoize" page:

	http://gcc.gnu.org/onlinedocs/gcc_7.html#SEC135

I've used protoize before with good results.  It was a fairly
substantial project, though not as big as gdb.

    Two of my goals in creating the scripts for the PARAMS purging
    activities was that the scripts should be 1) easy to invoke and 2)
    require no hand editing of the output when done.  I.e, you shouldn't
    have to edit any of the files that these scripts touch in order to fix

I trust that "3)" is:

    "be conservative; not convert something if it can't be sure
    of getting it right".

I'd much rather hand convert more of the code than have it make a
subtle but incorrect change.

    errors so that you can build again.  OTOH, the script may leave
    certain portions of the file alone that could possibly have be
    converted had the script been a little smarter.  The things that the
    script fails to convert *will* have to be fixed later on (in order to
    complete the cleanup activity), either by another script, or by hand. 
    For the PARAMS purging activity, I have spent a fair amount of time
    examining the diffs to make sure that this is indeed the case.  (And
    I intend to do the same for the activity in this proposal.)

Good.

    The reason that it is so important to avoid any hand edits is that we
    want people who have local repositories or checked out source trees to
    be able to run these conversion scripts against them so that merges
    will be less painful.  (Even easy.)

Agreed.

    With that said, keeping in mind the problems I noted above, I conclude
    that ``protoize'' is not the appropriate tool for us to use to convert
    function definitions in the gdb sources to their prototyped form.

I only consider 3) -- screwing up on PTR types -- to be serious; the
others seem minor enough.
[...]

    Finally, I should note that I've done a test build on GNU/Linux/x86
    and had no build problems, nor did I see any regressions when I ran
    the testsuite.

    The fix-decls script is below.  I'd be interested in finding out if
    anyone else has a favorite script for doing this sort of thing.  Other
    comments welcome too.

I'd be tempted to do a build before running your script; stash away the
object files; run the script; do another build; compare the object
files...

I consider the lack of (prototyped) function declarations to be more
serious "problem" than the use of old style function definitions in
old code.  I'd like to see:

. declarations near the top of every file (i.e., before the first
  function definition) for every static function in the file.

. a declaration in an included header file for every non static
  function definition and for every non static function used.

. changes to the default configuration to "encourage" developers to
  include the above declarations.

^ permalink raw reply	[flat|nested] 57+ messages in thread
* Re: gdb doesn't work very well with dynamic linked binaries
@ 2000-09-07  1:55 James Cownie
  2000-09-07  3:09 ` Mark Kettenis
  0 siblings, 1 reply; 57+ messages in thread
From: James Cownie @ 2000-09-07  1:55 UTC (permalink / raw)
  To: gdb

Mark Kettenis wrote :-
  I'm not sure whether the debug registers are
  per-thread or per-VM-space in Linux.  I'll probably need to look into
  the kernel source.

To save you the time, they are per-thread, just like all the 
other process' registers.

They are conceptually saved and restored on process scheduling
events (which for linuxthreads is the same thing as thread 
scheduling events, since linuxthreads _are_ processes as far as
the scheduler is concerned). 

The bug I mentioned previously is exactly that they're getting
cleared by the kernel and then not getting restored on return
to user space, leaving them wrong until the next reschedule :-(

-- 
-- Jim
James Cownie
jcownie@etnus.com
Etnus, Inc.
Phone +44 117 9071438

^ permalink raw reply	[flat|nested] 57+ messages in thread
* Re: Proposal: convert function definitions to prototyped form
@ 2000-06-02 13:11 David Taylor
  0 siblings, 0 replies; 57+ messages in thread
From: David Taylor @ 2000-06-02 13:11 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb

    Date: Fri, 2 Jun 2000 12:10:42 -0700
    From: Kevin Buettner <kevinb@cygnus.com>

    On Jun 2, 11:39am, David Taylor wrote:

    >       3) ``protoize'' screws up on PTR types.  E.g, in breakpoint.c, it
    >          converted
    > 
    >               static int
    >               cover_target_enable_exception_callback (arg)
    >                    PTR arg;
    > 
    >          to
    > 
    >               static int
    >               cover_target_enable_exception_callback (__builtin_va_list arg)
    > 
    > I consider this to be a more serious problem than the other complaints
    > you have.

    I think the setup issue is important too.  (I don't know if it's more
    serious though.)  As I mentioned in my first point (which is no longer
    quoted), you have to do a configure in the source directory above gdb

Sorry, I didn't consider it relevant to what I was replying to.

    in order to to properly run protoize or else it complains that it
    can't find certain header files.  Also, you need to make sure that the
    bfd header files are generated before you start.  None of these
    problems are insurmountable, but to do things safely with protoize,
    and in order to avoid polluting your sources with files that belong in
    a build tree, it would be necessary for a script using protoize to
    make a complete copy of the source tree somewhere else in order to do
    the work.

I don't consider the setup issue to be a big issue.  It requires some
time, but it doesn't require much human time.  Configure in the source
tree, then build.  Setup done.

During the commit phase, you don't commit anything that is new -- you
only commit files that existed prior to doing the configure.  No
separate tree needed.

    >       4) ``protoize'' does not reformat long argument lists.  The lists
    >          end up entirely contained on one line.
    > 
    > So... adopt the same solution for it that you chose to adopt for your
    > script -- run indent on the output!

    Granted.  A suitably imaginative script could identify just the lines
    that protoize touched and reformat those.  I don't think we want to
    run indent on entire files however, at least not for this activity.

Since Stan previously ran indent on all of the files, re-running it
*should* produce no change for stuff that hasn't changed.  Should
produce no change.  I'm not saying it won't.  If it changes its own
output when presented with it as input, I would consider that a bug.

    > I've used protoize before with good results.  It was a fairly
    > substantial project, though not as big as gdb.

    Okay.  Out of curiousity, did the project in question have a large
    number of active developers?  (This doesn't necessarily matter, but
    I think it's probably easier to manage this kind of thing when only
    a handful of developers are affected.)

It was at a former company.  There were a small number of active
developers all within the company.  The total project was around
200-250K lines of code.  There was a great deal less use of #if within
the sources than there is in GDB...

[...]
    I don't disagree, but I think that adding prototypes for everything
    should be a separate activity.  The question is whether it should
    occur before the activity covered by my proposal.  And if it should
    occur before, once again, we'll need to find a way to help automate
    the process because if we attempt to do it incrementally by hand
    over a period of time, it is likely that it'll never get done.

I agree that it should be a separate activity.

I think that your script is a good thing.  And due to the amount of
hand editing that appears to be necessary with protoize vs the amount
that appears to be necessary with your script, I think we should use
your script.

Ultimately, though, since you're doing the work, you get to select the
tool.  So long as it is fairly reliable and reasonably quick (quick in
terms of *your time*, not in terms of *elapsed time*), it doesn't
ultimately matter to me what tool you use.  (Which is not to say that
I am not interested in knowing what tool you use -- I am interested.)

Like I said, I think your script is a good thing.  And I look forward
to you using it to protoize the bulk of the GDB sources.

    Kevin

David

^ permalink raw reply	[flat|nested] 57+ messages in thread
* Proposal: convert function definitions to prototyped form
@ 2000-06-02  0:50 Kevin Buettner
  2000-06-02  2:42 ` Andrew Cagney
                   ` (3 more replies)
  0 siblings, 4 replies; 57+ messages in thread
From: Kevin Buettner @ 2000-06-02  0:50 UTC (permalink / raw)
  To: gdb

As many of you know, I'm in the midst of purging the use of ``PARAMS''
in prototyped function declarations from the gdb sources.  After this
activity is concluded, I'd like to begin converting function
definitions whose parameters are declared using the traditional C
style to the ISO C prototyped form.  I.e, I'd like to convert
functions of the form

    int
    foo (a, b, c)
         int a;
         char *b;
         int *c;
    {
      ...
    }

to

    int foo (int a, char *b, int *c)
    {
      ...
    }

To this end, I've been working on a script to automate most of this
conversion.  I've appended a work-in-progress version to the end of
this message and will discuss it in some detail further below.

But first...  it's been pointed out to me that the ``protoize''
program is supposed to do the same thing.  I gave ``protoize'' a whirl
and noticed the following problems:

    1) A substantial amount of initial setup is involved.  Only in
       the simplest cases could you just feed a list of files to
       work on to protoize and expect it to work okay.  In particular,
       for gdb, I found it necessary to do a configure *in the source
       directory* so that xm.h, tm.h, and nm.h are set up.  I also
       found it necessary to build in bfd so that certain header
       files are created.

       The reason all of this is necessary is because protoize invokes
       gcc to learn about the program.  As a consequence, it is also
       important to know the set of -I switches that one normally feeds
       to gcc to do a build.

    2) ``protoize'' fails to convert functions disabled by ifdefs for
       the given platform.  OTOH, on some other platform(s), these
       functions might not be disabled and would be converted.  E.g,
       in breakpoint.c, on my GNU/Linux/x86 machine, protoize failed
       to convert create_longjmp_breakpoint() which is protected by an
       "#ifdef GET_LONGJMP_TARGET".

    3) ``protoize'' screws up on PTR types.  E.g, in breakpoint.c, it
       converted

            static int
            cover_target_enable_exception_callback (arg)
                 PTR arg;

       to

            static int
            cover_target_enable_exception_callback (__builtin_va_list arg)

    4) ``protoize'' does not reformat long argument lists.  The lists
       end up entirely contained on one line.

For more information on protoize, see the "Running protoize" page:

    http://gcc.gnu.org/onlinedocs/gcc_2.html#SEC48

and the "Caveats of using protoize" page:

    http://gcc.gnu.org/onlinedocs/gcc_7.html#SEC135

Two of my goals in creating the scripts for the PARAMS purging
activities was that the scripts should be 1) easy to invoke and 2)
require no hand editing of the output when done.  I.e, you shouldn't
have to edit any of the files that these scripts touch in order to fix
errors so that you can build again.  OTOH, the script may leave
certain portions of the file alone that could possibly have be
converted had the script been a little smarter.  The things that the
script fails to convert *will* have to be fixed later on (in order to
complete the cleanup activity), either by another script, or by hand. 
For the PARAMS purging activity, I have spent a fair amount of time
examining the diffs to make sure that this is indeed the case.  (And
I intend to do the same for the activity in this proposal.)

The reason that it is so important to avoid any hand edits is that we
want people who have local repositories or checked out source trees to
be able to run these conversion scripts against them so that merges
will be less painful.  (Even easy.)

With that said, keeping in mind the problems I noted above, I conclude
that ``protoize'' is not the appropriate tool for us to use to convert
function definitions in the gdb sources to their prototyped form.

Now, I'll tell you about the fix-decls script (see below).

The fix-decls script is run via "fix-decls <dirname>" where <dirname>
is the name of the directory to (recursively) fix.  It only touches
the .c files, with the exception of gnu-regex.c and the testsuite
files.  After it converts a traditional C style declaration to a
prototyped one, it invokes GNU indent (on the function declaration
only) to make sure that our indentation standards are still adhered
to.  There is no gratuitous reformatting of any other code.

Here are a list of things that it won't handle (at the moment,
anyway):

    - declarations with comments in them
    - function pointers
    - array declarations
    - malformed declarations (e.g, look at m88k_skip_prologue in m88k-tdep.c)

Functions with traditional C declarations with any of the above in
them will be left alone.  (And need to be converted by hand at some
point.)  But this isn't so bad.  When I ran the script over the gdb
sources, it converted 5,204 function definitions.  After throwing
out gnu-regex.c (which needs to track glibc), all of the stuff in
the testsuite, and everything in tui (which has ifdefs around each
and every function declaration), there are only 143 cases left to
examine by hand.  I've sampled these and many of them are unhandled
due to having comments following a parameter's type declaration.
If I could figure out what to do about comments, we'd have even
fewer cases to fix up by hand.

Here are some of the more interesting cases that it does handle:

Missing int in declaration (i960-tdep.c):

 CORE_ADDR
-frame_args_address (fi, must_be_correct)
-     struct frame_info *fi;
+frame_args_address (struct frame_info *fi, int must_be_correct)
 {

Comma separated parameter lists (remote-mm.c):

 static void
-init_target_mm (tstart, tend, dstart, dend, entry, ms_size, rs_size, arg_start)
-     ADDR32 tstart, tend, dstart, dend, entry;
-     INT32 ms_size, rs_size;
-     ADDR32 arg_start;
+init_target_mm (ADDR32 tstart, ADDR32 tend, ADDR32 dstart, ADDR32 dend,
+		ADDR32 entry, INT32 ms_size, INT32 rs_size, ADDR32 arg_start)
 {

Comma separated list with differing number of stars on the parameter
names (sparc-tdep.c):

 static branch_type
-isbranch (instruction, addr, target)
-     long instruction;
-     CORE_ADDR addr, *target;
+isbranch (long instruction, CORE_ADDR addr, CORE_ADDR * target)
 {

And another one (command.c):

 struct cmd_list_element *
-lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
-     char **text;
-     struct cmd_list_element *clist, **result_list;
-     int ignore_help_classes;
+lookup_cmd_1 (char **text, struct cmd_list_element *clist,
+	      struct cmd_list_element **result_list, int ignore_help_classes)
 {

Out of order comma separated parameter list - note positions of ``from''
and ``to'' (gdbserver/remote-utils.c):

 void
-decode_M_packet (from, mem_addr_ptr, len_ptr, to)
-     char *from, *to;
-     CORE_ADDR *mem_addr_ptr;
-     unsigned int *len_ptr;
+decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr, unsigned int *len_ptr,
+		 char *to)
 {

Finally, I should note that I've done a test build on GNU/Linux/x86
and had no build problems, nor did I see any regressions when I ran
the testsuite.

The fix-decls script is below.  I'd be interested in finding out if
anyone else has a favorite script for doing this sort of thing.  Other
comments welcome too.

--- fix-decls ---
#!/usr/bin/perl -w

use File::Find;
use FileHandle;
use IPC::Open3;
use English;

my ($root) = @ARGV;

if (!defined($root)) {
    die "Usage: $0 root\n";
}

@ARGV = ();

find(
    sub { 
	if ($_ eq 'testsuite') {
	    $File::Find::prune = 1;
	} elsif (-f && -T && /\.c$/ && $_ ne "gnu-regex.c") {
	    push @ARGV, $File::Find::name;
	}
    },
    $root
);

#$INPLACE_EDIT = '.bak';
$INPLACE_EDIT = '';
undef $/;			# slurp entire files

while (<>) {
    s/
	^			# line start
	( 
	  \w+			# function name
	)
	(
	  \s*			# spaces
	  \(			# left paren
	  \s*			# spaces
	)
	(
	  (?:\w+\s*,\s*)*	# 1 thru N-1 parameter names
	  \w+			# last parameter name
	)
	(
	  \s*			# spaces
	  \)			# right paren
	)
	(
	  (?:
	    [^;{}()]+;		# trad C parameter decl
	  )*
	)
	(
	  \s*			# spaces
	)
	(?=^{)			# lookahead to make sure we see a
				# right curly brace at the beginning
				# of the line
    /
	fix_decl($1, $2, $3, $4, $5, $6);
    /smgex;

    s/
	^			# line start
	( 
	  \w+			# function name
	)
	\s*			# spaces
	\(			# left paren
	\s*			# spaces
	\)			# right paren
	(?=\s*^{)		# lookahead to make sure we see a
				# right curly brace at the beginning
				# of the line
     /$1 (void)/smgx;

    print;
}

sub fix_decl {
    my ($funcname, $lparen, $params, $rparen, $decls, $spaces) = @_;
    my %h = ();
    my ($param, $decl);

    # Define $bailstr to be the original function declaration.  We
    # return it when we see something which doesn't make sense.
    my $bailstr = $funcname . $lparen . $params . $rparen . $decls . $spaces;

    if ($funcname =~ /^(do|while|if)$/) {
	# 'if', 'do', and 'while' are not function names
	# find_overload_match() in valops.c contains an if statement
	# which is confused as a function if we don't have this test.
	return $bailstr;
    }

    foreach $param (split /\s*,\s*/, $params) {
	if (defined $h{$param} || $param eq 'void') {
	    # Bail; either param has already been encountered or
	    # it's void in which case the decl in question is already
	    # ISO C.
	    return $bailstr;
	}
	$h{$param} = "int $param";	# Default
    }

    $decls =~ s/\s*;\Z//;		# remove final semicolon
    			
    foreach $decl (split /\s*;\s*/, $decls) {
	my ($type, $dparams) = 
	    $decl =~ /^				# beginning of string
	              (.*?)			# type
	              (				# dparams...
		        (?:
			  \**			#  stars
			  \s*			#  spaces
			  \w+			#  identifier
			  \s*			#  spaces
			  ,			#  comma
			  \s*			#  spaces
			)*			# any number of the above
			\**			#  stars
			\s*			#  spaces
			\w+			#  identifier
		      )
		      $				# end of string
		     /sx;
	return $bailstr			if !defined $type || !defined $dparams;
	$type =~ s/\A\s+//;		# nuke leading spaces
	$type =~ s/\s+\Z//;		# nuke trailing spaces
	return $bailstr			if $type eq '';
					# Bail if no type
	foreach $param (split /\s*,\s*/, $dparams) {

	    my ($stars, $stripped_param) = 
		$param =~ /(\**)\s*(\w+)/;

	    if (!defined($stripped_param) || !defined $h{$stripped_param}) {
		# Either we couldn't find the parameter or else
		# the parameter wasn't found in the parameter list
		return $bailstr;
	    }
	    $h{$stripped_param} = "$type $param";
	}
    }

    my $newparams = join(', ', map { $h{$_} } split(/\s*,\s*/, $params));

    my $newdecl = reindent("$funcname ($newparams)\n{\n}\n");
    $newdecl =~ s/{\n}//;
    return $newdecl;
}


sub reindent {
    my ($decl, $line_length) = @_;
    $line_length = 80		unless defined $line_length;
    my ($rfh, $wfh, $efh) = (FileHandle->new, FileHandle->new,
					      FileHandle->new);
    my $pid = open3($wfh, $rfh, $efh, "indent -l$line_length");
    $rfh->input_record_separator(undef);
    $efh->input_record_separator(undef);
    $wfh->print($decl);
    $wfh->close();
    my $replacement = <$rfh>;
    $rfh->close();
    my $errstr = <$efh>;
    $efh->close();
    waitpid $pid, 0;
    $replacement =~ s#\n$##;
    if ($errstr ne "") {
	print STDERR "Check $ARGV...\n$errstr\nInput:$decl\nOutput:$replacement\n\n"
    }
    $replacement;
}
--- end fix-decls ---

^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2001-03-21 15:59 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-06-02  8:40 Proposal: convert function definitions to prototyped form David Taylor
2000-06-02 12:10 ` Kevin Buettner
2000-06-03  3:58   ` Eli Zaretskii
     [not found]     ` <eliz@delorie.com>
2000-06-03 10:50       ` Kevin Buettner
2000-06-03 11:37         ` Eli Zaretskii
2000-06-03 18:18         ` Andrew Cagney
2000-06-03 15:42       ` Kevin Buettner
2001-02-16  0:45       ` [RFC] Unified watchpoints for x86 platforms Kevin Buettner
  -- strict thread matches above, loose matches on Subject: below --
2000-09-07  1:55 gdb doesn't work very well with dynamic linked binaries James Cownie
2000-09-07  3:09 ` Mark Kettenis
2000-09-07  8:02   ` Eli Zaretskii
2000-09-08  8:30     ` Mark Kettenis
2001-02-10  7:34       ` [RFC] Unified watchpoints for x86 platforms Eli Zaretskii
2001-02-10 10:19         ` H . J . Lu
2001-02-10 11:28           ` Eli Zaretskii
2001-02-15  3:48         ` Eli Zaretskii
2001-02-15  8:17           ` Mark Kettenis
2001-02-15  9:32             ` Eli Zaretskii
2001-02-15 10:33               ` Mark Kettenis
2001-02-15 13:26                 ` Eli Zaretskii
2001-02-15 10:41             ` Kevin Buettner
2001-02-15 13:26               ` Eli Zaretskii
2001-02-15 14:46                 ` J.T. Conklin
2001-02-15 16:11                   ` Kevin Buettner
2001-02-15 23:29                     ` Eli Zaretskii
2001-02-24 10:14                     ` Eli Zaretskii
2001-02-27  3:28                       ` Mark Kettenis
2001-02-27 10:57                         ` Eli Zaretskii
2001-03-21 15:59                         ` [RFA] " Eli Zaretskii
2001-02-15 23:30                   ` [RFC] " Eli Zaretskii
2001-02-16 10:52                     ` J.T. Conklin
2001-02-16  0:00                   ` Mark Kettenis
2001-02-15  9:08           ` H . J . Lu
2000-09-09 14:39   ` gdb doesn't work very well with dynamic linked binaries Peter.Schauer
2000-06-02 13:11 Proposal: convert function definitions to prototyped form David Taylor
2000-06-02  0:50 Kevin Buettner
2000-06-02  2:42 ` Andrew Cagney
2000-06-03  0:13   ` Kevin Buettner
2000-06-03  0:21   ` Kevin Buettner
2000-06-03  4:52     ` Andrew Cagney
2000-06-02  5:26 ` Mark Kettenis
2000-06-02  8:16   ` Kevin Buettner
2000-06-02 10:44     ` J.T. Conklin
2000-06-03  5:17       ` Andrew Cagney
2000-06-05 11:05         ` J.T. Conklin
2000-06-12 16:30       ` Eric Bachalo
2000-06-12 17:29         ` Andrew Cagney
2000-06-12 18:03           ` Daniel Berlin
2000-06-12 18:15             ` Stan Shebs
2000-06-12 18:23               ` Daniel Berlin
2000-06-12 19:16                 ` Anatoly Vorobey
2000-06-12 19:42                   ` Daniel Berlin
2000-06-12 18:55         ` Kevin Buettner
2000-06-13  3:34         ` Eli Zaretskii
2000-06-03  4:48 ` Andrew Cagney
2000-06-12 18:10 ` Andrew Cagney
2000-06-12 19:48   ` Kevin Buettner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).