/** * Create a manifest from the specified input files. * * @returns Program exit code, failures with error message. * @param pszManifest The name of the output manifest file. NULL if * it should be written to standard output. * @param fStdFormat Whether to expect standard format (true) or * java format (false). * @param pszChDir The directory to change into before processing * the file arguments. * @param fAttr The file attributes to put in the manifest. * @param pGetState The RTGetOpt state. * @param pUnion What the last RTGetOpt() call returned. * @param chOpt What the last RTGetOpt() call returned. */ static RTEXITCODE rtManifestDoCreate(const char *pszManifest, bool fStdFormat, const char *pszChDir, uint32_t fAttr, PRTGETOPTSTATE pGetState, PRTGETOPTUNION pUnion, int chOpt) { /* * Open the manifest file. */ int rc; RTVFSIOSTREAM hVfsIos; if (!pszManifest) { rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, RTFILE_O_WRITE, false /*fLeaveOpen*/, &hVfsIos); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to prepare standard output for writing: %Rrc", rc); } else { const char *pszError; rc = RTVfsChainOpenIoStream(pszManifest, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE, &hVfsIos, &pszError); if (RT_FAILURE(rc)) { if (pszError && *pszError) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc:\n" " '%s'\n", " %*s^\n", rc, pszManifest, pszError - pszManifest, ""); return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed with %Rrc opening the manifest '%s'", rc, pszManifest); } } /* * Create the internal manifest. */ RTMANIFEST hManifest; rc = RTManifestCreate(0 /*fFlags*/, &hManifest); if (RT_SUCCESS(rc)) { /* * Change directory and start processing the specified files. */ if (pszChDir) { rc = RTPathSetCurrent(pszChDir); if (RT_FAILURE(rc)) RTMsgError("Failed to change directory to '%s': %Rrc", pszChDir, rc); } if (RT_SUCCESS(rc)) { while (chOpt == VINF_GETOPT_NOT_OPTION) { rc = rtManifestAddFileToManifest(hManifest, pUnion->psz, fAttr); if (RT_FAILURE(rc)) break; /* next */ chOpt = RTGetOpt(pGetState, pUnion); } if (RT_SUCCESS(rc) && chOpt != 0) { RTGetOptPrintError(chOpt, pUnion); rc = chOpt < 0 ? chOpt : -chOpt; } } /* * Write the manifest. */ if (RT_SUCCESS(rc)) { if (fStdFormat) { rc = RTManifestWriteStandard(hManifest, hVfsIos); if (RT_FAILURE(rc)) RTMsgError("RTManifestWriteStandard failed: %Rrc", rc); } else { RTMsgError("Support for Java manifest files is not implemented yet"); rc = VERR_NOT_IMPLEMENTED; } } RTManifestRelease(hManifest); } RTVfsIoStrmRelease(hVfsIos); return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); if (argc == 1) { char szPath[RTPATH_MAX]; int rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/..")); if (RT_FAILURE(rc)) { RTPrintf("fatal error: RTPathExecDir -> %Rrc\n", rc); return 1; } rc = RTPathSetCurrent(strcat(szPath, "/..")); if (RT_FAILURE(rc)) { RTPrintf("fatal error: RTPathSetCurrent -> %Rrc\n", rc); return 1; } Process("testcase/tst*", "testcase"); Process("tst*", "."); } else { char szDir[RTPATH_MAX]; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { /* case '':... */ default: RTPrintf("syntax error: Option '%s' is not recognized\n", argv[i]); return 1; } } else { size_t cch = strlen(argv[i]); if (cch >= sizeof(szDir)) { RTPrintf("syntax error: '%s' is too long!\n", argv[i]); return 1; } memcpy(szDir, argv[i], cch + 1); char *pszFilename = RTPathFilename(szDir); if (!pszFilename) { RTPrintf("syntax error: '%s' does not include a file name or file name mask!\n", argv[i]); return 1; } RTPathStripFilename(szDir); Process(argv[i], szDir); } } } RTPrintf("\n" "********************\n" "*** PASSED: %u\n" "*** FAILED: %u\n" "*** SKIPPED: %u\n" "*** TOTAL: %u\n", g_cPasses, g_cFailures, g_cSkipped, g_cPasses + g_cFailures + g_cSkipped); return !!g_cFailures; }