📄 modulutl.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.20 01/31/02 */
/* */
/* DEFMODULE UTILITY MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides routines for parsing module/construct */
/* names and searching through modules for specific */
/* constructs. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian L. Donnell */
/* */
/* Revision History: */
/* */
/*************************************************************/
#define _MODULUTL_SOURCE_
#include "setup.h"
#include "memalloc.h"
#include "router.h"
#include "envrnmnt.h"
#include "modulpsr.h"
#include "modulutl.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static void *SearchImportedConstructModules(void *,struct symbolHashNode *,
struct defmodule *,
struct moduleItem *,struct symbolHashNode *,
int *,int,struct defmodule *);
/********************************************************************/
/* FindModuleSeparator: Finds the :: separator which delineates the */
/* boundary between a module name and a construct name. The value */
/* zero is returned if the separator is not found, otherwise the */
/* position of the second colon within the string is returned. */
/********************************************************************/
globle unsigned FindModuleSeparator(
char *theString)
{
unsigned i, foundColon;
for (i = 0, foundColon = FALSE; theString[i] != EOS; i++)
{
if (theString[i] == ':')
{
if (foundColon) return(i);
foundColon = TRUE;
}
else
{ foundColon = FALSE; }
}
return(FALSE);
}
/*******************************************************************/
/* ExtractModuleName: Given the position of the :: separator and a */
/* module/construct name joined using the separator, returns a */
/* symbol reference to the module name (or NULL if a module name */
/* cannot be extracted). */
/*******************************************************************/
globle SYMBOL_HN *ExtractModuleName(
void *theEnv,
unsigned thePosition,
char *theString)
{
char *newString;
SYMBOL_HN *returnValue;
/*=============================================*/
/* Return NULL if the :: is in a position such */
/* that a module name can't be extracted. */
/*=============================================*/
if (thePosition <= 1) return(NULL);
/*==========================================*/
/* Allocate storage for a temporary string. */
/*==========================================*/
newString = (char *) gm2(theEnv,thePosition);
/*======================================================*/
/* Copy the entire module/construct name to the string. */
/*======================================================*/
strncpy(newString,theString,
(STD_SIZE) thePosition - 1);
/*========================================================*/
/* Place an end of string marker where the :: is located. */
/*========================================================*/
newString[thePosition-1] = EOS;
/*=====================================================*/
/* Add the module name (the truncated module/construct */
/* name) to the symbol table. */
/*=====================================================*/
returnValue = (SYMBOL_HN *) EnvAddSymbol(theEnv,newString);
/*=============================================*/
/* Return the storage of the temporary string. */
/*=============================================*/
rm(theEnv,newString,thePosition);
/*=============================================*/
/* Return a pointer to the module name symbol. */
/*=============================================*/
return(returnValue);
}
/********************************************************************/
/* ExtractConstructName: Given the position of the :: separator and */
/* a module/construct name joined using the separator, returns a */
/* symbol reference to the construct name (or NULL if a construct */
/* name cannot be extracted). */
/********************************************************************/
globle SYMBOL_HN *ExtractConstructName(
void *theEnv,
unsigned thePosition,
char *theString)
{
size_t theLength;
char *newString;
SYMBOL_HN *returnValue;
/*======================================*/
/* Just return the string if it doesn't */
/* contain the :: symbol. */
/*======================================*/
if (thePosition == 0) return((SYMBOL_HN *) EnvAddSymbol(theEnv,theString));
/*=====================================*/
/* Determine the length of the string. */
/*=====================================*/
theLength = strlen(theString);
/*=================================================*/
/* Return NULL if the :: is at the very end of the */
/* string (and thus there is no construct name). */
/*=================================================*/
if (theLength <= (thePosition + 1)) return(NULL);
/*====================================*/
/* Allocate a temporary string large */
/* enough to hold the construct name. */
/*====================================*/
newString = (char *) gm2(theEnv,theLength - thePosition);
/*================================================*/
/* Copy the construct name portion of the */
/* module/construct name to the temporary string. */
/*================================================*/
strncpy(newString,&theString[thePosition+1],
(STD_SIZE) theLength - thePosition);
/*=============================================*/
/* Add the construct name to the symbol table. */
/*=============================================*/
returnValue = (SYMBOL_HN *) EnvAddSymbol(theEnv,newString);
/*=============================================*/
/* Return the storage of the temporary string. */
/*=============================================*/
rm(theEnv,newString,theLength - thePosition);
/*================================================*/
/* Return a pointer to the construct name symbol. */
/*================================================*/
return(returnValue);
}
/****************************************************/
/* ExtractModuleAndConstructName: Extracts both the */
/* module and construct name from a string. Sets */
/* the current module to the specified module. */
/****************************************************/
globle char *ExtractModuleAndConstructName(
void *theEnv,
char *theName)
{
unsigned separatorPosition;
SYMBOL_HN *moduleName, *shortName;
struct defmodule *theModule;
/*========================*/
/* Find the :: separator. */
/*========================*/
separatorPosition = FindModuleSeparator(theName);
if (! separatorPosition) return(theName);
/*==========================*/
/* Extract the module name. */
/*==========================*/
moduleName = ExtractModuleName(theEnv,separatorPosition,theName);
if (moduleName == NULL) return(NULL);
/*====================================*/
/* Check to see if the module exists. */
/*====================================*/
theModule = (struct defmodule *) EnvFindDefmodule(theEnv,ValueToString(moduleName));
if (theModule == NULL) return(NULL);
/*============================*/
/* Change the current module. */
/*============================*/
EnvSetCurrentModule(theEnv,(void *) theModule);
/*=============================*/
/* Extract the construct name. */
/*=============================*/
shortName = ExtractConstructName(theEnv,separatorPosition,theName);
return(ValueToString(shortName));
}
/************************************************************/
/* FindImportedConstruct: High level routine which searches */
/* a module and other modules from which it imports */
/* constructs for a specified construct. */
/************************************************************/
globle void *FindImportedConstruct(
void *theEnv,
char *constructName,
struct defmodule *matchModule,
char *findName,
int *count,
int searchCurrent,
struct defmodule *notYetDefinedInModule)
{
void *rv;
struct moduleItem *theModuleItem;
/*=============================================*/
/* Set the number of references found to zero. */
/*=============================================*/
*count = 0;
/*===============================*/
/* The :: should not be included */
/* in the construct's name. */
/*===============================*/
if (FindModuleSeparator(findName)) return(NULL);
/*=============================================*/
/* Remember the current module since we'll be */
/* changing it during the search and will want */
/* to restore it once the search is completed. */
/*=============================================*/
SaveCurrentModule(theEnv);
/*==========================================*/
/* Find the module related access functions */
/* for the construct type being sought. */
/*==========================================*/
if ((theModuleItem = FindModuleItem(theEnv,constructName)) == NULL)
{
RestoreCurrentModule(theEnv);
return(NULL);
}
/*===========================================*/
/* If the construct type doesn't have a find */
/* function, then we can't look for it. */
/*===========================================*/
if (theModuleItem->findFunction == NULL)
{
RestoreCurrentModule(theEnv);
return(NULL);
}
/*==================================*/
/* Initialize the search by marking */
/* all modules as unvisited. */
/*==================================*/
MarkModulesAsUnvisited(theEnv);
/*===========================*/
/* Search for the construct. */
/*===========================*/
rv = SearchImportedConstructModules(theEnv,(SYMBOL_HN *) EnvAddSymbol(theEnv,constructName),
matchModule,theModuleItem,
(SYMBOL_HN *) EnvAddSymbol(theEnv,findName),count,
searchCurrent,notYetDefinedInModule);
/*=============================*/
/* Restore the current module. */
/*=============================*/
RestoreCurrentModule(theEnv);
/*====================================*/
/* Return a pointer to the construct. */
/*====================================*/
return(rv);
}
/*********************************************************/
/* AmbiguousReferenceErrorMessage: Error message printed */
/* when a reference to a specific construct can be */
/* imported from more than one module. */
/*********************************************************/
globle void AmbiguousReferenceErrorMessage(
void *theEnv,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -