As I myself am very curious about answers to your first question unfortunately I am not able to give you any good advice here.
To at least give you an answer to your second question: This is the somewhat semi-automatic way I use to manually add missing or adjust changed declarations in out of sync header files.
use the compiler with warnings enabled (!) to spot missing / changed declarations:
Adjust declarations
After changing the signature of a function definition gcc
will throw an error like the following one:
error: conflicting types for ‘....’
note: previous declaration of ‘....’ was here
Fixing this one is relatively easy as both a reference to the definition and the corresponding declaration are already given in the error message.
As I am an emacs
user I can’t tell you the way this is done in vi
, but I am quite sure there is an equally simple way to automatically jump to this spots.
All that has to be done is:
-
jump to location one copy the line
-
jump to location two replace old line with the copy and add a trailing
;
Missing declarations
If on the other a new function was added without adding it’s prototype to the corresponding header file gcc
will throw something like:
warning: implicit declaration of function ...
Fixing this one a tag table comes in handy. Again I don’t know for sure how this is handled in vi
, but I am quite sure there is some way to quickly jump to the function definition given by its name in the compiler warning as well.
Workflow here looks like this:
-
jump to function ….’s definition, copy line
-
switch to header file, paste line and add a trailing
;
While this method is anything but elegant it has turned out to be working for those cases in which I forgot to adjust the header to keep it in sync with the source file, which can be done with a few keystrokes.
A broken Example
To demonstrate its application by example here a minmal program that needs it’s headers to be fixed:
/* main.c */
#include "add.h"
int main (int argc, char *argv[]) {
int a=0, b=0;
add (a, b);
sub (a, b);
return 0;
}
Both functions add
and sub
are defined in add.c
shown below:
/* add.c */
#include "add.h"
int add (int a, int b) {
return a + b;
}
int sub (int a, int b) {
return a - b;
}
The culprit add.h
shows both a signature mismatch of the function add
and a missing declaration of the function sub
:
/* add.h */
long add (long a, long b);
Trying to compile will result in:
gcc -Wall main.c add.c
main.c: In function ‘main’:
main.c:7: warning: implicit declaration of function ‘sub’
add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here
Fixing the example
Missing declarations
The first problem:
main.c:7: warning: implicit declaration of function ‘sub’
Is due to the fact that a declaration of sub
is missing in add.h
Finding the right signature:
- C-x` (next-error) will jump to the location of the error
- M-. (gtags-find-tag) will prompt for the tag to lookup
- RET will jump to the definition of
sub
as the symbol at point is the default - M-z{ (zap-to-char) C-y (yank) to copy the signature
Up to here all steps could have also be done automatically by a keyboard macro as no intervention was needed. The next part will have to be done by hand:
- open the “correct” header file
- and navigate to the spot where the declaration should be entered
As the choice of “correct” header file and “correct” location most probably is a matter of taste in contrast to the steps taken so far I don’t think there’s much automation possible here.
Finally the last step is to paste the copied signature:
- C-yM-y paste the copied signature
- DEL; to replace
{
with;
Adjusting declarations
Next the mismatch between add
s declaration and definition has to be fixed.
add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here
To copy the new signature from the definition:
- C-x` (next-error) will jump to the location of the definition
- M-z{ (zap-to-char) C-y (yank) to copy the signature
To replace the declaration:
- C-x` (next-error) will jump to the location of the declaration
- M-z; (zap-to-char) to delete the old declaration
- C-yM-y now paste the copied signature
- DEL; to replace
{
with;
And back again
Since two buffers have been poped:
- M-2M-x burry-buffer should go back to buffer that was visited before
Summary
As you can see while not a too time consuming process constantly jumping back and forth to fix missing or wrong declarations using this approach is still a rather tedious task I only use it to fix up declarations that I mistyped or completely missed in the first run.
Manually placing the “correct” declarations into the header still is the main approach that I take.
As laying out the API prior to implementing it might not be the worst idea IMHO this strategy shouldn’t be a choice too bad.