Using the C API

## Getting Started with the C API

### Traversing the Understand Database

Using the C API to access the Understand database is generally done in the following way:

- Open Understand database
- Retrieve List of All Entities
- Filter the List of Entities
- Retrieve Desired Info about each Entity from the Filtered List
  Entity Info includes:
  - names, types, kinds, etc.
  - metric values
  - reference information
  - - retrieve file/line/column information about a reference
  - - "follow" a reference to produce a "tree"
- Close database

### API Include file

To use the Understand API, you will need to include udb.h in any source files that call an Understand API function. Reference the .h file with the appropriate relative path from your project source area. For example:

     #include "../sti/src/udb/udb.h"

### Understand Licensing

In order for your application to use the Understand API functions, an Understand license must first be found. You have several options in specifying where the API should look to find the required Understand license file:

Call udbSetLicense() to specify the actual path to your Understand license.
Set the environment variable $STILICENSE
Or
the API will use the license found in the location specified by $STIHOME/conf/license

Note that the license will not be `checked out' for use until the Understand database is opened. Be sure to always check the return status of udbDbOpen() as it will fail if all licenses are already in use or if a license is not found.

     udbSetLicense ("c:\\Program Files\\STI\\conf\\license");

### Opening and Closing the Database

As previously noted, use udbDbOpen() to open the Understand database for reading. This action also consumes an Understand license. Refer to udbDbOpen for detailed information and return statuses.

     status = udbDbOpen("test.udc");

Then close the database when done:

     udbDbClose();

### Get a List of Entities

Once the database is open, retrieve all the entities that are of interest to you.

First get the list of all entities:

     udbListEntity( &allEnts, &allEntsSize);

Then filter the list to include only what you are interested in. In this example, the list is filtered to include only functions:

     udbListEntityFilter (allEnts, udbKindParse("function"),
                                      &funcEnts, &funcEntsSize);

When done with the entity lists, be sure to free them:

     udbListEntityFree(allEnts);
     udbListEntityFree(funcEnts);

### Get Information About an Entity

Once you have an entity (or group of entities), you can obtain all kinds of information about it. The following example prints both the short and long names of each function.

     for (i=0; i<funcEntsSize; i++)   {
     	 printf ("Shortname: %s, Longname:%s\n",
     	 	 udbEntityNameShort(funcEnts[i]),
     	 	 udbEntityNameLong(funcEnts[i]) );
     }

### Get Reference Information for an Entity

In addition to getting general entity and metrics information, you can also get information about the references to or from an entity. Again, you obtain a list of all references for a particular entity, and then filter the list to include only those types of references that you are interested in.

The following example reports where an entity is defined showing the parent entity in which it is defined, as well as the file, line, and column location where the definition occurs.

First, get all the references for the entity, then filter the reference list to include only those where the the entity is defined , of which there should only be one occurrence.

     udbListReference(entity, &refs, NULL);
     udbListReferenceFilter(refs,
                      udbKindParse("definedin,declaredin"),
                      NULL,
                      0, &defs,  NULL);

Once you have the desired list of references, you can do whatever you want with them. As always, remember to free the Reference Lists when done.

     if (defs != NULL && defs[0] != 0)  {
        printf ("     %s (%s at line:%d col:%d)\n\n",
                	 udbEntityNameShort(udbReferenceEntity(defs[0])),
                	 udbEntityNameShort(udbReferenceFile(defs[0])),
                	 udbReferenceLine(defs[0]),
                	 udbReferenceColumn(defs[0]) );
        udbListReferenceFree(defs);
      }
     udbListReferenceFree(refs);

### About Library Support

Several API functions utilize libraries. Currently these functions only apply to Understand for Ada databases. In Understand for Ada, there will always be a library named "standard" and this is the only Ada library supported at this time.

Any entity that is not in the "standard" library, is considered to be in the NULL library. To filter on entities that are not in the standard library, specify "~standard". For example:

     udbLibraryFilterEntity(entities,
                            "~standard",
                            &entities, &size);

will return a list of all entities not in the standard library. (for Ada only).

Future versions of Understand will support libraries.

### Compiling & Linking with the API library

Compile the application as you normally would, adding dependencies for the API header file and library to the Makefile.

The API libraries are located in the $STIHOME/bin/<architecture> directory.

On Windows, link with either udp_api.lib (for dynamic linking) or udb_api.obj (for static linking).

On Unix/Linux, link with either udb_api.so or udb_api.sl (for dynamic linking) or udb_api.a (for static linking).

Define the system libraries needed. Your application may need additional libraries defined. The following system libraries are needed for use with the static library of the API:

     WIN32_LIBS= \
       wsock32.lib \
       advapi32.lib \
       libc.lib \
       user32.lib \
       netapi32.lib

Following is a simple Makefile to compile and link a sample.c file with the dynamic API library on Windows - it assumes the default installation location of Understand (c:\program files\sti):

     STI        = "c:\program files\sti"
     UDB_SRC    = $(STI)\src\udb
     UDB_LIB    = $(STI)\bin\pc-win95
     WIN32_LIBS = wsock32.lib advapi32.lib libc.lib user32.lib netapi32.lib
     sample: sample.exe sample_dll.exe
     sample.exe: sample.obj
     	 link /nologo /out:$@ sample.obj $(UDB_LIB)udb_api.obj $(WIN32_LIBS)
     sample_dll.exe: sample.obj
     	 link /nologo /out:$@ sample.obj $(UDB_LIB)udb_api.lib $(WIN32_LIBS)
     sample.obj: sample.c
     	 cl /nologo /c /I$(UDB_SRC) sample.c

The example Makefile assumes Microsoft Visual C++ as the compiler, but the principals shown should work with any compiler.

Scientific Toolworks, Inc. http://www.scitools.com Voice: (802) 763-2995 Fax: (802) 763-3066 support@scitools.com sales@scitools.com