|
|
/*++
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(); }
|