432 lines
8.6 KiB
C
432 lines
8.6 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1990 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
mbrqry.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file contains the functions that perform the queries to the
|
||
|
database. These functions are called by the top-level functions
|
||
|
which implement the browser commands (see mbrdlg.c).
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Ramon Juan San Andres (ramonsa) 07-Nov-1990
|
||
|
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#include "mbr.h"
|
||
|
|
||
|
|
||
|
// INST_MATCHES_CRITERIA
|
||
|
//
|
||
|
// This macro is used to find out if an instance matches the
|
||
|
// current MBF criteria.
|
||
|
//
|
||
|
#define INST_MATCHES_CRITERIA(Iinst) FInstFilter(Iinst, BscMbf)
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Static variables reflect the current state of
|
||
|
// Definition/Reference queries.
|
||
|
//
|
||
|
static IREF LastiRef; // Last reference index
|
||
|
static IREF iRefMin, iRefMax; // Current reference index range
|
||
|
|
||
|
static IDEF LastiDef; // Last definition index
|
||
|
static IDEF iDefMin, iDefMax; // Current definition index range
|
||
|
|
||
|
static IINST LastIinst; // Last instance index
|
||
|
static IINST IinstMin, IinstMax; // Current instance index range
|
||
|
|
||
|
static DEFREF LastQueryType; // last query type:
|
||
|
// Q_DEFINITION or
|
||
|
// Q_REFERENCE
|
||
|
|
||
|
static buffer LastSymbol; // Last symbol queried.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/**************************************************************************/
|
||
|
|
||
|
void
|
||
|
pascal
|
||
|
InitDefRef(
|
||
|
IN DEFREF QueryType,
|
||
|
IN char *Symbol
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Initializes the query state, this must be done before querying for
|
||
|
the first definition/reference of a symbol.
|
||
|
|
||
|
After calling this function, the first definition/reference must be
|
||
|
obtained by calling the NextDefRef function.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
QueryType - Type of query (Q_DEFINITION or Q_REFERENCE).
|
||
|
Symbol - Symbol name.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
ISYM Isym;
|
||
|
|
||
|
LastQueryType = QueryType;
|
||
|
strcpy(LastSymbol, Symbol);
|
||
|
|
||
|
Isym = IsymFrLsz(Symbol);
|
||
|
|
||
|
InstRangeOfSym(Isym, &IinstMin, &IinstMax);
|
||
|
|
||
|
LastIinst = IinstMin;
|
||
|
|
||
|
if (QueryType == Q_DEFINITION) {
|
||
|
DefRangeOfInst(LastIinst, &iDefMin, &iDefMax);
|
||
|
LastiDef = iDefMin - 1;
|
||
|
} else {
|
||
|
RefRangeOfInst(LastIinst, &iRefMin, &iRefMax);
|
||
|
LastiRef = iRefMin - 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**************************************************************************/
|
||
|
|
||
|
void
|
||
|
GotoDefRef (
|
||
|
void
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Makes the file containing the current definition/reference the
|
||
|
current file and positions the cursor in the line where the
|
||
|
definition/reference takes place.
|
||
|
|
||
|
The state of the query (current instance and definition/reference
|
||
|
indexes) must be set before calling this function.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
char *pName = NULL;
|
||
|
WORD Line = 0;
|
||
|
PFILE pFile;
|
||
|
char szFullName[MAX_PATH];
|
||
|
|
||
|
|
||
|
szFullName[0] = '\0';
|
||
|
if (LastQueryType == Q_DEFINITION) {
|
||
|
DefInfo(LastiDef, &pName, &Line);
|
||
|
} else {
|
||
|
RefInfo(LastiRef, &pName, &Line);
|
||
|
}
|
||
|
|
||
|
if (BscInUse && pName) {
|
||
|
|
||
|
if (rootpath(pName, szFullName)) {
|
||
|
strcpy(szFullName, pName);
|
||
|
}
|
||
|
|
||
|
pFile = FileNameToHandle(szFullName,NULL);
|
||
|
|
||
|
if (!pFile) {
|
||
|
pFile = AddFile(szFullName);
|
||
|
if (!FileRead(szFullName, pFile)) {
|
||
|
RemoveFile(pFile);
|
||
|
pFile = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!pFile) {
|
||
|
errstat(MBRERR_NOSUCHFILE, szFullName);
|
||
|
return;
|
||
|
}
|
||
|
pFileToTop(pFile);
|
||
|
MoveCur(0,Line);
|
||
|
GetLine(Line, buf, pFile);
|
||
|
MoveToSymbol(Line, buf, LastSymbol);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**************************************************************************/
|
||
|
|
||
|
void
|
||
|
pascal
|
||
|
MoveToSymbol(
|
||
|
IN LINE Line,
|
||
|
IN char *Buf,
|
||
|
IN char *Symbol
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Moves the cursor to the first occurance of a symbol within
|
||
|
a line. It is case-sensitive.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Line - Line number
|
||
|
Buf - Contents of the line
|
||
|
Symbol - Symbol to look for.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
// First Symbol within Buf
|
||
|
//
|
||
|
char *p = Buf;
|
||
|
char *q = Symbol;
|
||
|
char *Mark;
|
||
|
|
||
|
while (*p) {
|
||
|
//
|
||
|
// Look for first character
|
||
|
//
|
||
|
if (*p == *q) {
|
||
|
Mark = p;
|
||
|
//
|
||
|
// compare rest
|
||
|
//
|
||
|
while (*p && *q && *p == *q) {
|
||
|
p++;
|
||
|
q++;
|
||
|
}
|
||
|
if (*q) {
|
||
|
q = Symbol;
|
||
|
p = Mark+1;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
} else {
|
||
|
p++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!*q) {
|
||
|
MoveCur((COL)(Mark-Buf), Line);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**************************************************************************/
|
||
|
|
||
|
void
|
||
|
NextDefRef (
|
||
|
void
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Displays next definition or reference of a symbol.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
IINST Iinst;
|
||
|
|
||
|
|
||
|
// For locating the next def/ref we do the following:
|
||
|
//
|
||
|
// 1.- If the def/ref index is within the current range, we just
|
||
|
// increment it.
|
||
|
// 2.- Otherwise we look for the next instance that matches the
|
||
|
// MBF criteria, and set the def/ref index to the min value of
|
||
|
// the def/ref range for that instance.
|
||
|
// 3.- If no next instance is found, we display an error message
|
||
|
//
|
||
|
|
||
|
if (LastQueryType == Q_DEFINITION) {
|
||
|
if (LastiDef == iDefMax-1) {
|
||
|
|
||
|
Iinst = LastIinst;
|
||
|
|
||
|
do {
|
||
|
LastIinst++;
|
||
|
} while ((LastIinst < IinstMax) &&
|
||
|
(!INST_MATCHES_CRITERIA(LastIinst)));
|
||
|
|
||
|
if (LastIinst == IinstMax ) {
|
||
|
LastIinst = Iinst;
|
||
|
errstat(MBRERR_LAST_DEF, "");
|
||
|
return;
|
||
|
} else {
|
||
|
DefRangeOfInst(LastIinst, &iDefMin, &iDefMax);
|
||
|
LastiDef = iDefMin;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
LastiDef++;
|
||
|
}
|
||
|
} else {
|
||
|
if (LastiRef == iRefMax-1) {
|
||
|
|
||
|
Iinst = LastIinst;
|
||
|
|
||
|
do {
|
||
|
LastIinst++;
|
||
|
} while ((LastIinst < IinstMax) &&
|
||
|
(!INST_MATCHES_CRITERIA(LastIinst)));
|
||
|
|
||
|
if (LastIinst == IinstMax) {
|
||
|
LastIinst = Iinst;
|
||
|
errstat(MBRERR_LAST_REF, "");
|
||
|
return;
|
||
|
} else {
|
||
|
RefRangeOfInst(LastIinst, &iRefMin, &iRefMax);
|
||
|
LastiRef = iRefMin;
|
||
|
}
|
||
|
} else {
|
||
|
LastiRef++;
|
||
|
}
|
||
|
}
|
||
|
GotoDefRef();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**************************************************************************/
|
||
|
|
||
|
void
|
||
|
PrevDefRef (
|
||
|
void
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Displays the previous definition or reference of a symbol.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
IINST Iinst;
|
||
|
BOOL Match;
|
||
|
|
||
|
// For locating the previous def/ref we do the following:
|
||
|
//
|
||
|
// 1.- if the def/ref index is within the current range, we
|
||
|
// just decrement it.
|
||
|
// 2.- Otherwise we look for the most previous instance that
|
||
|
// matches the MBF criteria, and set the def/ref index to
|
||
|
// the maximum value within the def/ref range for that
|
||
|
// instance.
|
||
|
// 3.- If not such instance exist, we display an error message.
|
||
|
//
|
||
|
|
||
|
if (LastQueryType == Q_DEFINITION) {
|
||
|
if (LastiDef == iDefMin) {
|
||
|
|
||
|
if (LastIinst == IinstMin) {
|
||
|
errstat(MBRERR_FIRST_DEF, "");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Iinst = LastIinst;
|
||
|
|
||
|
do {
|
||
|
Iinst--;
|
||
|
} while ((LastIinst > IinstMin) &&
|
||
|
(!(Match = INST_MATCHES_CRITERIA(LastIinst))));
|
||
|
|
||
|
if (!Match) {
|
||
|
LastIinst = Iinst;
|
||
|
errstat(MBRERR_FIRST_DEF, "");
|
||
|
return;
|
||
|
} else {
|
||
|
DefRangeOfInst(LastIinst, &iDefMin, &iDefMax);
|
||
|
LastiDef = iDefMax - 1;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
LastiDef--;
|
||
|
}
|
||
|
} else {
|
||
|
if (LastiRef == iRefMin) {
|
||
|
|
||
|
if (LastIinst == IinstMin) {
|
||
|
errstat(MBRERR_FIRST_REF, "");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Iinst = LastIinst;
|
||
|
|
||
|
do {
|
||
|
Iinst--;
|
||
|
} while ((LastIinst > IinstMin) &&
|
||
|
(!(Match = INST_MATCHES_CRITERIA(LastIinst))));
|
||
|
|
||
|
if (!Match) {
|
||
|
LastIinst = Iinst;
|
||
|
errstat(MBRERR_FIRST_REF, "");
|
||
|
return;
|
||
|
} else {
|
||
|
RefRangeOfInst(LastIinst, &iRefMin, &iRefMax);
|
||
|
LastiRef = iRefMax - 1;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
LastiRef--;
|
||
|
}
|
||
|
}
|
||
|
GotoDefRef();
|
||
|
}
|