I will explain my process for parsing complex c-style declarations. I hope you find this helpful.
C-style parsing can be considered as parsing from right to left, starting with an identifier and limited by brackets. So we start with the proto_type
// vvvvvvvvvv------------------- void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
As we see, moving directly from proto_type, we immediately see the function call and some parameters, so it's easy. proto_type is a function that takes long int and char* parameters.
// v void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
Here we get into the first bounding parentheses, so we need to go back to find the next token that is here:
// v---------------------------- void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
So now we know that it returns a pointer to something. Now we need to look right again to find out that due to bounding parentheses again
// v--------------------------------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
Since we found another function call statement, the pointer returned by it should be a pointer to a function that accepts const char* and unsigned short int .
Finally, we have reached yet another bounding parenthesis, so go back to find the return value of this function pointer.
//vvvv----------------------------------------------------------------------v void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
The function pointer returns void * as the return value.
So, to return to English: proto_type takes long int and char* parameters as parameters and returns a pointer to a function that takes const char* and unsigned short int parameters as parameters and returns void* .