////////////////////////////////////////////////////////////////////////////// // ppm2pps // // Copyright (c) 1996-1999 Microsoft Corporation // // Dump contents of ppm file // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include "gen.h" // string to put in front of all error messages so that BUILD can find them. const char *ErrMsgPrefix = "NMAKE : U8603: 'PPM2PPS' "; // // global variables BOOL fDebug; // global debug flag BOOL fDumpCCheck; // when set build ppswind.h for checking sizes/offsets HANDLE hFile; HANDLE hMapFile = NULL; PRBTREE pFunctions = NULL; PRBTREE pStructures = NULL; PRBTREE pTypedefs = NULL; PKNOWNTYPES NIL = NULL; // function prototypes void __cdecl ErrMsg(char *pch, ...); void __cdecl ExitErrMsg(BOOL bSysError, char *pch, ...); BOOL DumpTypedefs(FILE *filePpsfile, // file to write output BOOL fDumpNamedOnly, // when set don't do unnamed PRBTREE pHead); // known types function list BOOL DumpStructures(FILE *filePpsfile, // file to write output BOOL fDumpNamedOnly, // when set don't do unnamed PRBTREE pHead); // known types function list BOOL DumpFunctions(FILE *filePpsfile, // file to write output BOOL fDumpNamedOnly, // when set don't do unnamed PRBTREE pHead); // known types function list void Usage(char *s); BOOL ParseArguments(int argc, char *argv[], char *sPpmfile, char *sPpsfile, BOOL *pfDumpNamedOnly, BOOL *pfDebug, BOOL *pfDumpCCheck); BOOL DumpCCheckHeader(PRBTREE pTypedefs, // typedef lsit PRBTREE pStructs); // structs sit int __cdecl main(int argc, char *argv[]) { void *pvPpmData = NULL; BOOL fDumpNamedOnly; char sPpmfile[MAX_PATH]; char sPpsfile[MAX_PATH]; FILE *pfilePpsfile; try { if (! ParseArguments(argc, argv, sPpmfile, sPpsfile, &fDumpNamedOnly, &fDebug, &fDumpCCheck)) { Usage(argv[0]); return(-1); } if (*sPpmfile) { PCVMHEAPHEADER pHeader; pvPpmData = MapPpmFile(sPpmfile, TRUE); pHeader = (PCVMHEAPHEADER)pvPpmData; pFunctions = &pHeader->FuncsList; pTypedefs = &pHeader->TypeDefsList; pStructures =&pHeader->StructsList; NIL =&pHeader->NIL; pfilePpsfile = fopen(sPpsfile, "w"); if (pfilePpsfile == 0) { ErrMsg("ERROR - Could not open output file %s\n", sPpsfile); CloseHandle(hFile); CloseHandle(hMapFile); return(-1); } if (DumpFunctions(pfilePpsfile, fDumpNamedOnly, pFunctions)) { if (DumpStructures(pfilePpsfile, fDumpNamedOnly, pStructures)) { DumpTypedefs(pfilePpsfile,fDumpNamedOnly, pTypedefs); } } fclose(pfilePpsfile); } if (fDumpCCheck && pTypedefs && pStructures) { DumpCCheckHeader(pTypedefs, pStructures); } CloseHandle(hFile); CloseHandle(hMapFile); } except(EXCEPTION_EXECUTE_HANDLER) { ExitErrMsg(FALSE, "ExceptionCode=%x\n", GetExceptionCode() ); } return(0); } void DumpFuncinfo(FILE *pfilePpsfile, PFUNCINFO pf) { while (pf) { int i; fprintf(pfilePpsfile, "%s %s%s %s %s %s", TokenString[pf->tkDirection], (pf->fIsPtr64) ? "__ptr64 " : "", TokenString[pf->tkPreMod], TokenString[pf->tkSUE], pf->sType, TokenString[pf->tkPrePostMod] ); i = pf->IndLevel; while (i--) { fprintf(pfilePpsfile, "*"); } fprintf(pfilePpsfile, "%s %s", TokenString[pf->tkPostMod], (pf->sName) ? pf->sName : "" ); pf = pf->pfuncinfoNext; if (pf) { fprintf(pfilePpsfile, ", "); } } } ///////////////////////////////////////////////////////////////////////////// // // DumpCCheckHeader // // dump header file that can be used to check sizes in ppm file against // those that are generated by C // // returns TRUE on success // ///////////////////////////////////////////////////////////////////////////// BOOL DumpCCheckHeader(PRBTREE pTypedefs, // typedef lsit PRBTREE pStructs) // structs lsit { PKNOWNTYPES pknwntyp, pknwntypBasic; FILE *pfile; pfile = fopen("ppswind.h", "w"); if (pfile == NULL) { ErrMsg("Error opening ppwind.h for output\n"); return(FALSE); } fprintf(pfile, "CCHECKSIZE cchecksize[] = {\n"); // // typedefs pknwntyp = pTypedefs->pLastNodeInserted; while (pknwntyp) { if ((! isdigit(*pknwntyp->TypeName)) && (strcmp(pknwntyp->TypeName,"...")) && (strcmp(pknwntyp->TypeName,"()")) && (strcmp(pknwntyp->BasicType, szFUNC)) && (pknwntyp->Size > 0) && (pknwntyp->dwScopeLevel == 0)) { pknwntypBasic = GetBasicType(pknwntyp->TypeName, pTypedefs, pStructs); if (! ( (pknwntypBasic == NULL) || ( (! strcmp(pknwntypBasic->BaseName, szVOID)) && (pknwntypBasic->pmeminfo == NULL)))) { fprintf(pfile, " { %4d, sizeof(%s), \"%s\"}, \n", pknwntyp->Size, pknwntyp->TypeName, pknwntyp->TypeName); } } pknwntyp = pknwntyp->Next; } // // structs pknwntyp = pStructs->pLastNodeInserted; while (pknwntyp) { if ((! isdigit(*pknwntyp->TypeName) && (pknwntyp->pmeminfo))) { if (!(pknwntyp->Flags & BTI_ANONYMOUS) && (pknwntyp->Size > 0) && (pknwntyp->dwScopeLevel == 0)) { fprintf(pfile, " { %4d, sizeof(%s %s), \"%s %s\" }, \n", pknwntyp->Size, pknwntyp->BaseName, pknwntyp->TypeName, pknwntyp->BaseName, pknwntyp->TypeName); } } pknwntyp = pknwntyp->Next; } fprintf(pfile, " {0xffffffff, 0xffffffff, \"\"}\n"); fprintf(pfile,"\n};\n"); // // structs fields fprintf(pfile, "CCHECKOFFSET ccheckoffset[] = {\n"); pknwntyp = pStructs->pLastNodeInserted; while (pknwntyp) { if (! isdigit(*pknwntyp->TypeName)) { if (!(pknwntyp->Flags & BTI_ANONYMOUS) && !(pknwntyp->Flags & BTI_VIRTUALONLY) && (pknwntyp->Size > 0) && (pknwntyp->dwScopeLevel == 0)) { PMEMBERINFO pmeminfo = pknwntyp->pmeminfo; while (pmeminfo != NULL) { if ((pmeminfo->sName != NULL) && (*pmeminfo->sName != 0) && !(pmeminfo->bIsBitfield)) { fprintf(pfile, " { %4d, (long) (& (((%s %s *)0)->%s)), \"%s\", \"%s\" },\n", pmeminfo->dwOffset, pknwntyp->BaseName, pknwntyp->TypeName, pmeminfo->sName, pknwntyp->TypeName, pmeminfo->sName); } pmeminfo = pmeminfo->pmeminfoNext; } } } pknwntyp = pknwntyp->Next; } fprintf(pfile, " {0xffffffff, 0xffffffff, \"\", \"\"}\n"); fprintf(pfile,"\n};\n"); fclose(pfile); return(TRUE); } ///////////////////////////////////////////////////////////////////////////// // // DumpTypedefs // // dump structures from ppm file to output file // // returns TRUE on success // ///////////////////////////////////////////////////////////////////////////// BOOL DumpTypedefs(FILE *pfilePpsfile, // file to write output BOOL fDumpNamedOnly, // when set don't do unnamed PRBTREE pHead) // known types function list { KNOWNTYPES *pknwntyp; pknwntyp = pHead->pLastNodeInserted; fprintf(pfilePpsfile,"[Typedefs]\n\n"); while (pknwntyp) { fprintf(pfilePpsfile, "%2.1x|%2.1x|%2.1x|%s|%s|%s|%s|%s|", pknwntyp->Flags, pknwntyp->IndLevel, pknwntyp->Size, pknwntyp->BasicType, pknwntyp->BaseName ? pknwntyp->BaseName : szNULL, pknwntyp->FuncRet ? pknwntyp->FuncRet : szNULL, pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL, pknwntyp->TypeName ); DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo); fprintf(pfilePpsfile, "|\n"); pknwntyp = pknwntyp->Next; } return(TRUE); } ///////////////////////////////////////////////////////////////////////////// // // DumpStructures // // dump structures from ppm file to output file // // returns TRUE on success // ///////////////////////////////////////////////////////////////////////////// BOOL DumpStructures(FILE *pfilePpsfile, // file to write output BOOL fDumpNamedOnly, // when set don't do unnamed PRBTREE pHead) // known types function list { KNOWNTYPES *pknwntyp; DWORD dw; PMEMBERINFO pmeminfo; pknwntyp = pHead->pLastNodeInserted; fprintf(pfilePpsfile,"[Structures]\n\n"); while (pknwntyp) { if (! fDumpNamedOnly || ! isdigit(*pknwntyp->TypeName)) { fprintf(pfilePpsfile, "%2.1x|%2.1x|%2.1x|%s|%s|%s|%s|%s|", pknwntyp->Flags, pknwntyp->IndLevel, pknwntyp->Size, pknwntyp->BasicType, pknwntyp->BaseName ? pknwntyp->BaseName : szNULL, pknwntyp->FuncRet ? pknwntyp->FuncRet : szNULL, pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL, pknwntyp->TypeName); // dump out the structure member info, if present pmeminfo = pknwntyp->pmeminfo; while (pmeminfo) { int i; fprintf(pfilePpsfile, "%s", pmeminfo->sType); i = pmeminfo->IndLevel; if (i) { fprintf(pfilePpsfile, " "); while (i--) { fprintf(pfilePpsfile, "*"); } } if (pmeminfo->sName) { fprintf(pfilePpsfile, " %s", pmeminfo->sName); } fprintf(pfilePpsfile, " @ %d|", pmeminfo->dwOffset); pmeminfo = pmeminfo->pmeminfoNext; } // dump out the function info, if present DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo); fprintf(pfilePpsfile, "\n"); } pknwntyp = pknwntyp->Next; } return(TRUE); } ///////////////////////////////////////////////////////////////////////////// // // DumpFunctions // // dump fucntion prototypes from ppm file to output file // // returns TRUE on success // ///////////////////////////////////////////////////////////////////////////// BOOL DumpFunctions(FILE *pfilePpsfile, // file to write output BOOL fDumpNamedOnly, // when set don't do unnamed PRBTREE pHead) // known types function list { KNOWNTYPES *pknwntyp; PFUNCINFO pf; pknwntyp = pHead->pLastNodeInserted; fprintf(pfilePpsfile,"[Functions]\n\n"); while (pknwntyp) { fprintf(pfilePpsfile, "%s|%s|%s|%s|", (pknwntyp->Flags & BTI_DLLEXPORT) ? "dllexport" : "", pknwntyp->FuncRet, pknwntyp->FuncMod ? pknwntyp->FuncMod : szNULL, pknwntyp->TypeName ); DumpFuncinfo(pfilePpsfile, pknwntyp->pfuncinfo); fprintf(pfilePpsfile, "|\n"); pknwntyp = pknwntyp->Next; } return(TRUE); } ///////////////////////////////////////////////////////////////////////////// // // Usgae // // tells how to use // // ///////////////////////////////////////////////////////////////////////////// void Usage(char *s) // name of command invoked { printf("Usage:\n"); printf(" %s -d -n -x \n", s); printf(" -d set debug flag\n"); printf(" -n dumps only named structs/enums/unions\n"); printf(" -x creates ppswind.h for size/offset checking\n"); } ///////////////////////////////////////////////////////////////////////////// // // ParseArgumaners // // parse arguments // // returnms FALSE on syntax error // ///////////////////////////////////////////////////////////////////////////// BOOL ParseArguments(int argc, char *argv[], char *sPpmfile, char *sPpsfile, BOOL *pfDumpNamedOnly, BOOL *pfDebug, BOOL *pfDumpCCheck) { int i; *sPpmfile = 0; *sPpsfile = 0; *pfDumpNamedOnly = FALSE; *pfDebug = FALSE; *pfDumpCCheck = FALSE; for (i = 1; i < argc; i++) { if (*argv[i] == '-') { switch(tolower(argv[i][1])) { case 'd': { *pfDebug = TRUE; break; } case 'n': { *pfDumpNamedOnly = TRUE; break; } case 'x': { *pfDumpCCheck = TRUE; break; } default: { return(FALSE); } } } else { if (lstrlenA(argv[i]) >= MAX_PATH) { return(FALSE); } if (*sPpmfile == 0) { strcpy(sPpmfile, argv[i]); } else if (*sPpsfile == 0) { strcpy(sPpsfile, argv[i]); } else { return(FALSE); } } } return( *pfDumpCCheck || ((*sPpmfile != 0) && (*sPpsfile != 0))); } void HandlePreprocessorDirective( char *p ) { ExitErrMsg(FALSE, "Preprocessor directives not allowed by ppm2pps\n"); }