📄 tmt.cpp
字号:
// $util\tmt.cpp 1.5 milbo$ test mt// Warning: this is raw research code -- expect it to be quite messy.// milbo durban may 2006//-----------------------------------------------------------------------------// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// A copy of the GNU General Public License is available at// http://www.r-project.org/Licenses///-----------------------------------------------------------------------------#include "conio.h" // for _kbhit#include "all.hpp"//-----------------------------------------------------------------------------#define SED_FILE "tmt.sed" // sed file name#define TMP_FILE "tmt.tmp" // temporary file name#define N_OLD 5 // actually the current code supports only 2 (will get Err if you try more)#define N_NEW 100 // 100 is arbitrary#define MAX_MS_DAT 1000000 // maximum number of tests per ms.dat file -- make very big so we never split up the ms.dat file#define RELEASE "Release" // "Release" or "Debug": build version when make is called by this program#define SEMA_FILE "/a/masm/masm/out/semaFile" // semaphore file, tells ModelStatsUpdate.r that it can run)#define LOG_ERRS 0 // defined to 0 because the egrep takes too long if ms is appending to previous log files#define ERR_FILE "tmt.err" // any ms error or warning msgs are accumulated in here, if LOG_ERRS is defined to 1#define LSLEN 1024 // long stringstypedef struct tTmtTab { int fPlaySoundWhenDone; char sPrefix[SLEN]; // string prepended to model name int nFilesPerTest; // -ni parameter for sMsParam0, sMsParam1, sMsParam2 int nRand; // -nr parameter bool fUseMirroredFiles; // modify file spec to include/exclude mirrored files char *sMsPParam; // -P param for ms char *sProlog; // execute this command before starting bool fAr, fBioId, fXm2vts; // run tests for each of these? bool fSkipBuildIfAsmFileExists; // if true, doesn't do masm -o FILENAME if FILENAME already exists char *sBuild; // %s parameter is test name (created internally from sPrefix sNew0 sNew1) char *sRefTest; // no parameters char *sTest; // %s parameter is test name (created internally from sPrefix sNew0 sNew1) // the 5 defs below are are used only if sed is invoked i.e. only if sFile is not "" char *sFile; // file to change: sed results go to this file char *sSedPrefix; char *sSedPrefixReplace; char *sTouch; // files to "touch": use "" for none, can have more than one file separated by spaces char *sMake; // %s parameter is RELEASE char *sOld[N_OLD]; char *sNew[N_NEW]; char **pNew[N_OLD]; }tTmtTab;#include "tmt.hpp" // include parameters for this specific test set#define USE_PREFIX_IN_MODEL_NAME 0#define USE_PARAMS_IN_MODEL_NAME 1static bool fgNeedToRestoreModifiedFile = false;static bool fgRun = false;static int __cdecl System(bool fRun, int iRetCodeHandler, char *pArgs, ...);//-----------------------------------------------------------------------------static void MyShutdown (void){if (fgRun) { if (fgNeedToRestoreModifiedFile) { lprintf("Restoring %s ", gTab.sFile); System(true, 0, "cp %s %s", TMP_FILE, gTab.sFile); fgNeedToRestoreModifiedFile = false; } else lprintf("No need to restore files\n"); unlink(SED_FILE); // remove working files, may not be necessary in which it is harmless unlink(TMP_FILE); unlink(SEMA_FILE);#if LOG_ERRS unlink(ERR_FILE);#endif }Shutdown();}//-----------------------------------------------------------------------------// User interrupt (hit Control C or caused SIGINT in some other way).static void __cdecl IntHandler (int Dummy){if (!fgUserInt) { fgUserInt = true; lprintf("\nUser Interrupt\n"); MyShutdown(); exit(-1); }}//-----------------------------------------------------------------------------// Print an error message and exit.// This puts a \n on the msg so you shouldn't.void __cdecl MyErr (const char *pArgs, ...) // args like printf{static bool fInHere;va_list pArg;if (fInHere) // if already in here then just exit printf("\nRecursive call to Err\n");else { fInHere = true; char *s = (char *)malloc(CONF_nMaxPrintfLen); va_start(pArg, pArgs); vsprintf(s, pArgs, pArg); va_end(pArg); printf("\n%s\n", s); fflush(stdout); // unneeded under Win98 but needed under WinXP logprintf("\nErr: %s\n", s); // allows easy post processing of log file: grep for "MyErr:"#if _DEBUG if (CONF_fAbortOnErr) EnterDebugger;#endif MyShutdown(); free(s); }exit(-1);}//-----------------------------------------------------------------------------// Execute the command giben in pArgs, if the fRun flag is true// If pArgs is "" or NULL then no command is executed//// We echo the command unless the first char of pArgs is @//// If the command returns <0 then we always print a msg and terminate//// If the command returns >0 then we// iRetCodeHandler=0 print msg and terminate// iRetCodeHandler=1 print msg but otherwise ignore// iRetCodeHandler=2 ignore//// If this routine returns, it returns with the value returned by the executed commandstatic int __cdecl System (bool fRun, int iRetCodeHandler, char *pArgs, ...) // arguments like printf{int iRet = 0;if (pArgs && pArgs[0]) { char s[LSLEN]; va_list pArg; va_start(pArg, pArgs); vsprintf(s, pArgs, pArg); va_end(pArg); int iOffset = 0; if (s[0] == '@') iOffset = 1; if (s[0] != '@' || !fRun) lprintf(">%s\n", s); if (fRun) { iRet = system(s+iOffset); char *sCmd = strtok(s, " \t"); if (iRet < 0) switch (errno) { case E2BIG: MyErr("%s: argument list is too big", sCmd); // MyErr() never returns case ENOENT: MyErr("%s: can't find command interpreter", sCmd); case ENOEXEC: MyErr("%s: command has invalid format", sCmd); case ENOMEM: MyErr("%s: out of memory", sCmd); default: MyErr("%s returned %d, errno %d", sCmd, iRet, errno); } else if (iRet) switch (iRetCodeHandler) // see function header for iRetCodeHandler definitions { case 0: MyErr("%s returned %d", sCmd, iRet); case 1: lprintf("\n%s returned %d (ignoring)\n", sCmd, iRet); case 2: break; // ignore default: MyErr("System: bad iRetCodeHandler %d", iRet); } } }return iRet;}//-----------------------------------------------------------------------------// Auxilary function for CreateSedFilestatic void CreateSedFileAux (bool fRun, FILE *pFile, const char sSedPrefix[], const char sSedPrefixReplace[], const char sOld[], const char sNew[]){char s[LSLEN];// replace everything from sOld to end of line with "sOld sNew"sprintf(s, "s/%s%s[ \t].*/%s%s %s/g", sSedPrefix, sOld, sSedPrefixReplace, sOld, sNew);if (fRun) Fprintf(pFile, "%s\n", s);else lprintf("SED %s\n", s);}//-----------------------------------------------------------------------------static void CreateSedFile (bool fRun, const char sSedFile[], // in const char sSedPrefix[], const char sSedPrefixReplace[], // in const char sOld0[], const char sNew0[], // in const char sOld1[], const char sNew1[]) // in{FILE *pFile;if (fRun) pFile = Fopen(sSedFile, "w");CreateSedFileAux(fRun, pFile, sSedPrefix, sSedPrefixReplace, sOld0, sNew0);if (sOld1[0]) CreateSedFileAux(fRun, pFile, sSedPrefix, sSedPrefixReplace, sOld1, sNew1);if (fRun) fclose(pFile);}//-----------------------------------------------------------------------------// In the file name part of s, strip characters that aren't valid filename chars// This allows us to use arbitary C expression for subsitute strings in gTab.sNewstatic char *sConvertFilename (const char s[]){static char sNewPath[LSLEN];char sNewFilename[LSLEN];char sDrive[_MAX_DRIVE], sDir[_MAX_DIR], sFname[_MAX_FNAME], sExt[_MAX_EXT];_splitpath(s, sDrive, sDir, sFname, sExt);int j = 0;for (int i = 0; sFname[i]; i++) { int c = sFname[i]; if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c=='.' || c=='(' || c==')' || c=='+' || c=='~' || c=='!' || c=='{' || c=='}' || c=='=' || c=='_' || c==',' || c=='-' || c=='+') sNewFilename[j++] = c; }sNewFilename[j] = 0;_makepath(sNewPath, sDrive, sDir, sNewFilename, sExt);return sNewPath;}//-----------------------------------------------------------------------------static const char *sGetModelName (const char sPrefix[], const char sNew0[], const char sNew1[], const char sParam1[], const char sParam2[]){static char s[LSLEN];char sParam1Temp[SLEN]; sParam1Temp[0] = 0;char sParam2Temp[SLEN]; sParam2Temp[0] = 0;#if USE_PARAMS_IN_MODEL_NAMEint i = 0;if (strlen(sParam1) > 5 && sParam1[0] == 'C' && sParam1[1] == 'O') i = 5; // strip "CONF_" prefixsprintf(sParam1Temp, "%s=", &sParam1[i]);i = 0;if (strlen(sParam2) > 5 && sParam2[0] == 'C' && sParam2[1] == 'O') i = 5;sprintf(sParam2Temp, "%s=", &sParam2[i]);#endifif (sNew1 && sNew1[0]) sprintf(s, "%s%s-%s%s", sParam1Temp, sNew0, sParam2Temp, sNew1);else sprintf(s, "%s%s", sParam1Temp, sNew0);#if USE_PREFIX_IN_MODEL_NAMEif (sNew1 && sNew1[0]) { strcat(s, "-"); strcat(s, sPrefix); }#endifreturn sConvertFilename(s);}//-----------------------------------------------------------------------------static void Separator (void){lprintf("-------------------------------------------------------------------------------\n");}//-----------------------------------------------------------------------------static void CheckFileExists (const char sFile[]){FILE *pFile = fopen(sFile, "r");if (pFile) fclose(pFile);else lprintf("NO FILE %s\n", sFile);}//-----------------------------------------------------------------------------static bool fFileExists (const char sFile[]){FILE *pFile = fopen(sFile, "r");if (pFile) fclose(pFile);//lprintf("\nfFileExists(%s) %d\n", sFile, pFile != NULL);return pFile != NULL;}//-----------------------------------------------------------------------------static void CheckCmdParams (bool fRun, const char sCmd[], bool fCheckLast){if (!fRun) { char *sWhiteSpace = " \t"; char sCmd1[LSLEN]; strcpy(sCmd1, sCmd); char *sToken = strtok(sCmd1, sWhiteSpace); char s[LSLEN]; sprintf(s, "%s.exe", sToken); CheckFileExists(s); char *sLast; while (sToken = strtok(NULL, sWhiteSpace)) { if (0 == strcmp(sToken, "-m") || 0 == strcmp(sToken, "-r")) { sToken = strtok(NULL, sWhiteSpace); CheckFileExists(sToken); } sLast = sToken; } if (fCheckLast) CheckFileExists(sLast); }}//-----------------------------------------------------------------------------// This only works if you run this program in a command window, not under epsilonstatic void PossiblyPause (void){#define ESC 0x1bif (_kbhit()) { lprintf("\nKBHIT\n"); int c = _getch(); lprintf("\n'%c'\n", c); if (ESC == c) { lprintf("PAUSED "); while (1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -