windows-nt/Source/XPSP1/NT/sdktools/mep/extens/mbrowse/mbrqry.c

432 lines
8.6 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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();
}