/* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */ /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */ #include "precomp.h" /* print all undefined/unexported symbols and terminate */ void UndefinedError(AssignmentList_t ass, UndefinedSymbolList_t undef, UndefinedSymbol_t *bad) { UndefinedSymbol_t *u; char *type; int undefined = 0, unexported = 0; char *identifier; /* count undefined and unexported symbols */ for (u = undef; u; u = u->Next) { switch (u->Type) { case eUndefinedSymbol_SymbolNotDefined: case eUndefinedSymbol_SymbolNotExported: if (FindUndefinedSymbol(ass, bad, u->U.Symbol.ReferenceType, u->U.Symbol.Identifier, u->U.Symbol.Module)) continue; break; case eUndefinedSymbol_FieldNotDefined: case eUndefinedSymbol_FieldNotExported: if (FindUndefinedField(ass, bad, u->U.Field.ReferenceFieldType, u->U.Field.ObjectClass, u->U.Field.Identifier, u->U.Field.Module)) continue; break; } switch (u->Type) { case eUndefinedSymbol_SymbolNotDefined: case eUndefinedSymbol_FieldNotDefined: undefined = 1; break; case eUndefinedSymbol_SymbolNotExported: case eUndefinedSymbol_FieldNotExported: unexported = 1; break; } } /* print the undefined symbols */ if (undefined) { fprintf(stderr, "Following symbols are undefined:\n"); for (u = undef; u; u = u->Next) { if (u->Type == eUndefinedSymbol_SymbolNotExported || u->Type == eUndefinedSymbol_FieldNotExported) continue; if (u->Type == eUndefinedSymbol_SymbolNotDefined && FindUndefinedSymbol(ass, bad, u->U.Symbol.ReferenceType, u->U.Symbol.Identifier, u->U.Symbol.Module)) continue; if (u->Type == eUndefinedSymbol_FieldNotDefined && FindUndefinedField(ass, bad, u->U.Field.ReferenceFieldType, u->U.Field.ObjectClass, u->U.Field.Identifier, u->U.Field.Module)) continue; if (u->Type == eUndefinedSymbol_SymbolNotDefined) { switch (u->U.Symbol.ReferenceType) { case eAssignment_Type: type = "type"; break; case eAssignment_Value: type = "value"; break; case eAssignment_ObjectClass: type = "object class"; break; case eAssignment_Object: type = "object"; break; case eAssignment_ObjectSet: type = "object set"; break; case eAssignment_Macro: type = "macro"; break; case eAssignment_Undefined: if (isupper(*u->U.Symbol.Identifier)) type = "type?"; else if (islower(*u->U.Symbol.Identifier)) type = "value?"; else type = "?"; break; default: MyAbort(); /*NOTREACHED*/ } identifier = u->U.Symbol.Identifier ? u->U.Symbol.Identifier : ""; if (u->U.Symbol.Module) { fprintf(stderr, "%s.%s (%s)\n", u->U.Symbol.Module->Identifier, identifier, type); } else { fprintf(stderr, "%s (%s)\n", identifier, type); } } else { switch (u->U.Field.ReferenceFieldType) { case eSetting_Type: type = "type field"; break; case eSetting_Value: type = "value field"; break; case eSetting_ValueSet: type = "value set field"; break; case eSetting_Object: type = "object field"; break; case eSetting_ObjectSet: type = "object set field"; break; case eAssignment_Macro: type = "macro"; break; default: MyAbort(); /*NOTREACHED*/ } identifier = u->U.Field.Identifier ? u->U.Field.Identifier : ""; if (u->U.Field.Module) { fprintf(stderr, "%s.%s.%s (%s)\n", u->U.Field.Module->Identifier, u->U.Field.ObjectClass->U.Reference.Identifier, identifier, type); } else { fprintf(stderr, "%s.%s (%s)\n", u->U.Field.ObjectClass->U.Reference.Identifier, identifier, type); } } } } /* print the unexported symbols */ if (unexported) { fprintf(stderr, "Following symbols have not been exported:\n"); for (u = undef; u; u = u->Next) { if (u->Type == eUndefinedSymbol_SymbolNotDefined || u->Type == eUndefinedSymbol_FieldNotDefined) continue; if (u->Type == eUndefinedSymbol_SymbolNotExported && FindUndefinedSymbol(ass, bad, u->U.Symbol.ReferenceType, u->U.Symbol.Identifier, u->U.Symbol.Module)) continue; if (u->Type == eUndefinedSymbol_FieldNotExported && FindUndefinedField(ass, bad, u->U.Field.ReferenceFieldType, u->U.Field.ObjectClass, u->U.Field.Identifier, u->U.Field.Module)) continue; if (u->Type == eUndefinedSymbol_SymbolNotExported) { switch (u->U.Symbol.ReferenceType) { case eAssignment_Type: type = "type"; break; case eAssignment_Value: type = "value"; break; case eAssignment_ObjectClass: type = "object class"; break; case eAssignment_Object: type = "object"; break; case eAssignment_ObjectSet: type = "object set"; break; case eAssignment_Macro: type = "macro"; break; case eAssignment_Undefined: if (isupper(*u->U.Symbol.Identifier)) type = "type?"; else if (islower(*u->U.Symbol.Identifier)) type = "value?"; else type = "?"; break; default: MyAbort(); /*NOTREACHED*/ } identifier = u->U.Symbol.Identifier ? u->U.Symbol.Identifier : ""; if (u->U.Symbol.Module) { fprintf(stderr, "%s.%s (%s)\n", u->U.Symbol.Module->Identifier, identifier, type); } else { fprintf(stderr, "%s (%s)\n", identifier, type); } } else { switch (u->U.Field.ReferenceFieldType) { case eSetting_Type: type = "type field"; break; case eSetting_Value: type = "value field"; break; case eSetting_ValueSet: type = "value set field"; break; case eSetting_Object: type = "object field"; break; case eSetting_ObjectSet: type = "object set field"; break; case eAssignment_Macro: type = "macro"; break; default: MyAbort(); /*NOTREACHED*/ } identifier = u->U.Field.Identifier ? u->U.Field.Identifier : ""; if (u->U.Field.Module) { fprintf(stderr, "%s.%s.%s (%s)\n", u->U.Field.Module->Identifier, u->U.Field.ObjectClass->U.Reference.Identifier, identifier, type); } else { fprintf(stderr, "%s.%s (%s)\n", u->U.Field.ObjectClass->U.Reference.Identifier, identifier, type); } } } } MyExit(1); } /* compare two undefined symbol entries */ /* return 0 if equal */ int CmpUndefinedSymbol(AssignmentList_t ass, UndefinedSymbol_t *u1, UndefinedSymbol_t *u2) { if (u1->Type != u2->Type) return 1; switch (u1->Type) { case eUndefinedSymbol_SymbolNotExported: case eUndefinedSymbol_SymbolNotDefined: return strcmp(u1->U.Symbol.Identifier, u2->U.Symbol.Identifier) || u1->U.Symbol.Module && !u2->U.Symbol.Module || !u1->U.Symbol.Module && u2->U.Symbol.Module || u1->U.Symbol.Module && u2->U.Symbol.Module && CmpModuleIdentifier(ass, u1->U.Symbol.Module, u2->U.Symbol.Module); case eUndefinedSymbol_FieldNotExported: case eUndefinedSymbol_FieldNotDefined: return strcmp(u1->U.Field.Identifier, u2->U.Field.Identifier) || strcmp(u1->U.Field.ObjectClass->U.Reference.Identifier, u2->U.Field.ObjectClass->U.Reference.Identifier) || CmpModuleIdentifier(ass, u1->U.Field.ObjectClass->U.Reference.Module, u2->U.Field.ObjectClass->U.Reference.Module) || u1->U.Field.Module && !u2->U.Field.Module || !u1->U.Field.Module && u2->U.Field.Module || u1->U.Field.Module && u2->U.Field.Module && CmpModuleIdentifier(ass, u1->U.Field.Module, u2->U.Field.Module); default: MyAbort(); /*NOTREACHED*/ } return 1; // not equal } /* compare two lists of undefined symbols */ int CmpUndefinedSymbolList(AssignmentList_t ass, UndefinedSymbolList_t u1, UndefinedSymbolList_t u2) { for (; u1 && u2; u1 = u1->Next, u2 = u2->Next) { if (CmpUndefinedSymbol(ass, u1, u2)) return 1; } return u1 || u2; }