Re: C structure analyzer ("Reflection" in C?)

Dibyendu Majumdar <dibyendu@mazumdar.demon.co.uk>
30 Jul 1999 22:44:15 -0400

          From comp.compilers

Related articles
C structure analyzer ("Reflection" in C?) phollingsworth@sbsintl.com (1999-07-19)
Re: C structure analyzer ("Reflection" in C?) jsgray@acm.org.nospam (Jan Gray) (1999-07-20)
Re: C structure analyzer ("Reflection" in C?) pmai@acm.org (1999-07-21)
Re: C structure analyzer ("Reflection" in C?) kst@cts.com (Keith Thompson) (1999-07-23)
Re: C structure analyzer ("Reflection" in C?) jerry.pendergraft@endocardial.com (Jerry Pendergraft) (1999-07-28)
Re: C structure analyzer ("Reflection" in C?) norbert@dune.gia.rwth-aachen.de (Norbert Berzen) (1999-07-30)
Re: C structure analyzer ("Reflection" in C?) kst@cts.com (Keith Thompson) (1999-07-30)
Re: C structure analyzer ("Reflection" in C?) dibyendu@mazumdar.demon.co.uk (Dibyendu Majumdar) (1999-07-30)
Re: C structure analyzer ("Reflection" in C?) denne@aps.rwth-aachen.de (Volker Denneberg) (1999-07-30)
Re: C structure analyzer ("Reflection" in C?) atrn@zeta.org.au (1999-08-01)
| List of all articles for this month |

From: Dibyendu Majumdar <dibyendu@mazumdar.demon.co.uk>
Newsgroups: comp.compilers
Date: 30 Jul 1999 22:44:15 -0400
Organization: Compilers Central
References: 99-07-063
Keywords: C, tools

phollingsworth@sbsintl.com wrote:


> Does anybody know of a tool that I could use that converts the C
> structure definitions into some other source file that has each data
> member name, byte offset, size etc so that I could make a program to
> dynamically compose these "structures"?


Hello.


I am not sure if this will help ...


I used the parser in the UPS C Interpreter to generate the following:


union example size=136 offset=0 {
        struct person size=136 offset=0 {
                (array[10] of char) name size=10 offset=0
                (array[20] of char) surname size=20 offset=10
                (int) age size=4 offset=32
                (double) salary size=8 offset=36
                struct address size=87 offset=44 {
                        (array[30] of char) city size=30 offset=0
                        (array[30] of char) state size=30 offset=30
                        (array[7] of char) postcode size=7 offset=60
                        (array[20] of char) country size=20 offset=67
                }
                (pointer to struct person) next size=4 offset=132
        }
        struct address size=87 offset=0 {
                (array[30] of char) city size=30 offset=0
                (array[30] of char) state size=30 offset=30
                (array[7] of char) postcode size=7 offset=60
                (array[20] of char) country size=20 offset=67
        }
        (double) d size=8 offset=0
        (char) c size=1 offset=0
        (int) i size=4 offset=0
}
struct person size=136 offset=0 {
        (array[10] of char) name size=10 offset=0
        (array[20] of char) surname size=20 offset=10
        (int) age size=4 offset=32
        (double) salary size=8 offset=36
        struct address size=87 offset=44 {
                (array[30] of char) city size=30 offset=0
                (array[30] of char) state size=30 offset=30
                (array[7] of char) postcode size=7 offset=60
                (array[20] of char) country size=20 offset=67
        }
        (pointer to struct person) next size=4 offset=132
}
struct address size=87 offset=0 {
        (array[30] of char) city size=30 offset=0
        (array[30] of char) state size=30 offset=30
        (array[7] of char) postcode size=7 offset=60
        (array[20] of char) country size=20 offset=67
}


from the file example7.data containing:


struct address {
                char city[30];
                char state[30];
                char postcode[7];
                char country[20];
};


struct person {
                char name[10];
                char surname[20];
                int age;
                double salary;
                struct address addr;
                struct person *next;
};


union example {
                struct person p;
                struct address a;
                double d;
                char c;
                int i;
};


void dummy() {}


The code that does this looks like:


/* example7.c */
/* author: Dibyendu Majumdar */
/* created: 29 July 1999 */


/* This program illustrates how the UPS C Interpreter's parser can be
  * used as a "reflection" mechanism.
  * Run this as:
  * example7 example7.data
  */


#include "Cinterpreter.h"


void
for_each_global_aggr_type(
                Cinterpreter_t *ci,
                void (*funcptr)(aggr_or_enum_def_t*,int,int))
{
                parse_res_t *pres = (parse_res_t *) ci->ci_parse_id;
                block_t *block = pres->pr_block;
                aggr_or_enum_def_t *ae = block->bl_aggr_or_enum_defs;


                for (; ae != NULL; ae = ae->ae_next) {
                                funcptr(ae, 0, 0);
                }
}


void dumptype(aggr_or_enum_def_t *ae, int offset, int level)
{
                var_t *var;
                if ((ae->ae_type->ty_code != TY_STRUCT
                        && ae->ae_type->ty_code != TY_UNION)
                        || ae->ae_is_complete == AE_INCOMPLETE) {
                                fprintf(stderr, "Aggregate type %s is not a struct or
union\n"
                                                "or is incompletely defined\n",
                                                ae->ae_tag);
                                return;
                }
                fprintf(stdout, "%*s%s %s size=%d offset=%d {\n", level, "",
                                (ae->ae_type->ty_code == TY_STRUCT ? "struct" : "union"),
                                ae->ae_tag, ae->ae_size, offset);
                for (var = ae->ae_aggr_members; var != NULL; var = var->va_next) {


                                if (var->va_type->ty_code == TY_STRUCT) {
                                                dumptype(var->va_type->ty_aggr_or_enum,
                                                                var->va_addr, level+4);
                                }
                                else {
                                                char *str;
                                                str = ci_type_to_english(var->va_type, FALSE);
                                                fprintf(stdout, " %*s(%s) %s size=%d
offset=%d\n",
                                                                level, "", str, var->va_name,
                                                                var->va_type->ty_size, var->va_addr);
                                                free(str);
                                }
                }
                fprintf(stdout, "%*s}\n", level, "");
}


int main(int argc, char *argv[])
{
                Cinterpreter_t ci;


                if ( argc != 2 ) {
                                fprintf(stderr, "usage: example7 <file>\n");
                                exit(1);
                }


                if ( ci_create_interpreter_from_file(&ci, argv[1], NULL,
                                                NULL) ) {
                                for_each_global_aggr_type(&ci, dumptype);
                                ci_destroy_interpreter(&ci);
                }


                return 0;
}


The UPS C Interpreter can be downloaded from
http://www.mazumdar.demon.co.uk/ups3.tar.gz .
This is my private version - it incorporates the ups-3.34-beta4 from the
official UPS website
http://www.concerto.demon.co.uk/UPS.


The example above can be found in the sub-directory
interpreter/tutorial/example7.c (in my version only).


Please note that the ups-3.33 C Interpreter will not work in
stand-alone mode - you need either the ups-3.34-beta4 or my version
which has some additional bug fixes.


I built the UPS C Interpreter on SuSE Linux 6.1 (Kernel 2.2.7). It
appears to me that you are probably looking for a Windows tool. I
think the UPS C Interpreter can be built on Windows using the Win32
GNU C compiler from Cygnus (which has a UNIX emulation layer).


I shall post an article on UPS C Interpreter.


Regards


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.