📄 modulpsr.c
字号:
/* If the next token is the special variable ?ALL, then all */
/* constructs of the specified type are imported/exported. If */
/* the next token is the special variable ?NONE, then no */
/* constructs of the specified type will be imported/exported. */
/*=============================================================*/
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
if (theToken->type == SF_VARIABLE)
{
/*==============================*/
/* Check to see if the variable */
/* is either ?ALL or ?NONE. */
/*==============================*/
if (strcmp(ValueToString(theToken->value),"ALL") == 0)
{
newPort = (struct portItem *) get_struct(theEnv,portItem);
newPort->moduleName = moduleName;
newPort->constructType = theConstruct;
newPort->constructName = NULL;
newPort->next = NULL;
}
else if (strcmp(ValueToString(theToken->value),"NONE") == 0)
{ newPort = NULL; }
else
{
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
/*=======================================================*/
/* The export/import specification must end with a right */
/* parenthesis after ?ALL or ?NONE at this point. */
/*=======================================================*/
GetToken(theEnv,readSource,theToken);
if (theToken->type != RPAREN)
{
if (newPort != NULL) rtn_struct(theEnv,portItem,newPort);
PPBackup(theEnv);
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken->printForm);
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
/*=====================================*/
/* Add the new specification to either */
/* the import or export list. */
/*=====================================*/
if (newPort != NULL)
{
if (importModule != NULL)
{
newPort->next = newModule->importList;
newModule->importList = newPort;
}
else
{
newPort->next = newModule->exportList;
newModule->exportList = newPort;
}
}
/*============================================*/
/* Return FALSE to indicate the import/export */
/* specification was successfully parsed. */
/*============================================*/
return(FALSE);
}
/*============================================*/
/* There must be at least one named construct */
/* in the import/export list at this point. */
/*============================================*/
if (theToken->type == RPAREN)
{
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
/*=====================================*/
/* Read in the list of imported items. */
/*=====================================*/
while (theToken->type != RPAREN)
{
if (theToken->type != thePortConstruct->typeExpected)
{
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
/*========================================*/
/* Create the data structure to represent */
/* the import/export specification for */
/* the named construct. */
/*========================================*/
newPort = (struct portItem *) get_struct(theEnv,portItem);
newPort->moduleName = moduleName;
newPort->constructType = theConstruct;
newPort->constructName = (SYMBOL_HN *) theToken->value;
/*=====================================*/
/* Add the new specification to either */
/* the import or export list. */
/*=====================================*/
if (importModule != NULL)
{
newPort->next = newModule->importList;
newModule->importList = newPort;
}
else
{
newPort->next = newModule->exportList;
newModule->exportList = newPort;
}
/*===================================*/
/* Move on to the next import/export */
/* specification. */
/*===================================*/
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
}
/*=============================*/
/* Fix up pretty print buffer. */
/*=============================*/
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,")");
/*============================================*/
/* Return FALSE to indicate the import/export */
/* specification was successfully parsed. */
/*============================================*/
return(FALSE);
}
/*************************************************************/
/* ValidPortConstructItem: Returns TRUE if a given construct */
/* name is in the list of constructs which can be exported */
/* and imported, otherwise FALSE is returned. */
/*************************************************************/
globle struct portConstructItem *ValidPortConstructItem(
void *theEnv,
char *theName)
{
struct portConstructItem *theItem;
for (theItem = DefmoduleData(theEnv)->ListOfPortConstructItems;
theItem != NULL;
theItem = theItem->next)
{ if (strcmp(theName,theItem->constructName) == 0) return(theItem); }
return(NULL);
}
/***********************************************************/
/* FindMultiImportConflict: Determines if a module imports */
/* the same named construct from more than one module */
/* (i.e. an ambiguous reference which is not allowed). */
/***********************************************************/
static int FindMultiImportConflict(
void *theEnv,
struct defmodule *theModule)
{
struct defmodule *testModule;
int count;
struct portConstructItem *thePCItem;
struct construct *theConstruct;
void *theCItem;
/*==========================*/
/* Save the current module. */
/*==========================*/
SaveCurrentModule(theEnv);
/*============================*/
/* Loop through every module. */
/*============================*/
for (testModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
testModule != NULL;
testModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,testModule))
{
/*========================================*/
/* Loop through every construct type that */
/* can be imported/exported by a module. */
/*========================================*/
for (thePCItem = DefmoduleData(theEnv)->ListOfPortConstructItems;
thePCItem != NULL;
thePCItem = thePCItem->next)
{
EnvSetCurrentModule(theEnv,(void *) testModule);
/*=====================================================*/
/* Loop through every construct of the specified type. */
/*=====================================================*/
theConstruct = FindConstruct(theEnv,thePCItem->constructName);
for (theCItem = (*theConstruct->getNextItemFunction)(theEnv,NULL);
theCItem != NULL;
theCItem = (*theConstruct->getNextItemFunction)(theEnv,theCItem))
{
/*===============================================*/
/* Check to see if the specific construct in the */
/* module can be imported with more than one */
/* reference into the module we're examining for */
/* ambiguous import specifications. */
/*===============================================*/
EnvSetCurrentModule(theEnv,(void *) theModule);
FindImportedConstruct(theEnv,thePCItem->constructName,NULL,
ValueToString((*theConstruct->getConstructNameFunction)
((struct constructHeader *) theCItem)),
&count,FALSE,NULL);
if (count > 1)
{
ImportExportConflictMessage(theEnv,"defmodule",EnvGetDefmoduleName(theEnv,theModule),
thePCItem->constructName,
ValueToString((*theConstruct->getConstructNameFunction)
((struct constructHeader *) theCItem)));
RestoreCurrentModule(theEnv);
return(TRUE);
}
EnvSetCurrentModule(theEnv,(void *) testModule);
}
}
}
/*=============================*/
/* Restore the current module. */
/*=============================*/
RestoreCurrentModule(theEnv);
/*=======================================*/
/* Return FALSE to indicate no ambiguous */
/* references were found. */
/*=======================================*/
return(FALSE);
}
/******************************************************/
/* NotExportedErrorMessage: Generalized error message */
/* for indicating that a construct type or specific */
/* named construct is not exported. */
/******************************************************/
static void NotExportedErrorMessage(
void *theEnv,
char *theModule,
char *theConstruct,
char *theName)
{
PrintErrorID(theEnv,"MODULPSR",1,TRUE);
EnvPrintRouter(theEnv,WERROR,"Module ");
EnvPrintRouter(theEnv,WERROR,theModule);
EnvPrintRouter(theEnv,WERROR," does not export ");
if (theConstruct == NULL) EnvPrintRouter(theEnv,WERROR,"any constructs");
else if (theName == NULL)
{
EnvPrintRouter(theEnv,WERROR,"any ");
EnvPrintRouter(theEnv,WERROR,theConstruct);
EnvPrintRouter(theEnv,WERROR," constructs");
}
else
{
EnvPrintRouter(theEnv,WERROR,"the ");
EnvPrintRouter(theEnv,WERROR,theConstruct);
EnvPrintRouter(theEnv,WERROR," ");
EnvPrintRouter(theEnv,WERROR,theName);
}
EnvPrintRouter(theEnv,WERROR,".\n");
}
/*************************************************************/
/* FindImportExportConflict: Determines if the definition of */
/* a construct would cause an import/export conflict. The */
/* construct is not yet defined when this function is */
/* called. TRUE is returned if an import/export conflicts */
/* is found, otherwise FALSE is returned. */
/*************************************************************/
globle int FindImportExportConflict(
void *theEnv,
char *constructName,
struct defmodule *matchModule,
char *findName)
{
struct defmodule *theModule;
struct moduleItem *theModuleItem;
int count;
/*===========================================================*/
/* If the construct type can't be imported or exported, then */
/* it's not possible to have an import/export conflict. */
/*===========================================================*/
if (ValidPortConstructItem(theEnv,constructName) == NULL) return(FALSE);
/*============================================*/
/* There module name should already have been */
/* separated fromthe construct's name. */
/*============================================*/
if (FindModuleSeparator(findName)) return(FALSE);
/*===============================================================*/
/* The construct must be capable of being stored within a module */
/* (this test should never fail). The construct must also have */
/* a find function associated with it so we can actually look */
/* for import/export conflicts. */
/*===============================================================*/
if ((theModuleItem = FindModuleItem(theEnv,constructName)) == NULL) return(FALSE);
if (theModuleItem->findFunction == NULL) return(FALSE);
/*==========================*/
/* Save the current module. */
/*==========================*/
SaveCurrentModule(theEnv);
/*================================================================*/
/* Look at each module and count each definition of the specified */
/* construct which is visible to the module. If more than one */
/* definition is visible, then an import/export conflict exists */
/* and TRUE is returned. */
/*================================================================*/
for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
theModule != NULL;
theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
{
EnvSetCurrentModule(theEnv,(void *) theModule);
FindImportedConstruct(theEnv,constructName,NULL,findName,&count,TRUE,matchModule);
if (count > 1)
{
RestoreCurrentModule(theEnv);
return(TRUE);
}
}
/*==========================================*/
/* Restore the current module. No conflicts */
/* were detected so FALSE is returned. */
/*==========================================*/
RestoreCurrentModule(theEnv);
return(FALSE);
}
#endif /* DEFMODULE_CONSTRUCT && (! RUN_TIME) && (! BLOAD_ONLY) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -