Get struct definition

I have many headers with huge amount of structures in them, typical one looks like this:

$ cat a.h
struct Rec1 {
        int     f1;
        int     f2;
};
 struct Rec2 {
        char    r1;
        char    r2;
};
 struct Rec3 {
        int     f1;
        float   k1;
        float   k2;
};

To quickly look at a given definition I do this:

$ sed -n "/Rec2/,/^$/p" a.h
struct Rec2 {
        char    r1;
        char    r2;
};

I use an alias for the command and it is easy and quick, works in all systems where I need it.

Now I inherited headers with this type of definition:

$ cat b.h
typedef struct {
        int     f1;
        int     f2;
}Rec1;
typedef struct {
        char    r1;
        char    r2;
}Rec2;
typedef struct {
        int     f1;
        float   k1;
        float   k2;
}Rec3;

so my simple sed does not work anymore. Any idea how to deal with this format?

I thought of awk:

awk 'BEGIN{ n = 1; }
{
        if($0 ~ "typedef") {
                n=1;
        }
        arr[n]=$0;
        n++;
        if($0 ~ "Rec2") {
                for(i=1;i<=n;i++)
                        print arr;
        }
}' b.h

but I don't like it - too complex for a simple alias I can carry with me in different environments I deal with. And I am not sure awk is available everywhere. Any bash/sed based ideas?

This sed might help:

sed -n ' /Rec2/ {H;g;p;d}; /typedef/ {h;d}; H' file
typedef struct {
        char    r1;
        char    r2;
}Rec2;
1 Like

Well, I am not doing it right somehow:

 
 $ sed -n '/Rec2/ {H;g;p;d}; /typedef/ {h;d}; H' b.h 
sed: Command garbled: /Rec2/ {H;g;p;d}; /typedef/ {h;d}; H
 

RudiC, can you check my syntax, please?

Worked on my linux; on (Free)BSD I tried

sed -n '/Rec2/ {H;g;p;d; }; /typedef/ {h;d; }; H' file

Watch the ; } in both cases; it needs both. Some sed s need a newline char in front of the } . PLay around with it...

1 Like

If you are on Linux, another potential solution:

$ tac b.h | sed -n '/Rec2/,/typedef struct/p' | tac
typedef struct {
        char    r1;
        char    r2;
}Rec2;

I love tac, but it is not available on my Unix systems. Thanks for the idea!

To search all header files in the current directory in either of your two specified formats, the following will work with either ed or ex with any shell that accepts basic Bourne shell syntax (including any POSIX conforming shell such as bash and ksh ):

#!/bin/ksh
for i in *.h
do	ed -s "$i" <<-EOF
		g/^[ 	]*struct[ 	][ 	]*$1[ 	]*{/ .,/^};/p
		g/^}[ 	]*$1[ 	]*;/ ?typedef[ 	][ 	]*struct[ 	]*{?,.p
	EOF
done

Note that there is a single <tab> character before the EOF on the next to the last line. It will not work correctly if this tab is changed to spaces. Note also that in the here-document there is a single <space> character and a single <tab> character between each pair of square brackets ( [ and ] ).

With the sample a.h and b.h headers given in post #1 in this thread, if the above script is saved in a file named tester and it is made executable:

chmod +x tester

then the command:

./tester Rec3

produces the output:

 struct Rec3 {
        int     f1;
        float   k1;
        float   k2;
};
typedef struct {
        int     f1;
        float   k1;
        float   k2;
}Rec3;
2 Likes