Link to home
Start Free TrialLog in
Avatar of itsai
itsai

asked on

generic access of structure fields

say, i have two structures which are public defined like this

struct exp1
{
INT32 a;
char b[17];
short c;
}

struct exp2
{
INT32 aa;
INT32 bb;
char cc[12];
short dd;
}

My question is there a way to get the count of the structure elemants of a particular structure and.....
given the structure name can i print the name of elements inside it.

thanks


Avatar of jclayton
jclayton

Not that I know of, the only thing you could do is to describe the structures using a meta-data method.  E.g, something like this:

struct metainfo
{
      const char *name;
      int offset;
};

struct exp1
{
      INT32 a;
        char b[17];
        short c;
};

#define exp1value ((exp1 *)(void *)0)
metainfo exp1_metainfo[] =
{
      {"a", offsetof(exp1value->a)},
      {"b", offsetof(exp1value->b)},
      {"C", offsetof(exp1value->c)}
};

Which *probably* is not the answer you are looking for....

Of course, RTTI won't help here either which is the only other run time thing I know of in C++.
Avatar of itsai

ASKER

thanks, clayton. i did arrive at this point and i am actually looking for a possible solution.

anyway, thanks for the same

itsai, can you explain what this is needed for?
Avatar of itsai

ASKER

neitod,

well i am intended to develop an application wherein say 'n' structures are defined in a header file. My appl is takes the struct name as input. The application is supposed to be intelligent enough to search for the struct name in the header file and then get the relevant fields and put them in the database for further analysis. I hope this satisfies you...... else you are free to get back

And these are not structures that are defined within this program.  i.e. this program was not necessarily compiled with these structures.  The program is supposed to analyize source code and not necessarily the source code used to generate the program.  Right?   (If so I'll get back to you with some ideas.)
i still didn't understand what do you exectlly want

you got a header file with many structures that contains some data

and you define a global parameters from the structures???<like a global:metainfo s1;>

and what do you mean by the struct name???maybe you mean type???<metainfo>

answer my questions and i"ll try to help you



as you may see in many of the structures used in win32, are being changed uppon newer releases and changes.

The way you would solve this problem is by having a tiny version/type integer , at the first element of the structure.

check the version and cast it to the belonging struct.

example in win32net api is
netinfo1_t,netinfo2_t,netinfo3_t ....



hope this helps
if you you mean type you can use the func typeid or dymnic_cast

tell me if that what you mean and i"ll tell you more about it
>> you can use the func typeid or dymnic_cast
Not to determine symbolic name and other info about the data members for a class/structure.  

Besides its seems like he wants some sort of C++ souce code parser.  he says "search for the struct name in the header file and then get the relevant fields"
Would it be acceptable to search through the symbol names generated by the debugger in some way?

>> is there a way to get the count of the structure elemants of a particular
>> structure and given the structure name can i print the name of elements
>> inside it.

The short answer is no.

If the source is available, you can parse it (as Todd suggested).
If some debugging info is available, you can check it (as jclayton suggested).

Otherwise, you're SOL (and RTTI won't help).
for nietod i see that you like my answer and comment very much
so always leave me comments

i don't know what name he is talking about and maybe it's a data field in the struct that called name or he talks about the struct name as prototype
and he said search becouse he have to find from all the prototypes the one he need

so sorry but i don't know what he ment
>>  i don't know what he ment
I don't think anyone knows.  

to me it sounds like he just wants to look at source code.
Avatar of itsai

ASKER

yes, the question is defiantely trivial.Well that is the inner details for the appl i am developing. All your doubts do make sense. Yes, when your header file gets included in your project, the code <structname>.(will give all the fields inside it). My problem is not at this level, i am thinking beyond.

say i have got a scenario, wherein, when i install my application then it makes an entry of all the fields of all structures into a database dynamically. Hope this clears my original question
Avatar of itsai

ASKER

For the matter of fact, one more live example is the drop down list which appears with the structure elements, once we say <structname>.

how does the drop down list sense the elements inside the structure. Also, it is generic to all structures
>> Hope this clears my original question
Not at all

Is the program supposed to get information about structures that are compiled into that program.  i.e. structures that appear in the source code when the program is compiled.  

Or is the program supposed to get information about structures that appear in source code that was not used to create the program.  i.e source code for other programs.
>> drop down list sense the elements inside the structure
The approach it is going to depend on how the program learns about the structure and that is going to depend on the question I asked.
Avatar of itsai

ASKER

yeps nietod, i think you are slowly coming to the point.....yes....your second sentence is my reply..

"Or is the program supposed to get information about structures that appear in source code that was not used to create the program.  i.e source code for other programs."









Okay, what you want to do is to write a C/C++ parser program to look at the source code and "extract" information so that you can place it in a database.  Right?

the bad news is that, in general C/C++ parsing is increadibly difficult.  Even professionally written compilers often don't get it 100% right.  So I really don't think that writting code to completely parse the source code is going to be an option for you.  However, one option is to use a library that parses C/C++ code.  There are some commercial libraries available to do this (ther might alo be some free ones) these libraries are written to help programs create utilities that analyize code, like to create documentation or to cross reference function calls, that sort of thing.  A library like this might make this pretty easy to do.  

A 2nd option is to not parse the code completey, but only partially.  (a popular choice.)  Do to this you write a parser that can handle only very limited cases and ignores the rest of the code.  The parser will look for specific things in the code that tells it when it can start parsing.  For example, it might look for the word "struct" at the start of the line and it might then start parsing until it comes to an ending brace "}".  Rr it might look for a special keyword that is embedded in a comment.  That sort of thing.  This sort of approach tends to be less advanced.  it might not be able to handle nested structure for example, or might be fooled by syntaxes that are more complex than what it was intended to handle.  (Like the "struct" keyword used in a type definition might "turn it on" at the wrong time.)  So this means you hust have to be careful about how the parser is written, turned on, and turned of and make sure your code is written consistently to aid the parser.  However this sort of approach is quit reasonable to do.

A 3rd option is the reverse.  Don't parse the source code--create it.  store the information about the structs in a database or perhaps a simple format text file.  Then write a program that takes this information and uses it to create a .h file that has the proper C++ syntax structure definitions.  The advantage of this approach is that you don't have to worry about the parser getting messed up by unexpected syntax that mistakenly turns it on or of.  
Avatar of itsai

ASKER

Yes, what i am writing now is the parser code itself. My approach is similar to your third option. But, still i was looking for a better option if possible. I would wait and see for some more time before accepting your comments finally.
Hi itsai ,
 How about trying this code . This will solve ur first question of getting the count of data members for given struct name .Even though I have hard coded the struct name, U can modify that to get the struct name . Also instead os using "__FILE__" U can use any header file U want which has all the structs.

 I want u to try to get the name of the fields inside the struct , if U want me to give solution I can give .

Note : one condition here in my program is that I need to have blank space on the either side of the " ; " .
 But U can chage this code to check if a semicolon exists as a part of a string and increment the count. Run the following code .


#include <iostream>
#include <fstream>
#include <string>
using namespace std;

struct pr
{
      int a ;
      int b ;
      int c ;
};

void main()
{
      int count =0;
       ifstream file (__FILE__);
       string str1;
       while (file >> str1)
       {
             if (str1=="pr" )
             {
              file >> str1;
          while (str1 != "}")
              {
               file >> str1;
                  if (str1 == ";")
                  {
                        count++;
                  }
              }
             }
             
       }
       cout << count << endl;            
 }
      
      

 
 
The output of the above code will be 3 and thats the count of the members in the struct pr .
Avatar of itsai

ASKER

hi mprao,

i appreaciate your efforts, but this again kind of parsing which neitod has suggested. This is what i am doing infact, if you read my comments earlier then the things might be clear.

ok, lets go one step ahead, say, yo have the header file with structure definations included in your projects, can you get me the count....now

yes we can

In the samp.h

struct pr
{
      int a ;
      int b ;
} ;


In ur cpp file

#include <iostream>
#include <fstream>
#include <string>
#include "samp.h"
using namespace std;
void main()
{
      int count =0;
       ifstream file ("samp.h");
       string str1;
       while (file >> str1)
       {
             if (str1=="pr" )
             {
              file >> str1;
          while (str1 != "}")
              {
               file >> str1;
                  if (str1 == ";")
                  {
                        count++;
                  }
              }
             }
             
       }
       cout << count << endl;            
 }
      
This above program will print 2 thats the number os members in the struct pr.

Few more mofication has to be done in the above program .
 First U parse thru the current file using __FILE__ and look for "#include" then use file >> str to get to the next string of the file , do this until U get the correct header file U have all the structs come next to #include .Now pass parse thru this file in the str using ifstream file (str); .
 Rest I think U can do . If U want more clarification . I will write the sample code and give u .
 i hope U understood what I am trying to say . If not come back .

Why don't you try PCCTS (aka ANTLR)?
It is a parser generator tool that comes with samples to parse C++ files.
Hi itsai ,
 I have posted the whole code which handles the header files as well .

In the samp.h

struct pr
{
int a ;
int b ;
} ;



In the cpp program code the following

#include <iostream>
#include <fstream>
#include <string>
#include "samp.h"
using namespace std;
void main()
{
      string str;
      int count =0;
      ifstream file ( __FILE__ );
      while (file >> str )
      {
            if (str == "#include")
            {
                  file >> str;
                  if (str == "\"samp.h\"")
                  {
                        cout << str << " ";
                ifstream file1 ("samp.h");
                   string str1;
                while (file1 >> str1)
                    {
                          cout << str1<<endl;
                    if (str1=="pr" )
                        {
                     file1 >> str1;
                 while (str1 != "}")
                         {
                     file1 >> str1;
                      if (str1 == ";")
                            count++;
                          }
                        }
                    }
                  }
            }
      }
       cout << count << endl;            
 }
      
      

the above programs will solve ur problem I suppose .


Simple parsers like that will work if you restrict yourself to simple cases.  Most likely that is too much of a simplification.  It will fail on nested structures, member functons, class-local typedefs etc.  That may or may not be a problem.

I guess there is stil a 4th option, the one I use, which makes it suprising I didn't mention it.

I write my class definitions in the source code inside a comment using a vaugely C++-like  pseudo-code.  My parser finds these "psuedo-definitions" and ouputs propper  C++ definitions in a header file.  (It does a lot of the menial labor, like finding all the non-inline member functions and creating a declaration for them in the "real" class declaration.   Plus other "routine" work.)

So my class "definitions" might look like

/*

CLASS DerivedClassName : BaseClassName
{
    DataMember(int,Count,Public); // Some sort of count.
    DataMember(float,Size,Private); // Some sort of size.
    typedef char *BufPtrTyp; // non-standard code, just copied blindly
                        // by the parser.
}

This approach allows the parser to be pretty simple because it is looking for information with a prety well defined format.  However the structures/classes can have more complex formats--so long as the complex information does not have to be understood by the parser.  The parser just copies lines it doesn't understand and processes the lines it does understand.
ASKER CERTIFIED SOLUTION
Avatar of pitonyak
pitonyak

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial