27 #include "cantera/base/config.h"
37 #if defined(__CYGWIN__)
43 #include "tok_input_util.h"
45 int Debug_Flag =
true;
46 double grtol = 1.0E-3;
47 double gatol = 1.0E-9;
50 #define RT_FAILED_COL 1
51 #define RT_FAILED_HDR 2
52 #define RT_FAILED_OTHER 3
57 int Max_Input_Str_Ln = MAX_INPUT_STR_LN;
70 int getopt(
int argc,
char** argv,
const char*)
72 static int currArg = 1;
73 static int currOptInd = 1;
75 static int charPos = 0;
77 if (currArg >= argc) {
81 tok = string(argv[currArg]);
82 currOptInd = currArg+1;
83 if (currOptInd > argc - 1) {
87 optarg = argv[currArg+1];
89 size_t len = strlen(tok.c_str());
93 tok = string(argv[currArg]);
94 len = strlen(tok.c_str());
95 if (len > 1 && tok[0] ==
'-') {
98 if (len > 2 && tok[1] ==
'-') {
107 if (currArg < (argc-1)) {
118 if (charPos < static_cast<int>(len - 1)) {
132 static int diff_double(
double d1,
double d2,
double rtol,
double atol)
139 if (fabs(d1-d2) > (atol + rtol * 0.5 * (fabs(d1) + fabs(d2)))) {
145 static int diff_double_slope(
double d1,
double d2,
double rtol,
146 double atol,
double xtol,
double slope1,
double slope2)
153 double atol2 = xtol*(fabs(slope1) + fabs(slope2));
154 if (fabs(d1-d2) > (atol + atol2 + rtol * 0.5 * (fabs(d1) + fabs(d2)))) {
164 static double calc_rdiff(
double d1,
double d2,
double rtol,
double atol)
173 lhs = atol + rtol * 0.5 * (fabs(d1) + fabs(d2));
195 static int breakStrCommas(
char* str,
char** strlets,
int maxPieces)
204 cetn = strchr(cptr, (
int)
',');
208 strlets[numbreaks] = cptr;
211 }
while (cetn && (numbreaks < (maxPieces - 1)));
214 return numbreaks + 1;
227 static void check_consistency(FILE* fp,
const char *fileName,
const int nTitleLines,
const int nColTitleLines,
228 const int nCol,
const int nDataRows,
const std::vector<int>& ColIsFloat)
230 int retn, ncolsFound;
233 char* scanLine = mdp_alloc_char_1(MAX_INPUT_STR_LN+1,
'\0');
234 char** strlets = (
char**) mdp_alloc_ptr_1(nCol+200);
240 for (
int i = 0; i < nTitleLines; i++) {
241 retn = read_line(fp, scanLine, 0);
243 fprintf(stderr,
"check_consistency() error for file %s, Line %d couldn't be read\n",
248 if (nColTitleLines == 0) {
249 if (nTitleLines > 0) {
250 fprintf(stderr,
"check_consistency() error for file %s, number column title lines are zero but number title lines are greater than 0",
255 for (
int i = 0; i < nColTitleLines; i++) {
256 retn = read_line(fp, scanLine, 0);
258 fprintf(stderr,
"check_consistency() error for file %s, Line %d couldn't be read\n",
262 ncolsFound = breakStrCommas(scanLine, strlets, nCol);
263 if (ncolsFound != (nCol)) {
264 fprintf(stderr,
"check_consistency() error for file %s, Line %d of "
265 "ColTitleLines didn't have correct commas: %d vs %d\n", fileName, i, ncolsFound, nCol);
266 fprintf(stderr,
" %s\n", scanLine);
269 for (
int i = 0; i < nDataRows; i++) {
270 retn = read_line(fp, scanLine, 0);
271 ncolsFound = breakStrCommas(scanLine, strlets, nCol);
273 fprintf(stderr,
"check_consistency() error for file %s, Line %d couldn't be read\n",
277 if (ncolsFound != (nCol)) {
278 fprintf(stderr,
"check_consistency() error for file %s, Line %d of DataLines didn't have correct commas: %d vs %d\n",
279 fileName, i, ncolsFound, nCol);
280 fprintf(stderr,
" %s\n", scanLine);
283 for (
int j = 0; j < ncolsFound; j++) {
284 char* fieldStr = strlets[j];
285 fillTokStruct(&fieldToken, fieldStr);
286 if (ColIsFloat[j] > 0) {
287 (void) tok_to_double(&fieldToken, DBL_MAX, -DBL_MAX, 0.0, &rerr);
289 fprintf(stderr,
"check_consistency() error for file %s, Line %d of DataLines, col %d, "
290 "couldn't be converted to a double\n",
292 fprintf(stderr,
" %s\n", scanLine);
298 mdp_safe_free((
void**) &strlets);
299 mdp_safe_free((
void**) &scanLine);
302 #define LT_NULLLINE 0
303 #define LT_TITLELINE 1
304 #define LT_COLTITLE 2
305 #define LT_DATALINE 3
325 static void get_sizes(FILE* fp,
int& nTitleLines,
int& nColTitleLines,
326 int& nCol,
int& nDataRows, std::vector<int>& ColIsFloat)
328 int nScanLinesMAX = 100;
329 int nScanLines = nScanLinesMAX;
333 char* scanLine = mdp_alloc_char_1(MAX_INPUT_STR_LN+1,
'\0');
334 int* numCommas = mdp_alloc_int_1(nScanLinesMAX, -1);
343 for (i = 0; i < nScanLinesMAX; i++) {
344 retn = read_line(fp, scanLine, 0);
353 int ccount =
static_cast<int>(strlen(scanLine));
355 if (scanLine[ccount-1] ==
',') {
356 scanLine[ccount-1] =
'\0';
362 char* cptr = scanLine;
366 cetn = strchr(cptr, (
int)
',');
373 if (maxCommas < numCommas[i]) {
374 maxCommas = numCommas[i];
377 maxCommas = numCommas[0];
383 nCol = maxCommas + 1;
384 if (nScanLines == 0) {
387 char** strlets = (
char**) mdp_alloc_ptr_1(maxCommas+1);
389 if (ColIsFloat.size() < maxCommas+1) {
390 ColIsFloat.resize(maxCommas+1);
397 ColIsFloat.assign(ColIsFloat.size(), 0);
399 for (i = 0; i < nScanLines; i++) {
400 retn = read_line(fp, scanLine, 0);
401 int ncolsFound = breakStrCommas(scanLine, strlets, nCol);
402 if (ncolsFound == (maxCommas + 1)) {
403 for (j = 0; j < ncolsFound; j++) {
404 char* fieldStr = strlets[j];
405 fillTokStruct(&fieldToken, fieldStr);
406 if (fieldToken.ntokes != 1) {
410 (void) tok_to_double(&fieldToken, DBL_MAX, -DBL_MAX, 0.0, &rerr);
417 std::vector<int>::iterator it;
418 it = std::max_element(ColIsFloat.begin(), ColIsFloat.end());
420 it = std::min_element(ColIsFloat.begin(), ColIsFloat.end());
424 for (j = 0; j < maxCommas + 1; j++) {
425 if (ColIsFloat[j] != maxFloats) {
426 if (ColIsFloat[j] == minFloats) {
428 if (ColIsFloat[j] > 0) {
432 printf(
"WARNING: type of column %d couldn't be uniquely determined, assuming text\n", j);
440 int doingLineType = LT_TITLELINE;
441 if (nScanLines == 2) {
443 doingLineType = LT_COLTITLE;
448 for (i = 0; i < nScanLines; i++) {
449 retn = read_line(fp, scanLine, 0);
454 int ccount =
static_cast<int>(strlen(scanLine));
456 if (scanLine[ccount-1] ==
',') {
457 scanLine[ccount-1] =
'\0';
460 int ncolsFound = breakStrCommas(scanLine, strlets, nCol);
462 if (doingLineType == LT_TITLELINE) {
463 if (numCommas[i] == maxCommas) {
464 doingLineType = LT_COLTITLE;
469 if (doingLineType == LT_COLTITLE) {
470 bool goodDataLine =
true;
472 for (j = 0; j < ncolsFound; j++) {
473 char* fieldStr = strlets[j];
474 fillTokStruct(&fieldToken, fieldStr);
475 if (fieldToken.ntokes != 1) {
476 goodDataLine =
false;
479 if ((ColIsFloat[j]) > 0) {
480 (void) tok_to_double(&fieldToken, DBL_MAX, -DBL_MAX, 0.0, &rerr);
482 goodDataLine =
false;
488 doingLineType = LT_DATALINE;
490 nColTitleLines = i - nTitleLines;
492 if (doingLineType == LT_DATALINE) {
501 if (doingLineType == LT_DATALINE) {
502 for (i = nColTitleLines + nTitleLines; ; i++) {
503 retn = read_line(fp, scanLine, 0);
505 nDataRows = i - nColTitleLines - nTitleLines + 1;
512 int ccount =
static_cast<int>(strlen(scanLine));
514 if (scanLine[ccount-1] ==
',') {
515 scanLine[ccount-1] =
'\0';
518 int ncolsFound = breakStrCommas(scanLine, strlets, nCol);
519 bool goodDataLine =
true;
521 for (j = 0; j < ncolsFound; j++) {
522 char* fieldStr = strlets[j];
523 fillTokStruct(&fieldToken, fieldStr);
524 if (fieldToken.ntokes != 1) {
525 goodDataLine =
false;
528 if (ColIsFloat[j] > 0) {
529 (void) tok_to_double(&fieldToken, DBL_MAX,
530 -DBL_MAX, 0.0, &rerr);
532 goodDataLine =
false;
537 if (! goodDataLine) {
538 doingLineType = LT_NULLLINE;
539 nDataRows = i - nColTitleLines - nTitleLines + 1;
544 mdp_safe_free((
void**) &strlets);
545 mdp_safe_free((
void**) &scanLine);
546 mdp_safe_free((
void**) &numCommas);
555 read_title(FILE* fp,
char** *title,
int nTitleLines)
558 *title = (
char**) mdp_alloc_ptr_1(nTitleLines);
559 char* scanLine = mdp_alloc_char_1(Max_Input_Str_Ln + 1,
'\0');
560 for (
int i = 0; i < nTitleLines ; i++) {
561 retn = read_line(fp, scanLine, 0);
567 int ccount =
static_cast<int>(strlen(scanLine));
569 if (scanLine[ccount-1] ==
',') {
570 scanLine[ccount-1] =
'\0';
573 (*title)[i] = mdp_copy_string(scanLine);
576 mdp_safe_free((
void**) &scanLine);
584 read_colTitle(FILE* fp,
char**** ColMLNames_ptr,
int nColTitleLines,
int nCol)
587 *ColMLNames_ptr = (
char***) mdp_alloc_ptr_1(nCol);
588 char** *ColMLNames = *ColMLNames_ptr;
589 char* scanLine = mdp_alloc_char_1(Max_Input_Str_Ln + 1,
'\0');
590 char** strlets = (
char**) mdp_alloc_ptr_1(nCol+1);
591 if (nColTitleLines > 0) {
592 for (
int i = 0; i < nColTitleLines ; i++) {
593 retn = read_line(fp, scanLine, 0);
599 int ccount =
static_cast<int>(strlen(scanLine));
601 if (scanLine[ccount-1] ==
',') {
602 scanLine[ccount-1] =
'\0';
605 int ncolsFound = breakStrCommas(scanLine, strlets, nCol);
606 ColMLNames[i] = mdp_alloc_VecFixedStrings(nCol, MAX_TOKEN_STR_LN+1);
607 for (j = 0; j < ncolsFound; j++) {
609 strcpy(ColMLNames[i][j], strlets[j]);
614 ColMLNames[0] = mdp_alloc_VecFixedStrings(nCol, MAX_TOKEN_STR_LN+1);
615 for (j = 0; j < nCol; j++) {
617 sprintf(cbuff,
"Col_%d", j+1);
618 strcpy(ColMLNames[0][j], cbuff);
621 mdp_safe_free((
void**) &scanLine);
622 mdp_safe_free((
void**) &strlets);
629 static double get_atol(
const double* values,
const int nvals,
633 double sum = 0.0, retn;
637 for (i = 0; i < nvals; i++) {
643 return (retn + 1.0) * atol;
651 read_values(FILE* fp,
double** NVValues,
char** *NSValues,
int nCol,
int nDataRows,
652 std::vector<int>& ColIsFloat)
654 char** strlets = (
char**) mdp_alloc_ptr_1(nCol+1);
655 char* scanLine = mdp_alloc_char_1(Max_Input_Str_Ln + 1,
'\0');
659 for (
int i = 0; i < nDataRows; i++) {
660 retn = read_line(fp, scanLine, 0);
668 int ccount =
static_cast<int>(strlen(scanLine));
670 if (scanLine[ccount-1] ==
',') {
671 scanLine[ccount-1] =
'\0';
674 int ncolsFound = breakStrCommas(scanLine, strlets, nCol);
675 bool goodDataLine =
true;
677 for (j = 0; j < ncolsFound; j++) {
678 char* fieldStr = strlets[j];
679 NSValues[j][i] = mdp_copy_string(strlets[j]);
680 fillTokStruct(&fieldToken, fieldStr);
681 if (fieldToken.ntokes != 1) {
682 goodDataLine =
false;
686 value = tok_to_double(&fieldToken, DBL_MAX,
687 -DBL_MAX, 0.0, &rerr);
689 goodDataLine =
false;
692 NVValues[j][i] = value;
695 if (! goodDataLine) {
699 mdp_safe_free((
void**) &strlets);
700 mdp_safe_free((
void**) &scanLine);
706 static void print_usage()
709 printf(
" csvdiff [-h] [-a atol] [-r rtol] File1.csv File2.csv\n");
711 printf(
"\tCompares the variable values in two Excel formatted "
712 "comma separated files.\n");
713 printf(
"\tThe comparison is done using a weighted norm basis.\n");
715 printf(
"\tThe two files should be basically equal. However, File1.csv is\n");
716 printf(
"\ttaken as the reference file that has precedence, when there is\n");
717 printf(
"\tsomething to be decided upon.\n");
719 printf(
"\t Arguments:\n");
720 printf(
"\t -h = Usage info\n");
721 printf(
"\t -a atol = Set absolute tolerance parameter - default = 1.0E-9\n");
722 printf(
"\t -r rtol = Set relative tolerance parameter - default = 1.0E-3\n");
724 printf(
"\t Shell Return Values:\n");
725 printf(
"\t 0 = Comparison was successful\n");
726 printf(
"\t 1 = One or more nodal values failed the comparison\n");
727 printf(
"\t 2 = One or more header values failed the comparison\n");
728 printf(
"\t 3 = Apples to oranges, the files can not even be compared against\n");
729 printf(
"\t one another.\n");
736 int main(
int argc,
char* argv[])
743 char* fileName1=NULL, *fileName2=NULL;
744 FILE* fp1=NULL, *fp2=NULL;
745 int nTitleLines1 = 0, nTitleLines2 = 0;
746 int nColTitleLines1 = 0, nColTitleLines2 = 0;
747 int nCol1 = 0, nCol2 = 0, nColMAX = 0, nColcomparisons = 0;
748 int nDataRows1 = 0, nDataRows2 = 0;
749 char** title1 = 0, **title2 = 0;
750 int** compColList = NULL;
751 char** *ColMLNames1 = NULL, *** ColMLNames2 = NULL;
752 char** ColNames1 = NULL, **ColNames2 = NULL;
753 double** NVValues1 = NULL, **NVValues2 = NULL;
754 char** *NSValues1 = NULL, *** NSValues2 = NULL;
755 std::vector<int> ColIsFloat1;
756 std::vector<int> ColIsFloat2;
757 double* curVarValues1 = NULL, *curVarValues2 = NULL;
758 char** curStringValues1 = NULL, **curStringValues2 = NULL;
759 int i, j, ndiff, jmax=0, i1, i2, k;
761 double max_diff, rel_diff;
762 int testPassed = RT_PASSED;
763 double atol_j, atol_arg = 0.0, rtol_arg = 0.0;
774 while ((opt_let = getopt(argc, argv,
"ha:r:")) != EOF) {
789 id = sscanf(ggg,
"%lg", &atol_arg);
791 printf(
" atol param bad: %s\n", ggg);
802 id2 = sscanf(rrr,
"%lg", &rtol_arg);
804 printf(
" rtol param bad: %s\n", rrr);
813 printf(
"default called opt_let = %c\n", opt_let);
814 fprintf(stderr,
"ERROR in command line usuage:\n");
821 if (optind != argc-2) {
825 fileName1 = argv[argc-2];
826 fileName2 = argv[argc-1];
833 printf(
"----------------------------------------------------------\n");
834 printf(
"csvdiff: CSVFile comparison utility program\n");
835 printf(
" Harry K. Moffat Div. 9114 Sandia National Labs\n");
837 printf(
" First CSV File = %s\n", fileName1);
838 printf(
" Second CSV file = %s\n", fileName2);
840 printf(
" Absolute tol = %g\n", gatol);
841 printf(
" Relative tol = %g\n", grtol);
842 printf(
"----------------------------------------------------------\n");
848 if (!(fp1 = fopen(fileName1,
"r"))) {
849 fprintf(stderr,
"Error opening up file1, %s\n", fileName1);
852 if (!(fp2 = fopen(fileName2,
"r"))) {
853 fprintf(stderr,
"Error opening up file2, %s\n", fileName2);
857 ColIsFloat1.resize(200, 0);
858 ColIsFloat2.resize(200, 0);
864 get_sizes(fp1, nTitleLines1, nColTitleLines1, nCol1, nDataRows1, ColIsFloat1);
866 printf(
"Number of columns in file %s is zero\n", fileName1);
867 testPassed = RT_FAILED_OTHER;
868 exit(RT_FAILED_OTHER);
870 if (nDataRows1 == 0) {
871 printf(
"Number of data rows in file %s is zero\n", fileName1);
872 testPassed = RT_FAILED_OTHER;
873 exit(RT_FAILED_OTHER);
877 check_consistency(fp1, fileName1, nTitleLines1, nColTitleLines1, nCol1, nDataRows1, ColIsFloat1);
879 get_sizes(fp2, nTitleLines2, nColTitleLines2, nCol2, nDataRows2, ColIsFloat2);
881 printf(
"Number of columns in file %s is zero\n", fileName2);
882 testPassed = RT_FAILED_OTHER;
883 exit(RT_FAILED_OTHER);
885 if (nDataRows2 == 0) {
886 printf(
"Number of data rows in file %s is zero\n", fileName2);
887 testPassed = RT_FAILED_OTHER;
888 exit(RT_FAILED_OTHER);
891 if (nTitleLines1 != nTitleLines2) {
892 printf(
"Number of Title Lines differ:, %d %d\n",nTitleLines1, nTitleLines2);
893 testPassed = RT_FAILED_OTHER;
894 }
else if (Debug_Flag) {
895 printf(
"Number of Title Lines in each file = %d\n", nTitleLines1);
897 if (nColTitleLines1 != nColTitleLines2) {
898 printf(
"Number of Column title lines differ:, %d %d\n", nColTitleLines1,
900 testPassed = RT_FAILED_OTHER;
901 }
else if (Debug_Flag) {
902 printf(
"Number of column title lines in each file = %d\n", nColTitleLines1);
905 check_consistency(fp2, fileName2, nTitleLines2, nColTitleLines2, nCol2, nDataRows2, ColIsFloat2);
911 int nDataRowsMIN = min(nDataRows1, nDataRows2);
912 int nDataRowsMAX = max(nDataRows1, nDataRows2);
913 if (nDataRows1 != nDataRows2) {
914 printf(
"Number of Data rows in file1, %d, is different than file2, %d\n",
915 nDataRows1, nDataRows2);
917 printf(
"Number of Data rows in both files = %d\n", nDataRowsMIN);
922 read_title(fp1, &title1, nTitleLines1);
923 read_title(fp2, &title2, nTitleLines2);
925 if (nTitleLines1 > 0 || nTitleLines2 > 0) {
926 int n = min(nTitleLines1, nTitleLines2);
927 for (i = 0; i < n; i++) {
928 if (strcmp(title1[i], title2[i]) != 0) {
929 printf(
"Title Line %d differ:\n\t\"%s\"\n\t\"%s\"\n", i, title1[i], title2[i]);
930 testPassed = RT_FAILED_HDR;
931 }
else if (Debug_Flag) {
932 printf(
"Title Line %d for each file: \"%s\"\n", i, title1[i]);
935 if (nTitleLines1 != nTitleLines2) {
936 printf(
"Number of Title Lines differ: %d %d\n", nTitleLines1, nTitleLines2);
937 testPassed = RT_FAILED_HDR;
940 if (nTitleLines1 != nTitleLines2) {
942 printf(
"Titles differ: title for first file: \"%s\"\n",
944 testPassed = RT_FAILED_HDR;
947 printf(
"Titles differ: title for second file: \"%s\"\n",
950 testPassed = RT_FAILED_HDR;
958 if (nCol1 != nCol2) {
959 printf(
"Number of column variables differ:, %d %d\n",
961 testPassed = RT_FAILED_OTHER;
962 }
else if (Debug_Flag) {
963 printf(
"Number of column variables in both files = %d\n",
970 read_colTitle(fp1, &ColMLNames1, nColTitleLines1, nCol1);
971 read_colTitle(fp2, &ColMLNames2, nColTitleLines2, nCol2);
972 ColNames1 = ColMLNames1[0];
973 ColNames2 = ColMLNames2[0];
979 nColMAX = max(nCol1, nCol2);
981 compColList = mdp_alloc_int_2(nColMAX, 2, -1);
983 for (i = 0; i < nCol1; i++) {
985 for (j = 0; j < nCol2; j++) {
986 if (!strcmp(ColNames1[i], ColNames2[j])) {
987 compColList[nColcomparisons][0] = i;
988 compColList[nColcomparisons][1] = j;
995 printf(
"csvdiff WARNING Variable %s (%d) in first file not found"
996 " in second file\n", ColNames1[i], i);
997 testPassed = RT_FAILED_OTHER;
1000 for (j = 0; j < nCol2; j++) {
1002 for (i = 0; i < nColcomparisons; i++) {
1003 if (compColList[i][1] == j) {
1008 printf(
"csvdiff WARNING Variable %s (%d) in second file "
1009 "not found in first file\n",
1011 testPassed = RT_FAILED_OTHER;
1018 NVValues1 = mdp_alloc_dbl_2(nCol1, nDataRowsMAX, 0.0);
1019 NVValues2 = mdp_alloc_dbl_2(nCol2, nDataRowsMAX, 0.0);
1024 NSValues1 = (
char***) mdp_alloc_ptr_2(nCol1, nDataRowsMAX);
1025 NSValues2 = (
char***) mdp_alloc_ptr_2(nCol2, nDataRowsMAX);
1030 read_values(fp1, NVValues1, NSValues1, nCol1, nDataRows1, ColIsFloat1);
1031 read_values(fp2, NVValues2, NSValues2, nCol2, nDataRows2, ColIsFloat2);
1037 double slope1, slope2, xatol;
1039 for (k = 0; k < nColcomparisons; k++) {
1041 i1 = compColList[k][0];
1042 i2 = compColList[k][1];
1043 bool doFltComparison =
true;
1044 if (!ColIsFloat1[i1]) {
1045 doFltComparison =
false;
1048 if (!ColIsFloat2[i2]) {
1049 doFltComparison =
false;
1052 curStringValues1 = NSValues1[i1];
1053 curStringValues2 = NSValues2[i2];
1056 if (doFltComparison) {
1057 curVarValues1 = NVValues1[i1];
1058 curVarValues2 = NVValues2[i2];
1059 atol_j = get_atol(curVarValues1, nDataRows1, gatol);
1060 atol_j = min(atol_j, get_atol(curVarValues2, nDataRows2, gatol));
1061 for (j = 0; j < nDataRowsMIN; j++) {
1065 xatol = fabs(grtol * (NVValues1[0][j] - NVValues1[0][j-1]));
1066 if (j > 0 && k > 0) {
1067 slope1 = (curVarValues1[j] - curVarValues1[j-1])/
1068 (NVValues1[0][j] - NVValues1[0][j-1]);
1069 slope2 = (curVarValues2[j] - curVarValues2[j-1])/
1070 (NVValues2[0][j] - NVValues2[0][j-1]);
1073 notOK = diff_double_slope(curVarValues1[j], curVarValues2[j],
1074 grtol, atol_j, xatol, slope1, slope2);
1076 notOK = diff_double(curVarValues1[j], curVarValues2[j],
1081 rel_diff = calc_rdiff((
double) curVarValues1[j],
1082 (
double) curVarValues2[j], grtol, atol_j);
1083 if (rel_diff > max_diff) {
1085 max_diff = rel_diff;
1088 printf(
"\tColumn variable %s at data row %d ", ColNames1[i1], j + 1);
1089 printf(
" differ: %g %g\n", curVarValues1[j],
1095 for (j = 0; j < nDataRowsMIN; j++) {
1096 strip(curStringValues1[j]);
1097 strip(curStringValues2[j]);
1099 if (strcmp(curStringValues1[j], curStringValues2[j])) {
1103 printf(
"\tColumn String variable %s at data row %d ", ColNames1[i1], j + 1);
1104 printf(
" differ: %s %s\n", curStringValues1[j],
1105 curStringValues2[j]);
1111 if (nDataRowsMIN != nDataRowsMAX) {
1112 ndiff += nDataRowsMAX - nDataRowsMIN;
1114 if (nDataRows1 > nDataRows2) {
1115 for (j = nDataRowsMIN; j < nDataRowsMAX; j++) {
1116 printf(
"\tColumn variable %s at data row %d ", ColNames1[i1], j + 1);
1117 printf(
" differ: %g NA\n", curVarValues1[j]);
1120 for (j = nDataRowsMIN; j < nDataRowsMAX; j++) {
1121 printf(
"\tColumn variable %s at data row %d ", ColNames1[i1], j + 1);
1122 printf(
" differ: NA %g \n", curVarValues2[j]);
1134 "Column variable %s failed comparison test for %d occurrences\n",
1135 ColNames1[i1], ndiff);
1137 printf(
" Largest difference was at data row %d ", jmax + 1);
1138 printf(
": %g %g\n", curVarValues1[jmax], curVarValues2[jmax]);
1140 testPassed = RT_FAILED_COL;
1141 }
else if (Debug_Flag) {
1142 printf(
"Column variable %s passed\n", ColNames1[i1]);