Human-readable storage for types (with no pointers)?

  • Thread starter Konstantin Shemyak
  • Start date
K

Konstantin Shemyak

I have a big structure tree. All leaves are scalar values (no pointers).
Present are arrays, structures and unions. I want to be able to store/read
the content of the structure in/from a file, and in a readable format.
This is needed to provide manually constructed test input to a function,
which works with this tree. Number of types is huge, and I want to avoid
hand-coding read/write functions for each type.

Ideally, I'm thinking about code which takes .h file with several
typedef-s and produces C code with functions for reading/writing these
structures. For example, for file "types.h", containing definitions like

typedef {...} TypeA;

I'll get file "ReadWriteTypes.c", containing functions like

TypeA* readTypeA(FILE* fp) {...}
void writeTypeA(TypeA* a, FILE* fp) {...}

And the file content will be, for example, similar to what debuggers
show when asked to print a nested data structure. I repeat that the
leaves contain only scalar values, no pointers.

Any hints how this can be done?
I use GNU tools, so sources of gcc and gdb are at my hands. Still
I am in hope that someone has already done this before...
 
A

Arthur J. O'Dwyer

You can write this as a commandline program, called savestruct

savestruct sourcefile.c/.h typename outputfile

the problem is that C source can get very complex, with nested structures
and long chains of typedefs. For instance, you will have to evoke a C
pre-processor over the source if you want to allow the use of defined types.

s/evoke/invoke/

And what #defined types are you thinking of? FILE? I think it'd be
easier to simply ignore any types you weren't sure of. Alternatively,
you could add an option to compile those into calls to similar I/O
functions:

struct foo {
int i;
struct bar j;
};

would yield the function

int ReadStructFoo(struct foo *, FILE *);

which would contain logic for reading the 'int', plus a call to
the user-defined function ReadStructBar() [which would have to
be generated separately and linked together, most likely]. Then
the function WriteFileStuff()

typedef struct
{
int ft;
FILE *fp;
char *fname;
} FileStuff;

could call WriteFILE() to do its dirty work, and the programmer
would be free to say, "Wait, we can't really save a 'FILE *'.
Let's just make WriteFILE() a no-op, or remove the call completely."

Having reduced the structure to a list of basic types,

This is the part that stymies me. Does anyone have some nice
clean source code for parsing simple C declarations (just
single pointers, arrays, structs; nothing fancy necessary)?
I know 'cdecl' must be out there somewhere, but I believe it
uses lex/yacc, which is just ugly.
you then need some
logic to generate the fprintfs and fscanfs to load and save it. This
shouldn't be too difficult to do.

Yes, this part is fairly easy (if you make some standardizing
assumptions).

A really fancy 'savestruct' would probably serialize whole data
structures (which I think is really what the OP wants) -- flatten
trees, and so on. This is also something that would be handy to
have around.

If anyone writes, or has written, anything along these lines, I'd
*really* like to see it.

Thanks, and HTH,
-Arthur
 
A

Arthur J. O'Dwyer

I have a big structure tree. All leaves are scalar values (no pointers).
Present are arrays, structures and unions. I want to be able to store/read
the content of the structure in/from a file, and in a readable format.
This is needed to provide manually constructed test input to a function,
which works with this tree. Number of types is huge, and I want to avoid
hand-coding read/write functions for each type.

Ideally, I'm thinking about code which takes .h file with several
typedef-s and produces C code with functions for reading/writing these
structures. For example, for file "types.h", containing definitions like

typedef {...} TypeA;

I'll get file "ReadWriteTypes.c", containing functions like

TypeA* readTypeA(FILE* fp) {...}
void writeTypeA(TypeA* a, FILE* fp) {...}


I've started trying to work on this project, but I still haven't
gotten very far. It seems like the sort of thing that would be
easy to do in a half-baked way, but hard to make useful.

Here's what I would really like to see, in perceived order of
difficulty:


* Support for all unsigned integral types.
* Support for all signed integral types.
* Support for arrays of all supported types.
* Support for dynamic arrays, given a "size" member;
e.g.,
struct Packet {
int ndata;
unsigned char *data;
};
Be able to specify various ways of handling
dynamic arrays (images might have both height and
width, and data arrays of size (height*width), e.g).
* Support for dynamically allocated character strings
(that end with '\0').
* Intelligent use of typedef names for the structs,
if they're provided; including pointer typedefs.
* Support for recursive data structures: lists and
trees. Requires some knowledge of how the nodes are
organized, I think.
* Support for arbitrarily complicated types, including
function pointers, unions, and bitfields.


Of course, the idea would be that the generated code run
in any hosted environment, and not assume anything about
the representations or sizes of objects.

As I mentioned before, the hard part for me is the parsing
of the struct definition.

Any pointers or advice are welcome.

-Arthur
 
K

Konstantin Shemyak

I've started trying to work on this project, but I still haven't
gotten very far. It seems like the sort of thing that would be
easy to do in a half-baked way, but hard to make useful.

Here's what I would really like to see, in perceived order of
difficulty:


* Support for all unsigned integral types.
* Support for all signed integral types.
* Support for arrays of all supported types.

This plus structures of all supported types is my current need. I guess,
there is a big jump from this to the rest of what you mention.
* Support for dynamic arrays, given a "size" member;
e.g.,
struct Packet {
int ndata;
unsigned char *data;
};

But how would the syntax parser know that ndata refers to the size
of array data?
* Support for arbitrarily complicated types, including
function pointers, unions, and bitfields.

To my understanding, unions are impossible to fit into this scheme,
because again syntax parser would not know how to treat the union
member. Seems that this is a principal obstacle.

Well, if I get some minimal working code, I'll ring the bell.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top