An IOC database is created on a Unix system via a Database Configuration Tool and stored in a Unix file. EPICS provides two sets of database access routines: Static Database Access and Runtime Database Access. Static database access can be used on Unix or IOC database files. Runtime database requires an initialized IOC databases. Static database access is described in this chapter and runtime database access in the next chapter.
Static database access provides a simplified interface to a database, i.e. much of the complexity is hidden. DBF_MENU
and
DBF_DEVICE
fields are accessed via a common type called DCT_MENU
. A set of routines are provided to simplify access
to link fields. All fields can be accessed as character strings. This interface is called static database access because it can
be used to access an uninitialized as well as an initialized database.
Before accessing database records, the files describing menus, record types, and devices must be read via
dbReadDatabase
or dbReadDatabaseFP
. These routines, which are also used to load record instances, can be
called multiple times.
Database Configuration Tools (DCTs) should manipulate an EPICS database only via the static database access interface.
An IOC database is created on a host system via a database configuration tool and stored in a host file with a file
extension of ``.db
". Three routines (dbReadDatabase
, dbReadDatabaseFP
and dbWriteRecord
) access the
host database file. These routines read/write a database file to/from a memory resident EPICS database. All other access
routines manipulate the memory resident database.
An include file dbStaticLib.h
contains all the definitions needed to use the static database access library. Two
structures (DBBASE
and DBENTRY
) are used to access a database. The fields in these structures should not be accessed
directly. They are used by the static database access library to keep state information for the caller.
Multiple memory resident databases can be accessed simultaneously. The user must provide definitions in the form:
DBBASE *pdbbase;
NOTE: On an IOC pdbbase is a global variable, which is accessable if you include dbAccess.h
A typical declaration for a database entry structure is:
DBENTRY *pdbentry; pdbentry=dbAllocEntry(pdbbase);
Most static access to a database is via a DBENTRY
structure. As many DBENTRYs
as desired can be allocated.
The user should NEVER access the fields of DBENTRY
directly. They are meant to be used by the static database access
library.
Most static access routines accept an argument which contains the address of a DBENTRY
. Each routine uses this structure
to locate the information it needs and gives values to as many fields in this structure as possible. All other fields are set to
NULL
.
Each database field has a type as defined in the next chapter. For static database access a new and simpler set of field types are defined. In addition, at runtime, a database field can be an array. With static database access, however, all fields are scalars. Static database access field types are called DCT field types.
The DCT field types are:
A DCT_STRING
field contains the address of a NULL
terminated string. The field types DCT_INTEGER
and DCT_REAL
are used for numeric fields. A field that has any of these types can be accessed via the dbGetString
, dbPutString
,
dbVerify
, and dbGetRange
routines.
The field type DCT_MENU
has an associated set of strings defining the choices. Routines are available for accessing menu
fields. A menu field can also be accessed via the dbGetString
, dbPutString
, dbVerify
, and dbGetRange
routines.
The field type DCT_MENUFORM
is like DCT_MENU
but in addition the field has an associated link field. The information
for the link field can be entered via a set of form manipulation fields.
DCT_INLINK
(input), DCT_OUTLINK
(output), and DCT_FWDLINK
(forward) specify that the field is a link, which has
an associated set of static access routines described in the next subsection. A field that has any of these types can also be
accessed via the dbGetString
, dbPutString
, dbVerify
, and dbGetRange
routines.
DBBASE *dbAllocBase(void);
This routine allocates and initializes a DBBASE structure. It does not return if it is unable to allocate storage.
dbAllocBase
allocates and initializes a DBBASE structure. Normally an application does not need to call
dbAllocBase
because a call to dbReadDatabase
or dbReadDatabaseFP
automatically calls this routine if
pdbbase
is null. Thus the user only has to supply code like the following:
DBBASE *pdbbase=0; ... status = dbReadDatabase(&pdbbase,"sample.db", "<path>","<macro substitutions>");
The static database access library allows applications to work with multiple databases, each referenced via a different
(DBBASE *) pointer. Such applications may find it necessary to call dbAllocBase
directly.
dbAllocBase
does not return if it is unable to allocate storage.
void dbFreeBase(DBBASE *pdbbase);
dbFreeBase
frees the entire database reference by pdbbase
including the DBBASE structure itself.
DBENTRY *dbAllocEntry(DBBASE *pdbbase); void dbFreeEntry(DBENTRY *pdbentry);
These routines allocate, initialize, and free DBENTRY
structures. The user can allocate and free DBENTRY
structures as
necessary. Each DBENTRY
is, however, tied to a particular database.
dbAllocEntry
and dbFreeEntry
act as a pair, i.e. the user calls dbAllocEntry
to create a new DBENTRY and
calls dbFreeEntry
when done.
void dbInitEntry(DBBASE *pdbbase,DBENTRY *pdbentry); void dbFinishEntry(DBENTRY *pdbentry);
The routines dbInitEntry
and dbFinishEntry
are provided in case the user wants to allocate a DBENTRY
structure
on the stack. Note that the caller MUST call dbFinishEntry
before returning from the routine that calls
dbInitEntry
. An example of how to use these routines is:
int xxx(DBBASE *pdbbase) { DBENTRY dbentry; DBENTRY *pdbentry = &dbentry; ... dbInitEntry(pdbbase,pdbentry); ... dbFinishEntry(pdbentry); }
dbCopyEntry
Contents
DBENTRY *dbCopyEntry(DBENTRY *pdbentry); void dbCopyEntryContents(DBENTRY *pfrom,DBENTRY *pto);
The routine dbCopyEntry
allocates a new entry, via a call to dbAllocEntry
, copies the information from the original
entry, and returns the result. The caller must free the entry, via dbFreeEntry
when finished with the DBENTRY.
The routine dbCopyEntryContents
copies the contents of pfrom to pto. Code should never perform structure copies.
long dbReadDatabase(DBBASE **ppdbbase,const char *filename, char *path, char *substitutions); long dbReadDatabaseFP(DBBASE **ppdbbase,FILE *fp, char *path, char *substitutions); long dbPath(DBBASE *pdbbase,const char *path); long dbAddPath(DBBASE *pdbbase,const char *path);
dbReadDatabase
and dbReadDatabaseFP
both read a file containing database definitions as described in chapter
"Database Definitions". If *ppdbbase
is NULL, dbAllocBase
is automatically invoked and the return address
assigned to *pdbbase
. The only difference between the two routines is that one accepts a file name and the other a
"FILE *". Any combination of these routines can be called multiple times. Each adds definitions with the rules described
in chapter ``Database Definitions".
The routines dbPath
and dbAddPath
specify paths for use by include statements in database definition files. These are
not normally called by user code.
long dbWriteMenu(DBBASE *pdbbase,char *filename,char *menuName); long dbWriteMenuFP(DBBASE *pdbbase,FILE *fp,char *menuName); long dbWriteRecordType(DBBASE *pdbbase,char *filename,char *recordTypeName); long dbWriteRecordTypeFP(DBBASE *pdbbase,FILE *fp,char *recordTypeName); long dbWriteDevice(DBBASE *pdbbase,char *filename); long dbWriteDeviceFP(DBBASE *pdbbase,FILE *fp); long dbWriteDriver(DBBASE *pdbbase,char *filename); long dbWriteDriverFP(DBBASE *pdbbase,FILE *fp); long dbWriteRegistrarFP(DBBASE *pdbbase,FILE *fp); long dbWriteFunctionFP(DBBASE *pdbbase,FILE *fp); long dbWriteVariableFP(DBBASE *pdbbase,FILE *fp); long dbWriteBreaktable(DBBASE *pdbbase,const char *filename); long dbWriteBreaktableFP(DBBASE *pdbbase,FILE *fp);
Each of these routines writes files in the same format accepted by dbReadDatabase
and dbReadDatabaseFP
. Two
versions of each type are provided. The only difference is that one accepts a filename and the other a ``FILE
*". Thus only
one of each type has to be described.
dbWriteMenu
writes the description of the specified menu or, if menuName
is NULL, the descriptions of all menus.
dbWriteRecordType
writes the description of the specified record type or, if recordTypeName
is NULL, the
descriptions of all record types to the named file.
dbWriteDevice
writes the description of all devices to the named file.
dbWriteDriver
writes the description of all drivers to the named file.
dbWriteRegistrarFP
writes the list of all registrars to the given open file (no filename version is provided).
dbWriteFunctionFP
writes the list of all functions to the given open file (no filename version is provided).
dbWriteVariableFP
writes the list of all variables to the given open file (no filename version is provided).
dbWriteBreaktable
writes the definitions of all breakpoint tables to the named file.
long dbWriteRecord(DBBASE *pdbbase,char * file, char *precordTypeName,int level); long dbWriteRecordFP(DBBASE *pdbbase,FILE *fp, char *precordTypeName,int level);
Each of these routines writes files in the same format accepted by dbReadDatabase
and dbReadDatabaseFP
. Two
versions of each type are provided. The only difference is that one accepts a filename and the other a ``FILE
*". Thus only
one of each type has to be described.
dbWriteRecord
writes record instances. If precordTypeName
is NULL, then the record instances for all record
types are written, otherwise only the records for the specified type are written. level
has the following meaning:
int dbGetNRecordTypes(DBENTRY *pdbentry);
This routine returns the number of record types in the database.
long dbFindRecordType(DBENTRY *pdbentry, char *recordTypeName); long dbFirstRecordType(DBENTRY *pdbentry); long dbNextRecordType(DBENTRY *pdbentry);
dbFindRecordType
locates a particular record type. dbFirstRecordType
locates the first, in alphabetical order,
record type. Given that DBENTRY points to a particular record type, dbNextRecordType
locates the next record type.
Each routine returns 0 for success and a non zero status value for failure. A typical code segment using these routines is:
status = dbFirstRecordType(pdbentry); while(!status) { /*Do something*/ status = dbNextRecordType(pdbentry) }
char *dbGetRecordTypeName(DBENTRY *pdbentry);
This routine returns the name of the record type that DBENTRY currently references. This routine should only be called
after a successful call to dbFindRecordType
, dbFirstRecordType
, or dbNextRecordType
. It returns NULL if
DBENTRY does not point to a record description.
The routines described in this section all assume that DBENTRY references a record type, i.e. that
dbFindRecordType
, dbFirstRecordType
, or dbNextRecordType
has returned success or that a record instance
has been successfully located.
int dbGetNFields(DBENTRY *pdbentry,int dctonly);
Returns the number of fields for the record instance that DBENTRY currently references.
long dbFirstField(DBENTRY *pdbentry,int dctonly); long dbNextField(DBENTRY *pdbentry,int dctonly);
These routines are used to locate fields. If any of these routines returns success, then DBENTRY references that field description.
int dbGetFieldType(DBENTRY *pdbentry);
This routine returns the integer value for a DCT field type, see Section14.2.3 on page198, for a description of the field types.
char *dbGetFieldName(DBENTRY *pdbentry);
This routine returns the name of the field that DBENTRY currently references. It returns NULL if DBENTRY does not point to a field.
char *dbGetDefault(DBENTRY *pdbentry);
This routine returns the default value for the field that DBENTRY currently references. It returns NULL if DBENTRY does not point to a field or if the default value is NULL.
char *dbGetPrompt(DBENTRY *pdbentry); int dbGetPromptGroup(DBENTRY *pdbentry);
The dbGetPrompt
routine returns the character string prompt value, which describes the field. dbGetPromptGroup
returns the field group as described in guigroup.h.
A record attribute is a psuedo-field definition attached to a record type. If a attribute value is assigned to a psuedo field name then all record instances of that record type appear to have that field with the defined value. All attribute fields are DCT_STRING fields.
Two field attributes are automatically created: RTYP and VERS. RTYP is set equal to ,the record type name. VERS is initialized to the value ``none specified" but can be changed by record support.
Attribute
long dbPutRecordAttribute(DBENTRY *pdbentry, const char *name, const char *value)
This creates or modifies the attribute name on the record type referenced by pdbentry to value. Attribute names should be valid C identifiers, starting with a letter or underscore followed by any number of alphanumeric or underscore characters.
Attribute
long dbGetRecordAttribute(DBENTRY *pdbentry, const char *name);
Looks up the attribute name for the record type referenced by pdbentry and sets the the field pointer in pdbentry to refer to
this string if it exists. The routine dbGetString
can be used subsequently to read the current attribute value.
With the exception of dbFindRecord, each of the routines described in this section require that DBENTRY references a
valid record type, i.e. that dbFindRecordType
, dbFirstRecordType
, or dbNextRecordType
has been called
and returned success.
int dbGetNRecords(DBENTRY *pdbentry);
Returns the total number of record instances and aliases for the record type that DBENTRY currently references.
int dbGetNAliases(DBENTRY *pdbentry)
Returns the number of record aliases for the record type that DBENTRY currently references.
long dbFindRecord(DBENTRY *pdbentry,char *precordName); long dbFirstRecord(DBENTRY *pdbentry); long dbNextRecord(DBENTRY *pdbentry);
These routines are used to locate record instances and aliases. If any of these routines returns success, then DBENTRY
references a record or a record alias (use dbIsAlias
to distinguish the two). dbFindRecord
may be called without
DBENTRY referencing a valid record type. dbFirstRecord
only works if DBENTRY references a record type. The
dbDumpRecords
example given at the end of this chapter shows how these routines can be used.
dbFindRecord
also calls dbFindField
if the record name includes a field name, i.e. it ends in ``.XXX
". The routine
dbFoundField
returns (TRUE
, FALSE
) if the field (was, was not) found. If it was not found, then dbFindField
must
be called before individual fields can be accessed.
char *dbGetRecordName(DBENTRY *pdbentry);
This routine only works properly if called after dbFindRecord
, dbFirstRecord
, or dbNextRecord
has returned
success. If DBENTRY refers to an alias, the name returned is that of the alias, not of the record it refers to.
int dbIsAlias(DBENTRY *pdbentry)
This routine only works properly if called after dbFindRecord
, dbFirstRecord
, or dbNextRecord
has returned
success. If DBENTRY refers to an alias it returns a non-zero value, otherwise it returns zero.
long dbCreateRecord(DBENTRY *pdbentry,char *precordName); long dbCreateAlias(DBENTRY *pdbentry, const char *paliasName); long dbDeleteRecord(DBENTRY *pdbentry); long dbDeleteAliases(DBENTRY *pdbentry); long dbFreeRecords(DBBASE *pdbbase);
dbCreateRecord
, which assumes that DBENTRY
references a valid record type, creates a new record instance and
initializes it as specified by the record description. If it returns success, then DBENTRY
references the record just created.
dbCreateAlias
assumes that DBENTRY references a particular record instance and creates an alias for that record. If
it returns success, then DBENTRY references the alias just created. dbDeleteRecord
deletes either a single alias, or a
single record instance and all the aliases that refer to it. dbDeleteAliases
finds and deletes all aliases that refer to the
current record. dbFreeRecords
deletes all record instances.
long dbCopyRecord(DBENTRY *pdbentry, char *newRecordName int overWriteOK)
This routine copies the record instance currently referenced by DBENTRY
(it fails if DBENTRY references an alias). Thus
it creates a new record with the name newRecordName
that is of the same type as the original record and copies the
original records field values to the new record. If newRecordName
already exists and overWriteOK
is true, then the
original newRecordName
is deleted and recreated. If dbCopyRecord
completes successfully, DBENTRY references
the new record.
long dbRenameRecord(DBENTRY *pdbentry, char *newname)
This routine renames the record instance currently referenced by DBENTRY
(it fails if DBENTRY references an alias). If
dbRenameRecord
completes successfully, DBENTRY references the renamed record.
These routines are for use by graphical configuration tools.
long dbVisibleRecord(DBENTRY *pdbentry); long dbInvisibleRecord(DBENTRY *pdbentry); int dbIsVisibleRecord(DBENTRY *pdbentry);
dbVisibleRecord
sets a record to be visible. dbInvisibleRecord
sets a record invisible.
dbIsVisibleRecord
returns TRUE if a record is visible and FALSE otherwise.
long dbFindField(DBENTRY *pdbentry,char *pfieldName); int dbFoundField(DBENTRY *pdbentry);
Given that a record instance has been located, dbFindField
finds the specified field. If it returns success, then
DBENTRY
references that field. dbFoundField
returns (FALSE
, TRUE
) if (no field instance is currently available, a
field instance is available).
char *dbGetString(DBENTRY *pdbentry); long dbPutString(DBENTRY *pdbentry,char *pstring); char *dbVerify(DBENTRY *pdbentry,char *pstring); char *dbGetRange(DBENTRY *pdbentry); int dbIsDefaultValue(DBENTRY *pdbentry);
These routines are used to get or change field values. They work on all the database field types except DCT_NOACCESS
but should NOT be used to prompt the user for information for DCT_MENU
, DCT_MENUFORM
, or DCT_LINK_xxx
fields.
dbVerify
returns (NULL
, a message) if the string is (valid, invalid). Please note that the strings returned are volatile, i.e.
the next call to any routine that returns a string will overwrite the value returned by a previous call. Thus it is the caller's
responsibility to copy the strings if the value must be kept.
DCT_MENU
, DCT_MENUFORM
and DCT_LINK_xxx
fields can be manipulated via routines described in the following
sections. If, however dbGetString
and dbPutString
are used, they do work correctly. For these field types
dbGetString
and dbPutString
are intended to be used only for creating and restoring versions of a database.
These routines should only be used for DCT_MENU
and DCT_MENUFORM
fields. Thus they should only be called if
dbFindField
, dbFirstField
, or dbNextField
has returned success and the field type is DCT_MENU
or
DCT_MENUFORM
.
int dbGetNMenuChoices(DBENTRY *pdbentry);
This routine returns the number of menu choices for menu.
char **dbGetMenuChoices(DBENTRY *pdbentry);
This routine returns the address of an array of pointers to strings which contain the menu choices.
int dbGetMenuIndex(DBENTRY *pdbentry); long dbPutMenuIndex(DBENTRY *pdbentry,int index); char *dbGetMenuStringFromIndex(DBENTRY *pdbentry,int index); int dbGetMenuIndexFromString(DBENTRY *pdbentry, char *choice);
NOTE: These routines do not work if the current field value contains a macro definition.
dbGetMenuIndex
returns the index of the menu choice for the current field, i.e. it specifies which choice to which the
field is currently set. dbPutMenuIndex
sets the field to the choice specified by the index.
dbGetMenuStringFromIndex
returns the string value for a menu index. If the index value is invalid NULL is
returned. dbGetMenuIndexFromString
returns the index for the given string. If the string is not a valid choice a -1
is returned.
dbMenu *dbFindMenu(DBBASE *pdbbase,char *name);
dbFindMenu
is most useful for runtime use but is a static database access routine. This routine just finds a menu with the
given name.
Links are the most complicated types of fields. A link can be a constant, reference a field in another record, or can refer to
a hardware device. Two additional complications arise for hardware links. The first is that field DTYP
, which is a menu
field, determines if the INP
or OUT
field is a device link. The second is that the information that must be specified for a
device link is bus dependent. In order to shelter database configuration tools from these complications the following is
done for static database access.
DTYP
as a DCT_MENUFORM
field.
DCT_MENUFORM
can be entered via a set of form manipulation
routines associated with the DCT_MENUFORM
field. Thus the link information can be entered via the DTYP
field
rather than the link field.
Each link is one of the following types:
Database configuration tools can change any link between being a constant and a process variable link. Routines are provided to accomplish these tasks.
The routines dbGetString
, dbPutString
, and dbVerify
can be used for link fields but the form routines can be
used to provide a friendlier user interface.
int dbGetNLinks(DBENTRY *pdbentry); long dbGetLinkField(DBENTRY *pdbentry,int index) int dbGetLinkType(DBENTRY *pdbentry);
These are routines for manipulating DCT_xxxLINK
fields. dbGetNLinks
and dbGetLinkField
are used to walk
through all the link fields of a record. dbGetLinkType
returns one of the values: DCT_LINK_CONSTANT
,
DCT_LINK_PV
, DCT_LINK_FORM
, or the value -1 if it is called for an illegal field.
long dbCvtLinkToConstant(DBENTRY *pdbentry); long dbCvtLinkToPvlink(DBENTRY *pdbentry);
These routines should be used for modifying DCT_LINK_CONSTANT
or DCT_LINK_PV
links. They should not be used
for DCT_LINK_FORM
links, which should be processed via the associated DCT_MENUFORM
field described above.
These routines are used with a DCT_MENUFORM
field (a DTYP
field) to manipulate the associated DCT_INLINK
or
DCT_OUTLINK
field. They can also be used on any DCT_INLINK
, DCT_OUTLINK
, or DCT_FWDLINK
field.
int dbAllocForm(DBENTRY *pdbentry) long dbFreeForm(DBENTRY *pdbentry)
dbAllocForm
allocates storage needed to manipulate forms. The return value is the number of elements in the form. If
the current field value contains a macro definition, the number of lines returned is 0.
char **dbGetFormPrompt(DBENTRY *pdbentry) char **dbGetFormValue(DBENTRY *pdbentry) long dbPutForm(DBENTRY *pdbentry, char **value)
dbGetFormPrompt
returns a pointer to an array of pointers to character strings specifying the prompt string.
dbGetFormValue
returns the current values. dbPutForm
, which can use the same array of values returned by
dbGetForm
, sets new values.
char **dbVerifyForm(DBENTRY *pdbentry,char **value)
dbVerifyForm
can be called to verify user input. It returns NULL
if no errors are present. If errors are present, it returns
a pointer to an array of character strings containing error messages. Lines in error have a message and correct lines have a
NULL
string.
char *dbGetRelatedField(DBENTRY *pdbentry)
This routine returns the field name of the related field for a DCT_MENUFORM field. If it is called for any other type of field it returns NULL.
The following is code showing use of these routines:
char **value; char **prompt; char **error; int n; ... n = dbAllocForm(pdbentry); if(n<=0) {<Error>} prompt = dbGetFormPrompt(pdbentry); value = dbGetFormValue(pdbentry); for(i=0; i<n; i++) { printf("%s (%s) : \n",prompt[i],value[i]); /*The follwing accepts input from stdin*/ scanf("%s",value[i]); } error = dbVerifyForm(pdbentry,value); if(error) { for(i=0; i<n; i++) { if(error[i]) printf("Error: %s (%s) %s\n", prompt[i], value[i],error[i]); } }else { dbPutForm(pdbentry,value) } dbFreeForm(pdbentry);
All value strings are MAX_STRING_SIZE
in length.
A set of form calls for a particular DBENTRY
, MUST begin with a call to dbAllocForm
and end with a call to
dbFreeForm
. The values returned by dbGetFormPrompt
, dbGetFormValue
, and dbVerifyForm
are valid only
between the calls to dbAllocForm
and dbFreeForm
.
Information items are stored as a list attached to each individual record instance. All routines listed in this section require that the DBENTRY argument refer to a valid record instance.
long dbFirstInfo(DBENTRY *pdbentry); long dbNextInfo(DBENTRY *pdbentry); long dbFindInfo(DBENTRY *pdbentry,const char *name);
There are two ways to locate info items, by scanning through the list using first/next, or by asking for the item by name.
These routines set pdbentry
to refer to the info item and return 0, or return an error code if no info item is found.
const char * dbGetInfoName(DBENTRY *pdbentry);
Returns the name of the info item referred to by pdbentry
, or a NULL pointer if no item is referred to.
const char * dbGetInfoString(DBENTRY *pdbentry); long dbPutInfoString(DBENTRY *pdbentry,const char *string);
These routines provide access to the currently selected items' string value. When changing the string value using
dbPutInfoSting
, the character string provided will be copied, with additional memory being allocated as necessary.
Users are advised not to make continuously repeated calls to dbPutInfoString
at IOC runtime as this could fragment
the free memory heap. The Put routine returns 0 if Ok or an error code; the Get routine returns NULL on error.
void * dbGetInfoPointer(DBENTRY *pdbentry); long dbPutInfoPointer(DBENTRY *pdbentry, void *pointer);
Each info item includes space to store a single void*
pointer as well as the value string. Applications using the info item
may set this as often as they wish. The Put routine returns 0 if Ok or an error code; the Get routine returns NULL on error.
long dbPutInfo(DBENTRY *pdbentry,const char *name,const char *string); long dbDeleteInfo(DBENTRY *pdbentry);
A new info item can be created by calling dbPutInfo
. If an item by that name already exists its value will be replaced
with the new string, otherwise storage is allocated and the name and value strings copied into it. The function returns 0 on
success, or an error code.
When calling dbDeleteInfo
, the pdbentry must refer to the item to be removed (using dbFindFirst
/dbFindNext
or dbFindInfo
). The function returns 0 on success, or an error code.
const char * dbGetInfo(DBENTRY *pdbentry,const char *name);
It is common to want to look up the value of a named info item in one call, and dbGetInfo
is provided for this purpose.
It returns a NULL pointer if no info item exists with the given name.
brkTable *dbFindBrkTable(DBBASE *pdbbase,char *name)
This routine returns the address of the specified breakpoint table. It is normally used by the runtime breakpoint conversion routines so will not be discussed further.
void dbDumpPath(DBBASE *pdbbase) void dbDumpRecord(DBBASE *pdbbase,char *precordTypeName,int level); void dbDumpMenu(DBBASE *pdbbase,char *menuName); void dbDumpRecordType(DBBASE *pdbbase,char *recordTypeName); void dbDumpField(DBBASE *pdbbase,char *recordTypeName,char *fname); void dbDumpDevice(DBBASE *pdbbase,char *recordTypeName); void dbDumpDriver(DBBASE *pdbbase); void dbDumpRegistrar(DBBASE *pdbbase); void dbDumpFunction(DBBASE *pdbbase); void dbDumpVariable(DBBASE *pdbbase); void dbDumpBreaktable(DBBASE *pdbbase,char *name); void dbPvdDump(DBBASE *pdbbase,int verbose); void dbReportDeviceConfig(DBBASE *pdbbase,FILE *report);
These routines are used to dump information about the database. dbDumpRecord
, dbDumpMenu
, dbDumpDriver
, dbDumpRegistrar
and dbDumpVariable
just call the corresponding dbWritexxxFP
routine specifying stdout for
the file. dbDumpRecordType
, dbDumpField
, and dbDumpDevice
give internal information useful on an ioc.
These commands can be executed via iocsh. Just specify pdbbase as the first argument.
This example is like the dbExpand
utility, except that it doesn't allow path or macro substitution options, It reads a set of
database definition files and writes all definitions to stdout. All include statements appearing in the input files are
expanded.
/* dbExpand.c */ #include <stdlib.h> #include <stddef.h> #include <stdio.h> #include <epicsPrint.h> #include <dbStaticLib.h> DBBASE *pdbbase = NULL; int main(int argc,char **argv) { longstatus; inti; intarg; if(argc<2) { printf("usage: expandInclude file1.db file2.db...\n"); exit(0); } for(i=1; i<argc; i++) { status = dbReadDatabase(&pdbbase,argv[i],NULL,NULL); if(!status) continue; fprintf(stderr,"For input file %s",argv[i]); errMessage(status,"from dbReadDatabase"); } dbWriteMenuFP(pdbbase,stdout,0); dbWriteRecordTypeFP(pdbbase,stdout,0); dbWriteDeviceFP(pdbbase.stdout); dbWriteDriverFP(pdbbase.stdout); dbWriteRecordFP(pdbbase,stdout,0,0); return(0); }
NOTE: This example is similar but not identical to the actual dbDumpRecords
routine.
The following example demonstrates how to use the database access routines. The example shows how to locate each record and display each field.
void dbDumpRecords(DBBASE *pdbbase) { DBENTRY *pdbentry; long status; pdbentry = dbAllocEntry(pdbbase); status = dbFirstRecordType(pdbentry); if(status) {printf("No record descriptions\n");return;} while(!status) { printf("record type: %s",dbGetRecordTypeName(pdbentry)); status = dbFirstRecord(pdbentry); if(status) printf(" No Records\n"); while(!status) { if (dbIsAlias(pdbentry) printf("\n Alias:%s\n",dbGetRecordName(pdbentry)); else { printf("\n Record:%s\n",dbGetRecordName(pdbentry)); status = dbFirstField(pdbentry,TRUE); if(status) printf(" No Fields\n"); while(!status) { printf(" %s: %s",dbGetFieldName(pdbentry), dbGetString(pdbentry)); status=dbNextField(pdbentry,TRUE); } } status = dbNextRecord(pdbentry); } status = dbNextRecordType(pdbentry); } printf("End of all Records\n"); dbFreeEntry(pdbentry); }