9#include "tpcclibConfig.h"
23static char *info[] = {
24 "Verify that the contents in two TAC files are similar.",
25 "This can be used for automating software and analysis tool testing.",
26 "By default exact match is required for numerical values, but this behavior",
27 "can be changed with options -rel and -abs (below); if both are set, then",
28 "values are considered to match is either of the requirements is met.",
29 "Programs return code is 0, if files were matching, 10, if the files did",
30 "not match, and 1-9 in case of error.",
32 "Usage: @P [options] filename1 filename2",
36 " X values (sample times) are checked (y, default) or not checked (n).",
38 " Y values (concentrations) are checked (y, default) or not checked (n).",
40 " Weights are checked (y) or not checked (n, default).",
42 " TAC names are checked (y) or not checked (n, default).",
44 " Time unit is checked (y) or not checked (n, default).",
46 " Concentration unit is checked (y) or not checked (n, default).",
48 " Absolute differences must not exceed the specified limit.",
50 " Relative differences must not exceed the specified percent limit.",
54 " @P data1.tac data2.tac",
56 " @P -abs=0.02 -rel=5 data1.dat data2.dat",
58 "See also: taclist, iftmatch, imgmatch",
60 "Keywords: TAC, tool, software testing",
79int main(
int argc,
char **argv)
81 int ai, help=0, version=0, verbose=1;
83 char *cptr, tacfile1[FILENAME_MAX], tacfile2[FILENAME_MAX];
98 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
100 tacfile1[0]=tacfile2[0]=(char)0;
102 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
104 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
105 if(strncasecmp(cptr,
"ABS=", 4)==0) {
106 test_abs=
atofVerified(cptr+4);
if(!isnan(test_abs))
continue;
107 }
else if(strncasecmp(cptr,
"REL=", 4)==0) {
108 test_rel=
atofVerified(cptr+4);
if(!isnan(test_rel))
continue;
109 }
else if(strcasecmp(cptr,
"X")==0) {
111 }
else if(strncasecmp(cptr,
"X=", 2)==0) {
113 if(strncasecmp(cptr,
"YES", 1)==0) {xvals=1;
continue;}
114 else if(strncasecmp(cptr,
"NO", 1)==0) {xvals=0;
continue;}
115 }
else if(strcasecmp(cptr,
"Y")==0) {
117 }
else if(strncasecmp(cptr,
"Y=", 2)==0) {
119 if(strncasecmp(cptr,
"YES", 1)==0) {yvals=1;
continue;}
120 else if(strncasecmp(cptr,
"NO", 1)==0) {yvals=0;
continue;}
121 }
else if(strncasecmp(cptr,
"W=", 2)==0) {
123 if(strncasecmp(cptr,
"YES", 1)==0) {wvals=1;
continue;}
124 else if(strncasecmp(cptr,
"NO", 1)==0) {wvals=0;
continue;}
125 }
else if(strcasecmp(cptr,
"XUNIT")==0) {
127 }
else if(strncasecmp(cptr,
"XUNIT=", 6)==0) {
129 if(strncasecmp(cptr,
"YES", 1)==0) {xunit=1;
continue;}
130 else if(strncasecmp(cptr,
"NO", 1)==0) {xunit=0;
continue;}
131 }
else if(strcasecmp(cptr,
"YUNIT")==0) {
133 }
else if(strncasecmp(cptr,
"YUNIT=", 6)==0) {
135 if(strncasecmp(cptr,
"YES", 1)==0) {yunit=1;
continue;}
136 else if(strncasecmp(cptr,
"NO", 1)==0) {yunit=0;
continue;}
137 }
else if(strcasecmp(cptr,
"TACNAMES")==0) {
138 tacnames=1;
continue;
139 }
else if(strncasecmp(cptr,
"TACNAMES=", 9)==0) {
141 if(strncasecmp(cptr,
"YES", 1)==0) {tacnames=1;
continue;}
142 else if(strncasecmp(cptr,
"NO", 1)==0) {tacnames=0;
continue;}
144 fprintf(stderr,
"Error: invalid option '%s'\n", argv[ai]);
149 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
154 for(; ai<argc; ai++) {
156 strlcpy(tacfile1, argv[ai], FILENAME_MAX);
continue;
157 }
else if(!tacfile2[0]) {
158 strlcpy(tacfile2, argv[ai], FILENAME_MAX);
continue;
160 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
165 if(!tacfile2[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
169 for(ai=0; ai<argc; ai++) printf(
"%s ", argv[ai]);
171 printf(
"tacfile1 := %s\n", tacfile1);
172 printf(
"tacfile2 := %s\n", tacfile2);
173 if(test_abs>=0.0) printf(
"test_abs := %g\n", test_abs);
174 if(test_rel>=0.0) printf(
"test_rel := %g\n", test_rel);
175 printf(
"xvals := %d\n", xvals);
176 printf(
"yvals := %d\n", yvals);
177 printf(
"wvals := %d\n", wvals);
178 printf(
"xunit := %d\n", xunit);
179 printf(
"yunit := %d\n", yunit);
180 printf(
"tacnames := %d\n", tacnames);
191 if(verbose>1) printf(
"\nreading %s\n", tacfile1);
192 ret=
tacRead(&tac1, tacfile1, &status);
194 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), tacfile1);
200 printf(
"tacNr := %d\n", tac1.
tacNr);
201 printf(
"sampleNr := %d\n", tac1.
sampleNr);
202 if(tac1.
isframe) printf(
"frames := yes\n");
else printf(
"frames := no\n");
205 if(verbose>1) printf(
"\nreading %s\n", tacfile2);
206 ret=
tacRead(&tac2, tacfile2, &status);
208 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), tacfile2);
214 printf(
"tacNr := %d\n", tac2.
tacNr);
215 printf(
"sampleNr := %d\n", tac2.
sampleNr);
216 if(tac2.
isframe) printf(
"frames := yes\n");
else printf(
"frames := no\n");
226 fprintf(stdout,
" sample numbers in %s and %s do not match.\n", tacfile1, tacfile2);
230 if(yvals && tacnames && tac1.
tacNr!=tac2.
tacNr) {
231 fprintf(stdout,
" TAC numbers in %s and %s do not match.\n", tacfile1, tacfile2);
241 if(verbose>0) printf(
"test units\n");
243 if(yunit && (ret==1 || ret==3)) {
244 fprintf(stdout,
" concentration units in %s and %s do not match.\n", tacfile1, tacfile2);
248 if(xunit && (ret==2 || ret==3)) {
249 fprintf(stdout,
" time units in %s and %s do not match.\n", tacfile1, tacfile2);
264 if(ret==
TPCERROR_OK) printf(
" sample time units converted.\n");
265 else printf(
" sample time units could not be converted.\n");
268 if(verbose>0) printf(
"test sample times\n");
270 fprintf(stdout,
" time samples in %s and %s do not match.\n", tacfile1, tacfile2);
285 if(ret==
TPCERROR_OK) printf(
" concentration units converted.\n");
286 else printf(
" concentration units could not be converted.\n");
289 if(verbose>0) printf(
"test sample concentrations\n");
290 if(
tacCompareConc(&tac1, &tac2, -1, test_abs, 0.01*test_rel, &status)) {
291 fprintf(stdout,
" concentrations in %s and %s do not match.\n", tacfile1, tacfile2);
302 if(verbose>0) printf(
"test sample weights\n");
304 fprintf(stdout,
" weights in %s and %s do not match.\n", tacfile1, tacfile2);
315 if(verbose>0) printf(
"test tac names\n");
317 fprintf(stdout,
" TAC names in %s and %s do not match.\n", tacfile1, tacfile2);
327 fprintf(stderr,
"Error: no tests applied.\n");
329 }
else if(verbose>=0)
330 fprintf(stdout,
"Match was found.\n");
double atofVerified(const char *s)
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
void statusInit(TPCSTATUS *s)
char * errorMsg(tpcerror e)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacCompareWeights(TAC *d1, TAC *d2, const double test_abs, const double test_rel, TPCSTATUS *status)
int tacCompareNames(TAC *d1, TAC *d2, const int i, TPCSTATUS *status)
int tacCompareTimes(TAC *d1, TAC *d2, const double test_abs, const double test_rel, TPCSTATUS *status)
int tacCompareConc(TAC *d1, TAC *d2, const int i, const double test_abs, const double test_rel, TPCSTATUS *status)
int tacCompareUnit(TAC *d1, TAC *d2, TPCSTATUS *status)
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
char * tacFormattxt(tacformat c)
int tacYUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Header file for library libtpcextensions.
Header file for library libtpcift.
Header file for library libtpctac.