📄 trsapi.c
字号:
}
va_end(argptr);
return sepno; /* no of used seps */
}
TRSFUN(int, BracketsParse,(char *buf,char br0,char br1,char *prefix,char *expr,char * suffix)){
int i,j;
int res=-1; /* -1 if any NULL pointer */
int level;
if ((buf) && (prefix) && (expr) && (suffix)) {
for (i=0;((buf[i]!=0) && (buf[i]!=br0));) { /* Copy prefix until br0 */
prefix[i]=buf[i];i=i+1;
}
prefix[i]=0;
for (j=0,level=0;buf[i]!=0;) { /* Copy expr until pair br1 */
if (buf[i]==br1) level=level-1;
if (level>0) {expr[j]=buf[i];j=j+1;}
if (buf[i]==br0) level=level+1;
i=i+1;
if (level==0) break;
}
expr[j]=0; res=level;
for (j=0;buf[i]!=0;i=i+1) { /* copy rest of buf to suffix*/
suffix[j]=buf[i];
j=j+1;
}
suffix[j]=0;
}
return res;
}
static void* Reverse(void* Start){
typedef struct _listtype { struct _listtype *next;} listtype;
listtype *oldlist=(listtype*)Start;
listtype *newlist=NULL, *elem;
while(oldlist) {
elem=oldlist;
oldlist=oldlist->next;
elem->next=newlist;
newlist=elem;
}
return newlist;
}
/* ==========================================================================*/
TRSFUN(int, _trsReg,(char *FuncName, char *TestName,
char *TestClass,TRSProc_t Test, char *FuncCall,
char *File, int Line)) {
return _trsRegArg(FuncName,TestName,TestClass,
(TRSProcArg_t)Test,NULL, FuncCall,File,Line,0);
}
TRSFUN(int, _trsRegArg,(char *FuncName, /* lib Function name */
char *TestName, /* Brief test explanation */
char *TestClass, /* Name of test class */
TRSProcArg_t Test, /* t_ Function test */
void *Arg, /* Pointer to test data */
char *FuncCall, /* Test ascii name */
char *File, /* File, where is the test */
int Line, /* Start line of the test */
int Status)) /* Test reg status */
{
TRSid_t *ptr=NULL; /* =NULL for bcpro only */
TRSid_t *scan;
if (!RunMode && !ptr) {
ptr =(TRSid_t*)malloc(sizeof(TRSid_t));
ptr->funcname = FuncName;
ptr->testname = TestName;
ptr->testclass = TestClass;
ptr->proctext = FuncCall;
ptr->file = File;
ptr->line = Line;
ptr->test = Test;
ptr->arg = Arg;
ptr->status = Status;
ptr->infotext = NULL;
ptr->next = NULL;
if (TestList==NULL)
TestList=ptr;
else {
scan=TestList;
while ((scan->next) !=NULL) scan=scan->next;
scan->next=ptr;
};
};
return RunMode;
}
/* ==========================================================================*/
TRSFUN(void, trsMoreSize,(int i)) {
Trs_PageSize=i;
CurrLine=1;
}
static void DeleteComments(void) {
CommentsType *ptr;
while (CommentList) { /* Release test reg memory */
ptr=CommentList;
CommentList=CommentList->next;
if (ptr->comment) free(ptr->comment);
free(ptr);
}
CommentStatus=COMMENT_EMPTY;
}
/* Registrate some additional text */
static const char* trsComment(const char *format,...){
va_list argptr;
int res;
char buf[1024];
CommentsType *ptr;
va_start(argptr,format);
res=vsprintf(buf,format,argptr);
va_end(argptr);
if (res>sizeof(buf)) exit(0);
if (CommentStatus==COMMENT_READY) DeleteComments();
CommentStatus=COMMENT_STORING;
ptr =(CommentsType*)trsmAlloc(sizeof(CommentsType));
ptr->comment=StringDup(buf);
ptr->next = CommentList;
CommentList=ptr;
return ptr->comment;
}
static int putnchar(int ch,int n) {
for (;n>0;n=n-1) putchar(ch);
return ch;
}
static char * TimeString(double dTime) {
time_t ltime,htime,mtime,stime;
static char timestr[]="00:00:00";
ltime=(time_t) (dTime+0.5);
htime=ltime/3600;
if (htime>99) htime=99;
mtime=(ltime % 3600) /60;
stime=(ltime % 60);
sprintf(timestr,"%ld%ld:%ld%ld:%ld%ld",htime/10,htime%10,
mtime/10,mtime%10,stime/10,stime%10);
return timestr;
}
static void trsPrintHeader(TRSid_t *ptr,int header) {
int lt=201,rt=187,lb=200,rb=188,v=186,h=205;
if (header) {
lt=218;rt=191;lb=192;rb=217;v=179;h=196;
}
putchar(lt);putnchar(h,77);printf("%c\n",rt);
printf("%c<f>unction : %-63s%c\n",v,ptr->funcname,v);
printf("%c<t>est : %-63s%c\n",v,ptr->testname,v);
if (header)
printf("%c<c>lass : %-63s%c\n",v,ptr->testclass,v);
else {
printf("%c<c>lass : %-43s %s/",v,ptr->testclass,
TimeString(difftime(time(NULL),TestTime)));
printf("%s %c\n",
TimeString(difftime(time(NULL),TotalTime)),v);
}
printf("%c<T>est body : %-44s line: %-12d%c\n",v,ptr->proctext,ptr->line,v);
printf("%c<S>ource : %-63s%c\n",v,ptr->file,v);
if (header) {
putchar(lb);putnchar(h,77);printf("%c\n",rb);
} else {
printf("%c<R>esult : ",v);
if (ResultString) {
printf("%-55s",ResultString);
ResultString=(char*)trsFree(ResultString);
} else
printf("%-55s"," ");
switch (TestResult) {
case TRS_UNDEF: printf(" ");break;
case TRUE : printf(" OK");break;
case FALSE : printf(" FAIL");break;
default : printf("%-7d",TestResult);break;
}
printf(" %c\n",v);
}
}
static void trsPrintFooter(TRSid_t *ptr) {
CommentsType *cptr;
FILE *oldLstFile=LstFile;
char buf[1024],comment[1024];
int newline;
int trailspaces=77;
const char *summary;
int printsum;
summary=trsGetKeyArg('R');
if (summary)
printsum=((!strcmp(summary,"OK" )) && (TestResult==TRS_OK )) ||
((!strcmp(summary,"FAIL")) && (TestResult==TRS_FAIL));
else
printsum=TRUE;
if (printsum) {
if (SumFile) {
LstFile=SumFile;
/* trs_FlushAll();*/
}
trsPrintHeader(ptr,0);
if (CommentStatus!=COMMENT_EMPTY) {
if (CommentStatus==COMMENT_STORING)
CommentList=(CommentsType*)Reverse(CommentList);
CommentStatus=COMMENT_READY;
cptr=CommentList;
putchar(199);putnchar(196,77);putchar(182);putchar(LF);
newline=1;
while (cptr) {
if (cptr->comment) {
StringnCpy(buf,cptr->comment,sizeof(buf));
while (buf[0]!=0) {
if (newline) { putchar(186);trailspaces=77;}
newline=StrParse2(buf,"\n",comment,buf);
trailspaces=trailspaces-strlen(comment);
printf("%s",comment);
if (newline) {
if (trailspaces>0) putnchar(' ',trailspaces);
putchar(186);putchar(LF);
}
}
}
cptr=cptr->next;
}
}
putchar(200);putnchar(205,77);putchar(188);putchar(LF);
/* trs_FlushAll();*/
LstFile=oldLstFile;
}
trs_FlushAll();
}
static void WrLn(char *str) {
printf("%s\n",str);
}
static void FHlp(char *str) {
if (FullHelp) WrLn(str);
}
static int CmdLineHelp(int fullhelp){
trsMoreSize(Trs_PageSize);
FullHelp=fullhelp;
____("-a name - ini file with answers");
____("");
WrLn("-B string - batch mode, substitute all reads from CON by 'string'");
FHlp(" -B - accept default (simulate <CR>)");
FHlp(" -B\";>\" - accept default and write to default sections");
FHlp(" -B\";>[.i486];>[.p5]\"- accept default, write to extended sections");
FHlp(" -B\";>[lib]\" - accept default, write to absolute section");
FHlp(" -B -D\"*<\" - data from file, if no data, simulate <CR>");
FHlp(" -B\"!e\" -D\"*<\" - data from file, if no data, then exit");
FHlp("");
WrLn("-c name - class, apply command to tests of class 'name'");
FHlp("");
FHlp(" test -c ? - list all classes of tests");
FHlp(" test -c Algorithm - run all tests with class 'Algorithm'");
____(" test -c a%b*f - all test classes with pattern 'a%b*f'");
FHlp("");
WrLn("-C name - name of .csv file for performance numbers");
FHlp("");
WrLn("-d - DEBUG mode, activate trsWrite(TW_DEBUG,...)");
FHlp("");
WrLn("-D string - define symbols through 'string'");
FHlp(" -D \"a=1;b=4.3;c=abcd.ext\"");
FHlp(" -D \"?h;?l;!e\" - print test help, listing and exit");
FHlp(" -D \"*<\" - ?Read from section [funcname.testclass.testbody]");
FHlp(" -D \"*<[]\" - ?Read from section [funcname.testclass.testbody]");
FHlp(" -D \"*<[.p5]\" - ?Read from ext section [funcname.testclass.testbody.p5]");
FHlp(" -D \"*<a.ini[lib]\" - ?Read from a.ini, absolute section [lib]");
FHlp("");
____("-e name - error file is 'name'");
____("");
WrLn("-f name - apply command to function with name 'name'");
FHlp("");
FHlp(" test -f ? - show functions list");
FHlp(" test -f libsAdd - run all tests for function 'libsAdd'");
____(" test -f %%%Add* - run all tests of function Add");
FHlp("");
____("-g name - generate answer file");
____(" test -f %%%Add* -g %%%Add* - run all tests of funct Add and generate");
____(" answer files");
____(" test -f %%%Add* -g %%%Add* -d \"*=?\" - run all tests of funct Add,");
____(" reinitialize all values from console and");
____(" generate answer files");
____(" test -f %%%Add* -g %%%Add* -b - run all tests of funct Add and generate");
____(" answer files in BLAS style");
____("");
WrLn("-h - short help");
FHlp("");
WrLn("-H - full help");
FHlp("");
WrLn("-i name - set current ini file name");
FHlp("");
____("-I - terminate interactive mode");
____("-j");
____("-k");
WrLn("-l name - listing(TW_LST), output to file 'name', default *.lst");
FHlp("");
WrLn("-L n - loop, repeat each test 'n' times");
FHlp("");
WrLn("-m n - more mode, n lines per page, if no 'n', more off,");
FHlp(" more prompt '--More--' can accept '!q'");
FHlp("");
____("-o name - output file is 'name'");
____("-q level - quiet mode, report only errors");
WrLn("-R result - print to .sum (-s) only tests with result=OK/FAIL");
FHlp("");
WrLn("-r n - RERUN Mode");
FHlp("");
FHlp(" test -r - force RERUN mode, activate trsWrite(TW_RERUN,...)");
FHlp(" test -r 2 - if test FAIL repeat test 2 times in RERUN Mode");
FHlp("");
WrLn("-s name - summary (TW_SUM), only test results, default *.sum");
FHlp("");
WrLn("-S name - source, apply command to tests in file 'name'");
FHlp("");
FHlp(" test -S ? - show all source files in test system");
FHlp(" test -S abcd.c - run all tests in source file 'abcd.c'");
FHlp("");
WrLn("-t name - testname, apply command to functions with testname 'name'");
FHlp("");
FHlp(" test -t ? - show testnames list");
FHlp(" test -t Test1 - run all tests with name 'Test1'");
____(" test -t %%%Add - test all implementations of Add function");
FHlp("");
WrLn("-T name - testbody, apply command to testbody 'name'");
FHlp("");
FHlp(" test -T ? - show testbodies list");
FHlp(" test -T trsbody - run all tests with bodyname 'trsbody'");
FHlp("");
____("-u");
____("");
____("-w");
____("-X name - exec file, apply command to tests in bin file 'name'");
____("");
____(" test -X ? - show all bin files in test system");
____(" test -X abcd.exe - run all tests in bin file 'abcd.exe'");
____("");
____("-y");
____("-z");
WrLn("-- string - any user defined string, key -- is equiv to -Z");
WrLn("");
return FALSE;
}
/* ==========================================================================*/
#define KEYARRSIZE 'z'-'?'+1
static char *KeyStr[KEYARRSIZE]; /* ==NullStr - set, but no arg */
/* !=NullStr - set, has arg */
/* ==NULL - key is not set */
static Bool_t KeyFlg[KEYARRSIZE]; /* FALSE - value is not available */
/* TRUE - value is available */
static char Ch;
static char *tmpBuf;
static char *cmdBuf;
static int tmpBufIdx, tmpBufLen;
static int cmdBufIdx, cmdBufLen;
/* --- Command line key values ----------------------------------------------*/
TRSFUN(const char *, trsGetKeyArg,(char key)) {
if (key=='-') key='Z'; /* convert -- to -Z */
if (((key>='a') && (key<='z')) || ((key>='?') && (key<='Z')))
return KeyStr[key-'?'];
return NULL;
}
static void KeysWithArg(char *s){
int i,len;
char ch;
len=strlen(s);
for (i=0;i<KEYARRSIZE;i=i+1) {
KeyFlg[i]=FALSE;
KeyStr[i]=NULL;
};
for (i=0;i<len;i=i+1) {
ch=s[i];
if (((ch>='a') && (ch<='z')) || ((ch>='?') && (ch<='Z')))
KeyFlg[ch-'?']=TRUE;
};
}
static int MayHasArg(char key) {
if ( (((key>='a') && (key<='z')) || ((key>='?') && (key<='Z'))) &&
(KeyFlg[key-'?']) ) return TRUE;
return FALSE;
}
static void InvalidKey(char key) {
switch (key) {
case ' ': printf("?-%s-Invalid command\n",TestID);break;
default : printf("?-%s-Invalid key -%c\n",TestID,key);
};
}
static void ResetKeyArgBuf(char *keyargbuf,int keybuflen){
tmpBuf=keyargbuf;
tmpBuf[0]=0;
tmpBufIdx=0;
tmpBufLen=keybuflen;
}
static void StoreCh(char ch){
if (tmpBufIdx<tmpBufLen-1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -