I have been given a medium-sized but complex C project (about 200,000 lines in total) which contains around 100 .h files and nearly as many .c files.
Many of the .h files correspond to equivalent .c files, but there is one .h file in particular, let's call it project_common.h, that #includes many of the other .h files as well as containing about 2000 lines of mostly struct and enum definitions etc. Many of the structs are heavily nested so that their order very much matters.
The structure of the file is roughly:
#include guard
#include <assert.h>
#include <stdint.h>
/* etc */
#include "project_aaa.h"
#include "project_bbb.h"
/* Then another 30 or so lines like this. These are in alphabetical
order and a certain amount of effort has been made that they can be
included in any order. */
/* Then about 2000 lines of struct, enums, function definitions etc. */
I have been tasked with moving most or all of the 2000 lines and either creating new .h files for them or pasting them into one of the existing .h files. One rule is that each header must be able to be included independently of all others. In other words, each header must not need other headers to be included before it. After some effort, I've quickly realised that, even as a senior software engineer of 25+ years' experience, this is not an easy task at all because of the very complex and hierarchical nature of the struct definitions.
My problems in particular are:
- It's bad practice to include all those headers in project_common.h, and defeats the point of splitting it all up.
- It's really REALLY hard to split all this up in such a way that the resulting headers can be included from a given C file in any combination.
So what I am asking is, are there any tools out there that can help with refactoring all the .h files into a more optimal configuration, and/or is there a recognised method that's better than trial and error?
So far I've tried moving struct definitions around, but progress is very slow and tedious, and although I have nearly halved the size of project_common.h, the new headers I have created only work if they are included in the right order.