diff options
author | Pedro Vicente Nunes <pvn@hdfgroup.org> | 2005-06-28 16:25:42 (GMT) |
---|---|---|
committer | Pedro Vicente Nunes <pvn@hdfgroup.org> | 2005-06-28 16:25:42 (GMT) |
commit | 4a5f83b8f0cf0d6899940f1940ac1f63bac847ca (patch) | |
tree | 4618cfc007f3b127e7cff92adf7416e2b4107a16 /tools/lib | |
parent | 7592f727f409ebf9b179a1af636dbf072ee5477c (diff) | |
download | hdf5-4a5f83b8f0cf0d6899940f1940ac1f63bac847ca.zip hdf5-4a5f83b8f0cf0d6899940f1940ac1f63bac847ca.tar.gz hdf5-4a5f83b8f0cf0d6899940f1940ac1f63bac847ca.tar.bz2 |
[svn-r10994] Purpose:
bug fix
Description:
when 2 objects were not comparable, the final print information for the non verbose mode printed "0 differences found"
Solution:
replaced instead with a Summary message that says
"Some objects were not comparable"
Platforms tested:
linux
solaris
Misc. update:
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/h5diff.c | 1149 | ||||
-rw-r--r-- | tools/lib/h5diff.h | 1 | ||||
-rw-r--r-- | tools/lib/h5diff_array.c | 1 | ||||
-rw-r--r-- | tools/lib/h5diff_attr.c | 3 | ||||
-rw-r--r-- | tools/lib/h5diff_dset.c | 15 | ||||
-rw-r--r-- | tools/lib/h5diff_util.c | 2 |
6 files changed, 593 insertions, 578 deletions
diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index d9380d0..c7828e8 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -19,6 +19,7 @@ + /*------------------------------------------------------------------------- * Function: print_objname * @@ -51,7 +52,7 @@ void phdiff_dismiss_workers(void) { int i; for(i=1; i<g_nTasks; i++) - MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD); + MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD); } @@ -59,7 +60,7 @@ void phdiff_dismiss_workers(void) * Function: print_manager_output * * Purpose: special function that prints any output accumulated by the - * manager task. + * manager task. * * Return: none * @@ -74,27 +75,27 @@ void print_manager_output(void) /* If there was something we buffered, let's print it now */ if( (outBuffOffset>0) && g_Parallel) { - printf("%s", outBuff); + printf("%s", outBuff); - if(overflow_file) - { - int tmp; + if(overflow_file) + { + int tmp; - rewind(overflow_file); - while((tmp = getc(overflow_file)) >= 0) - putchar(tmp); + rewind(overflow_file); + while((tmp = getc(overflow_file)) >= 0) + putchar(tmp); - fclose(overflow_file); - overflow_file = NULL; - } + fclose(overflow_file); + overflow_file = NULL; + } - fflush(stdout); - memset(outBuff, 0, OUTBUFF_SIZE); - outBuffOffset = 0; + fflush(stdout); + memset(outBuff, 0, OUTBUFF_SIZE); + outBuffOffset = 0; } else if( (outBuffOffset>0) && !g_Parallel) { - printf("h5diff error: outBuffOffset>0, but we're not in parallel!\n"); + printf("h5diff error: outBuffOffset>0, but we're not in parallel!\n"); } } @@ -102,7 +103,7 @@ void print_manager_output(void) * Function: print_incoming_data * * Purpose: special function that prints any output that has been sent to the manager - * and is currently sitting in the incoming message queue + * and is currently sitting in the incoming message queue * * Return: none * @@ -115,20 +116,20 @@ void print_manager_output(void) static void print_incoming_data(void) { - char data[PRINT_DATA_MAX_SIZE+1]; - int incomingMessage; - MPI_Status Status; + char data[PRINT_DATA_MAX_SIZE+1]; + int incomingMessage; + MPI_Status Status; do - { - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &incomingMessage, &Status); - if(incomingMessage) - { - memset(data, 0, PRINT_DATA_MAX_SIZE+1); - MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status); - - printf("%s", data); - } + { + MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &incomingMessage, &Status); + if(incomingMessage) + { + memset(data, 0, PRINT_DATA_MAX_SIZE+1); + MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status); + + printf("%s", data); + } } while(incomingMessage); } #endif @@ -146,15 +147,15 @@ static void print_incoming_data(void) * Date: October 22, 2003 * * Modifications: Jan 2005 Leon Arber, larber@uiuc.edu - * Added support for parallel diffing + * Added support for parallel diffing * *------------------------------------------------------------------------- */ hsize_t h5diff (const char *fname1, - const char *fname2, - const char *objname1, const char *objname2, diff_opt_t * options) + const char *fname2, + const char *objname1, const char *objname2, diff_opt_t * options) { int nobjects1, nobjects2; trav_info_t *info1 = NULL; @@ -169,7 +170,7 @@ h5diff (const char *fname1, if (options->m_quiet && (options->m_verbose || options->m_report)) { printf - ("Error: -q (quiet mode) cannot be added to verbose or report modes\n"); + ("Error: -q (quiet mode) cannot be added to verbose or report modes\n"); options->err_stat = 1; return 0; } @@ -185,33 +186,33 @@ h5diff (const char *fname1, /* Open the files */ if ((file1_id = H5Fopen (fname1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) { - printf ("h5diff: <%s>: unable to open file\n", fname1); - options->err_stat = 1; + printf ("h5diff: <%s>: unable to open file\n", fname1); + options->err_stat = 1; #ifdef H5_HAVE_PARALLEL - if(g_Parallel) - { - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); - } + if(g_Parallel) + { + /* Let tasks know that they won't be needed */ + phdiff_dismiss_workers(); + } #endif - goto out; + goto out; } if ((file2_id = H5Fopen (fname2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) { - printf ("h5diff: <%s>: unable to open file\n", fname2); - options->err_stat = 1; + printf ("h5diff: <%s>: unable to open file\n", fname2); + options->err_stat = 1; #ifdef H5_HAVE_PARALLEL - if(g_Parallel) - { - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); - } + if(g_Parallel) + { + /* Let tasks know that they won't be needed */ + phdiff_dismiss_workers(); + } #endif - goto out; + goto out; } /* enable error reporting */ } @@ -230,11 +231,11 @@ h5diff (const char *fname1, printf ("Error: Could not get get file contents\n"); options->err_stat = 1; #ifdef H5_HAVE_PARALLEL - if(g_Parallel) - { - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); - } + if(g_Parallel) + { + /* Let tasks know that they won't be needed */ + phdiff_dismiss_workers(); + } #endif goto out; } @@ -254,15 +255,15 @@ h5diff (const char *fname1, printf ("Error: Not enough memory for object list\n"); options->err_stat = 1; if (info1) - h5trav_freeinfo (info1, nobjects1); + h5trav_freeinfo (info1, nobjects1); if (info2) - h5trav_freeinfo (info2, nobjects1); + h5trav_freeinfo (info2, nobjects1); #ifdef H5_HAVE_PARALLEL - if(g_Parallel) - { - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); - } + if(g_Parallel) + { + /* Let tasks know that they won't be needed */ + phdiff_dismiss_workers(); + } #endif goto out; } @@ -277,19 +278,19 @@ h5diff (const char *fname1, if (objname1) { - + #ifdef H5_HAVE_PARALLEL - if(g_Parallel) - { - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); - } + if(g_Parallel) + { + /* Let tasks know that they won't be needed */ + phdiff_dismiss_workers(); + } #endif assert (objname2); - options->cmn_objs = 1; /* eliminate warning */ + options->cmn_objs = 1; /* eliminate warning */ nfound = diff_compare (file1_id, fname1, objname1, nobjects1, info1, - file2_id, fname2, objname2, nobjects2, info2, - options); + file2_id, fname2, objname2, nobjects2, info2, + options); } /*------------------------------------------------------------------------- @@ -305,23 +306,23 @@ h5diff (const char *fname1, { int i; - if( (strlen(fname1) > 1024) || (strlen(fname2) > 1024)) - { - printf("The parallel diff only supports path names up to 1024 characters\n"); - MPI_Abort(MPI_COMM_WORLD, 0); - } + if( (strlen(fname1) > 1024) || (strlen(fname2) > 1024)) + { + printf("The parallel diff only supports path names up to 1024 characters\n"); + MPI_Abort(MPI_COMM_WORLD, 0); + } - strcpy(filenames[0], fname1); - strcpy(filenames[1], fname2); + strcpy(filenames[0], fname1); + strcpy(filenames[1], fname2); - /* Alert the worker tasks that there's going to be work. */ + /* Alert the worker tasks that there's going to be work. */ - for(i=1; i<g_nTasks; i++) - MPI_Send(filenames, 1024*2, MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); + for(i=1; i<g_nTasks; i++) + MPI_Send(filenames, 1024*2, MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); } #endif nfound = diff_match (file1_id, nobjects1, info1, - file2_id, nobjects2, info2, options); + file2_id, nobjects2, info2, options); } @@ -356,16 +357,16 @@ out: * Date: May 9, 2003 * * Modifications: Jan 2005 Leon Arber, larber@uiuc.edu - * Added support for parallel diffing + * Added support for parallel diffing * *------------------------------------------------------------------------- */ hsize_t diff_match (hid_t file1_id, - int nobjects1, - trav_info_t * info1, - hid_t file2_id, - int nobjects2, trav_info_t * info2, diff_opt_t * options) + int nobjects1, + trav_info_t * info1, + hid_t file2_id, + int nobjects2, trav_info_t * info2, diff_opt_t * options) { int more_names_exist = (nobjects1 > 0 && nobjects2 > 0) ? 1 : 0; trav_table_t *table = NULL; @@ -385,64 +386,64 @@ diff_match (hid_t file1_id, while (more_names_exist) { - /* criteria is string compare */ - cmp = strcmp (info1[curr1].name, info2[curr2].name); - if (cmp == 0) - { - infile[0] = 1; - infile[1] = 1; - trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, - table); - - curr1++; - curr2++; - } - else if (cmp < 0) - { - infile[0] = 1; - infile[1] = 0; - trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, - table); - curr1++; - } - else - { - infile[0] = 0; - infile[1] = 1; - trav_table_addflags (infile, info2[curr2].name, info2[curr2].type, - table); - curr2++; - } - - more_names_exist = (curr1 < nobjects1 && curr2 < nobjects2) ? 1 : 0; - - - } /* end while */ + /* criteria is string compare */ + cmp = strcmp (info1[curr1].name, info2[curr2].name); + if (cmp == 0) + { + infile[0] = 1; + infile[1] = 1; + trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, + table); + + curr1++; + curr2++; + } + else if (cmp < 0) + { + infile[0] = 1; + infile[1] = 0; + trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, + table); + curr1++; + } + else + { + infile[0] = 0; + infile[1] = 1; + trav_table_addflags (infile, info2[curr2].name, info2[curr2].type, + table); + curr2++; + } + + more_names_exist = (curr1 < nobjects1 && curr2 < nobjects2) ? 1 : 0; + + + } /* end while */ /* list1 did not end */ if (curr1 < nobjects1) { - while (curr1 < nobjects1) - { - infile[0] = 1; - infile[1] = 0; - trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, - table); - curr1++; - } + while (curr1 < nobjects1) + { + infile[0] = 1; + infile[1] = 0; + trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, + table); + curr1++; + } } /* list2 did not end */ if (curr2 < nobjects2) { - while (curr2 < nobjects2) - { - infile[0] = 0; - infile[1] = 1; - trav_table_addflags (infile, info2[curr2].name, info2[curr2].type, - table); - curr2++; - } + while (curr2 < nobjects2) + { + infile[0] = 0; + infile[1] = 1; + trav_table_addflags (infile, info2[curr2].name, info2[curr2].type, + table); + curr2++; + } } /*------------------------------------------------------------------------- @@ -452,16 +453,16 @@ diff_match (hid_t file1_id, if (options->m_verbose) { - printf ("\n"); - printf ("file1 file2\n"); - printf ("---------------------------------------\n"); - for (i = 0; i < table->nobjs; i++) - { - c1 = (table->objs[i].flags[0]) ? 'x' : ' '; - c2 = (table->objs[i].flags[1]) ? 'x' : ' '; - printf ("%5c %6c %-15s\n", c1, c2, table->objs[i].name); - } - printf ("\n"); + printf ("\n"); + printf ("file1 file2\n"); + printf ("---------------------------------------\n"); + for (i = 0; i < table->nobjs; i++) + { + c1 = (table->objs[i].flags[0]) ? 'x' : ' '; + c2 = (table->objs[i].flags[1]) ? 'x' : ' '; + printf ("%5c %6c %-15s\n", c1, c2, table->objs[i].name); + } + printf ("\n"); } @@ -471,243 +472,243 @@ diff_match (hid_t file1_id, */ { #ifdef H5_HAVE_PARALLEL - char* workerTasks = malloc((g_nTasks-1) * sizeof(char)); - int n; - int busyTasks=0; - hsize_t nFoundbyWorker; - struct diff_args args; - int havePrintToken = 1; - MPI_Status Status; - - /*set all tasks as free */ - memset(workerTasks, 1, g_nTasks-1); + char* workerTasks = malloc((g_nTasks-1) * sizeof(char)); + int n; + int busyTasks=0; + hsize_t nFoundbyWorker; + struct diff_args args; + int havePrintToken = 1; + MPI_Status Status; + + /*set all tasks as free */ + memset(workerTasks, 1, g_nTasks-1); #endif - for (i = 0; i < table->nobjs; i++) - { - if (table->objs[i].flags[0] && table->objs[i].flags[1]) - { + for (i = 0; i < table->nobjs; i++) + { + if (table->objs[i].flags[0] && table->objs[i].flags[1]) + { #ifdef H5_HAVE_PARALLEL - int workerFound = 0; + int workerFound = 0; #endif /* H5_HAVE_PARALLEL */ - options->cmn_objs = 1; - if(!g_Parallel) - { - nfound += diff (file1_id, - table->objs[i].name, - file2_id, - table->objs[i].name, options, table->objs[i].type); - } + options->cmn_objs = 1; + if(!g_Parallel) + { + nfound += diff (file1_id, + table->objs[i].name, + file2_id, + table->objs[i].name, options, table->objs[i].type); + } #ifdef H5_HAVE_PARALLEL - else - { - /* We're in parallel mode */ - /* Since the data type of diff value is hsize_t which can - * be arbitary large such that there is no MPI type that - * matches it, the value is passed between processes as - * an array of bytes in order to be portable. But this - * may not work in non-homogeneous MPI environments. - */ - - /*Set up args to pass to worker task. */ - if(strlen(table->objs[i].name) > 255) - { - printf("The parallel diff only supports object names up to 255 characters\n"); - MPI_Abort(MPI_COMM_WORLD, 0); - } - - strcpy(args.name, table->objs[i].name); - args.options = *options; - args.type= table->objs[i].type; - - /* if there are any outstanding print requests, let's handle one. */ - if(busyTasks > 0) - { - int incomingMessage; - /* check if any tasks freed up, and didn't need to print. */ - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &incomingMessage, &Status); - - if(incomingMessage) - { - workerTasks[Status.MPI_SOURCE-1] = 1; - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - busyTasks--; - } - - /* check to see if the print token was returned. */ - if(!havePrintToken) - { - /* check incoming queue for token */ - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status); - - /* incoming token implies free task. */ - if(incomingMessage) - { - workerTasks[Status.MPI_SOURCE-1] = 1; - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - busyTasks--; - havePrintToken = 1; - } - } - - /* check to see if anyone needs the print token. */ - if(havePrintToken) - { - /* check incoming queue for print token requests */ - MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &incomingMessage, &Status); - if(incomingMessage) - { - MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status); - MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); - havePrintToken = 0; - } - } - - /* Print all the data in our incoming queue */ - print_incoming_data(); - } - - /* check array of tasks to see which ones are free. - * Manager task never does work, so freeTasks[0] is really - * worker task 0. */ - - for(n=1; (n<g_nTasks) && !workerFound; n++) - { - if(workerTasks[n-1]) - { - /* send file id's and names to first free worker */ - MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, n, MPI_TAG_ARGS, MPI_COMM_WORLD); - - /* increment counter for total number of prints. */ - busyTasks++; - - /* mark worker as busy */ - workerTasks[n-1] = 0; - workerFound = 1; - } - - } - - - if(!workerFound) - { - /* if they were all busy, we've got to wait for one free up before we can move on. - * if we don't have the token, some task is currently printing so we'll wait for that task to return it. */ - if(!havePrintToken) - { - MPI_Recv(&nFoundbyWorker, sizeof(hsize_t), MPI_BYTE, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - havePrintToken = 1; - nfound += nFoundbyWorker; - /* send this task the work unit. */ - MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); - } - /* if we do have the token, check for task to free up, or wait for a task to request it */ - else - { - /* But first print all the data in our incoming queue */ - print_incoming_data(); - - MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); - if(Status.MPI_TAG == MPI_TAG_DONE) - { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); - } - else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST) - { - MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status); - MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); - - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); - } - else - { - printf("ERROR: Invalid tag (%d) received \n", Status.MPI_TAG); - MPI_Abort(MPI_COMM_WORLD, 0); - MPI_Finalize(); - } - } - } - } + else + { + /* We're in parallel mode */ + /* Since the data type of diff value is hsize_t which can + * be arbitary large such that there is no MPI type that + * matches it, the value is passed between processes as + * an array of bytes in order to be portable. But this + * may not work in non-homogeneous MPI environments. + */ + + /*Set up args to pass to worker task. */ + if(strlen(table->objs[i].name) > 255) + { + printf("The parallel diff only supports object names up to 255 characters\n"); + MPI_Abort(MPI_COMM_WORLD, 0); + } + + strcpy(args.name, table->objs[i].name); + args.options = *options; + args.type= table->objs[i].type; + + /* if there are any outstanding print requests, let's handle one. */ + if(busyTasks > 0) + { + int incomingMessage; + /* check if any tasks freed up, and didn't need to print. */ + MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &incomingMessage, &Status); + + if(incomingMessage) + { + workerTasks[Status.MPI_SOURCE-1] = 1; + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + } + + /* check to see if the print token was returned. */ + if(!havePrintToken) + { + /* check incoming queue for token */ + MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status); + + /* incoming token implies free task. */ + if(incomingMessage) + { + workerTasks[Status.MPI_SOURCE-1] = 1; + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + havePrintToken = 1; + } + } + + /* check to see if anyone needs the print token. */ + if(havePrintToken) + { + /* check incoming queue for print token requests */ + MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &incomingMessage, &Status); + if(incomingMessage) + { + MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status); + MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); + havePrintToken = 0; + } + } + + /* Print all the data in our incoming queue */ + print_incoming_data(); + } + + /* check array of tasks to see which ones are free. + * Manager task never does work, so freeTasks[0] is really + * worker task 0. */ + + for(n=1; (n<g_nTasks) && !workerFound; n++) + { + if(workerTasks[n-1]) + { + /* send file id's and names to first free worker */ + MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, n, MPI_TAG_ARGS, MPI_COMM_WORLD); + + /* increment counter for total number of prints. */ + busyTasks++; + + /* mark worker as busy */ + workerTasks[n-1] = 0; + workerFound = 1; + } + + } + + + if(!workerFound) + { + /* if they were all busy, we've got to wait for one free up before we can move on. + * if we don't have the token, some task is currently printing so we'll wait for that task to return it. */ + if(!havePrintToken) + { + MPI_Recv(&nFoundbyWorker, sizeof(hsize_t), MPI_BYTE, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); + havePrintToken = 1; + nfound += nFoundbyWorker; + /* send this task the work unit. */ + MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); + } + /* if we do have the token, check for task to free up, or wait for a task to request it */ + else + { + /* But first print all the data in our incoming queue */ + print_incoming_data(); + + MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); + if(Status.MPI_TAG == MPI_TAG_DONE) + { + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); + } + else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST) + { + MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status); + MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); + + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); + } + else + { + printf("ERROR: Invalid tag (%d) received \n", Status.MPI_TAG); + MPI_Abort(MPI_COMM_WORLD, 0); + MPI_Finalize(); + } + } + } + } #endif - } - } + } + } #ifdef H5_HAVE_PARALLEL - if(g_Parallel) - { - while(busyTasks > 0) /* make sure all tasks are done */ - { - MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); - if(Status.MPI_TAG == MPI_TAG_DONE) - { - MPI_Recv(&nFoundbyWorker, sizeof(hsize_t), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - busyTasks--; - } - else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN) - { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - busyTasks--; - havePrintToken = 1; - } - else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST) - { - MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status); - if(havePrintToken) - { - MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - busyTasks--; - } - else /* someone else must have it...wait for them to return it, then give it to the task that just asked for it. */ - { - int source = Status.MPI_SOURCE; - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - busyTasks--; - MPI_Send(NULL, 0, MPI_BYTE, source, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); - } - } - else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN) - { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - nfound += nFoundbyWorker; - busyTasks--; - havePrintToken = 1; - } - else if(Status.MPI_TAG == MPI_TAG_PRINT_DATA) - { - char data[PRINT_DATA_MAX_SIZE+1]; - memset(data, 0, PRINT_DATA_MAX_SIZE+1); - - MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status); - - printf("%s", data); - } - else - { - printf("ph5diff-manager: ERROR!! Invalid tag (%d) received \n", Status.MPI_TAG); - MPI_Abort(MPI_COMM_WORLD, 0); - } - } - - for(i=1; i<g_nTasks; i++) - MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD); - - /* Print any final data waiting in our queue */ - print_incoming_data(); - - } - - free(workerTasks); + if(g_Parallel) + { + while(busyTasks > 0) /* make sure all tasks are done */ + { + MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); + if(Status.MPI_TAG == MPI_TAG_DONE) + { + MPI_Recv(&nFoundbyWorker, sizeof(hsize_t), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + } + else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN) + { + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + havePrintToken = 1; + } + else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST) + { + MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status); + if(havePrintToken) + { + MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + } + else /* someone else must have it...wait for them to return it, then give it to the task that just asked for it. */ + { + int source = Status.MPI_SOURCE; + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + MPI_Send(NULL, 0, MPI_BYTE, source, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD); + } + } + else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN) + { + MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + havePrintToken = 1; + } + else if(Status.MPI_TAG == MPI_TAG_PRINT_DATA) + { + char data[PRINT_DATA_MAX_SIZE+1]; + memset(data, 0, PRINT_DATA_MAX_SIZE+1); + + MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status); + + printf("%s", data); + } + else + { + printf("ph5diff-manager: ERROR!! Invalid tag (%d) received \n", Status.MPI_TAG); + MPI_Abort(MPI_COMM_WORLD, 0); + } + } + + for(i=1; i<g_nTasks; i++) + MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD); + + /* Print any final data waiting in our queue */ + print_incoming_data(); + + } + + free(workerTasks); #endif } /* free table */ @@ -744,14 +745,14 @@ diff_match (hid_t file1_id, hsize_t diff_compare (hid_t file1_id, - const char *file1_name, - const char *obj1_name, - int nobjects1, - trav_info_t * info1, - hid_t file2_id, - const char *file2_name, - const char *obj2_name, - int nobjects2, trav_info_t * info2, diff_opt_t * options) + const char *file1_name, + const char *obj1_name, + int nobjects1, + trav_info_t * info1, + hid_t file2_id, + const char *file2_name, + const char *obj2_name, + int nobjects2, trav_info_t * info2, diff_opt_t * options) { int f1 = 0, f2 = 0; @@ -762,34 +763,35 @@ diff_compare (hid_t file1_id, if (i == -1) { - parallel_print ("Object <%s> could not be found in <%s>\n", obj1_name, - file1_name); - f1 = 1; + parallel_print ("Object <%s> could not be found in <%s>\n", obj1_name, + file1_name); + f1 = 1; } - if (j == -1) - { - parallel_print ("Object <%s> could not be found in <%s>\n", obj2_name, - file2_name); - f2 = 1; - } - if (f1 || f2) - { - options->err_stat = 1; - return 0; - } - - /* use the name with "/" first, as obtained by iterator function */ - obj1_name = info1[i].name; + if (j == -1) + { + parallel_print ("Object <%s> could not be found in <%s>\n", obj2_name, + file2_name); + f2 = 1; + } + if (f1 || f2) + { + options->err_stat = 1; + return 0; + } + + /* use the name with "/" first, as obtained by iterator function */ + obj1_name = info1[i].name; obj2_name = info2[j].name; /* objects are not the same type */ if (info1[i].type != info2[j].type) { if (options->m_verbose) - parallel_print - ("Comparison not possible: <%s> is of type %s and <%s> is of type %s\n", - obj1_name, get_type (info1[i].type), obj2_name, - get_type (info2[j].type)); + parallel_print + ("Comparison not possible: <%s> is of type %s and <%s> is of type %s\n", + obj1_name, get_type (info1[i].type), obj2_name, + get_type (info2[j].type)); + options->not_cmp=1; return 0; } @@ -805,10 +807,10 @@ diff_compare (hid_t file1_id, * * Purpose: switch between types and choose the diff function * TYPE is either - * H5G_LINK Object is a symbolic link - * H5G_GROUP Object is a group - * H5G_DATASET Object is a dataset - * H5G_TYPE Object is a named data type + * H5G_LINK Object is a symbolic link + * H5G_GROUP Object is a group + * H5G_DATASET Object is a dataset + * H5G_TYPE Object is a named data type * * Return: Number of differences found * @@ -837,165 +839,166 @@ diff (hid_t file1_id, switch (type) { - /*------------------------------------------------------------------------- - * H5G_DATASET - *------------------------------------------------------------------------- - */ - case H5G_DATASET: - - /* always print name */ - if (options->m_verbose) - { - if (print_objname (options, (hsize_t)1)) - parallel_print("Dataset: <%s> and <%s>\n", path1, path2); - nfound = diff_dataset (file1_id, file2_id, path1, path2, options); - - } - /* check first if we have differences */ - else - { - if (options->m_quiet == 0) - { - /* shut up temporarily */ - options->m_quiet = 1; - nfound = - diff_dataset (file1_id, file2_id, path1, path2, options); - /* print again */ - options->m_quiet = 0; - if (nfound) - { - if (print_objname (options, nfound)) - parallel_print("Dataset: <%s> and <%s>\n", path1, path2); - nfound = diff_dataset (file1_id, file2_id, path1, path2, options); - } /*if */ - } /*if */ - /* in quiet mode, just count differences */ - else - { - nfound = diff_dataset (file1_id, file2_id, path1, path2, options); - } - } /*else */ - - break; - - /*------------------------------------------------------------------------- - * H5G_TYPE - *------------------------------------------------------------------------- - */ - case H5G_TYPE: - if ((type1_id = H5Topen (file1_id, path1)) < 0) - goto out; - if ((type2_id = H5Topen (file2_id, path2)) < 0) - goto out; - - if ((ret = H5Tequal (type1_id, type2_id)) < 0) - goto out; - - /* if H5Tequal is > 0 then the datatypes refer to the same datatype */ - nfound = (ret > 0) ? 0 : 1; - - if (print_objname (options, nfound)) - parallel_print("Datatype: <%s> and <%s>\n", path1, path2); - - /*------------------------------------------------------------------------- - * compare attributes - * the if condition refers to cases when the dataset is a referenced object - *------------------------------------------------------------------------- - */ - if (path1) - diff_attr (type1_id, type2_id, path1, path2, options); - - if (H5Tclose (type1_id) < 0) - goto out; - if (H5Tclose (type2_id) < 0) - goto out; - - break; - - /*------------------------------------------------------------------------- - * H5G_GROUP - *------------------------------------------------------------------------- - */ - case H5G_GROUP: - if ((grp1_id = H5Gopen (file1_id, path1)) < 0) - goto out; - if ((grp2_id = H5Gopen (file2_id, path2)) < 0) - goto out; - - ret = HDstrcmp (path1, path2); - - /* if "path1" != "path2" then the groups are "different" */ - nfound = (ret != 0) ? 1 : 0; - - if (print_objname (options, nfound)) - parallel_print("Group: <%s> and <%s>\n", path1, path2); - - /*------------------------------------------------------------------------- - * compare attributes - * the if condition refers to cases when the dataset is a referenced object - *------------------------------------------------------------------------- - */ - if (path1) - diff_attr (grp1_id, grp2_id, path1, path2, options); - - if (H5Gclose (grp1_id) < 0) - goto out; - if (H5Gclose (grp2_id) < 0) - goto out; - - break; - - - /*------------------------------------------------------------------------- - * H5G_LINK - *------------------------------------------------------------------------- - */ - case H5G_LINK: - if (H5Gget_objinfo (file1_id, path1, FALSE, &sb1) < 0) - goto out; - if (H5Gget_objinfo (file1_id, path1, FALSE, &sb2) < 0) - goto out; - - buf1 = malloc (sb1.linklen); - buf2 = malloc (sb2.linklen); - - if (H5Gget_linkval (file1_id, path1, sb1.linklen, buf1) < 0) - goto out; - if (H5Gget_linkval (file2_id, path2, sb1.linklen, buf2) < 0) - goto out; - - ret = HDstrcmp (buf1, buf2); - - /* if "buf1" != "buf2" then the links are "different" */ - nfound = (ret != 0) ? 1 : 0; - - if (print_objname (options, nfound)) - parallel_print("Link: <%s> and <%s>\n", path1, path2); - - if (buf1) - { - free (buf1); - buf1 = NULL; - } - - if (buf2) - { - free (buf2); - buf2 = NULL; - } - - break; - - - default: - nfound = 0; - if (options->m_verbose) - { - parallel_print("Comparison not supported: <%s> and <%s> are of type %s\n", - path1, path2, get_type (type)); - } - - break; + /*------------------------------------------------------------------------- + * H5G_DATASET + *------------------------------------------------------------------------- + */ + case H5G_DATASET: + + /* always print name */ + if (options->m_verbose) + { + if (print_objname (options, (hsize_t)1)) + parallel_print("Dataset: <%s> and <%s>\n", path1, path2); + nfound = diff_dataset (file1_id, file2_id, path1, path2, options); + + } + /* check first if we have differences */ + else + { + if (options->m_quiet == 0) + { + /* shut up temporarily */ + options->m_quiet = 1; + nfound = + diff_dataset (file1_id, file2_id, path1, path2, options); + /* print again */ + options->m_quiet = 0; + if (nfound) + { + if (print_objname (options, nfound)) + parallel_print("Dataset: <%s> and <%s>\n", path1, path2); + nfound = diff_dataset (file1_id, file2_id, path1, path2, options); + } /*if */ + } /*if */ + /* in quiet mode, just count differences */ + else + { + nfound = diff_dataset (file1_id, file2_id, path1, path2, options); + } + } /*else */ + + break; + + /*------------------------------------------------------------------------- + * H5G_TYPE + *------------------------------------------------------------------------- + */ + case H5G_TYPE: + if ((type1_id = H5Topen (file1_id, path1)) < 0) + goto out; + if ((type2_id = H5Topen (file2_id, path2)) < 0) + goto out; + + if ((ret = H5Tequal (type1_id, type2_id)) < 0) + goto out; + + /* if H5Tequal is > 0 then the datatypes refer to the same datatype */ + nfound = (ret > 0) ? 0 : 1; + + if (print_objname (options, nfound)) + parallel_print("Datatype: <%s> and <%s>\n", path1, path2); + + /*------------------------------------------------------------------------- + * compare attributes + * the if condition refers to cases when the dataset is a referenced object + *------------------------------------------------------------------------- + */ + if (path1) + diff_attr (type1_id, type2_id, path1, path2, options); + + if (H5Tclose (type1_id) < 0) + goto out; + if (H5Tclose (type2_id) < 0) + goto out; + + break; + + /*------------------------------------------------------------------------- + * H5G_GROUP + *------------------------------------------------------------------------- + */ + case H5G_GROUP: + if ((grp1_id = H5Gopen (file1_id, path1)) < 0) + goto out; + if ((grp2_id = H5Gopen (file2_id, path2)) < 0) + goto out; + + ret = HDstrcmp (path1, path2); + + /* if "path1" != "path2" then the groups are "different" */ + nfound = (ret != 0) ? 1 : 0; + + if (print_objname (options, nfound)) + parallel_print("Group: <%s> and <%s>\n", path1, path2); + + /*------------------------------------------------------------------------- + * compare attributes + * the if condition refers to cases when the dataset is a referenced object + *------------------------------------------------------------------------- + */ + if (path1) + diff_attr (grp1_id, grp2_id, path1, path2, options); + + if (H5Gclose (grp1_id) < 0) + goto out; + if (H5Gclose (grp2_id) < 0) + goto out; + + break; + + + /*------------------------------------------------------------------------- + * H5G_LINK + *------------------------------------------------------------------------- + */ + case H5G_LINK: + if (H5Gget_objinfo (file1_id, path1, FALSE, &sb1) < 0) + goto out; + if (H5Gget_objinfo (file1_id, path1, FALSE, &sb2) < 0) + goto out; + + buf1 = malloc (sb1.linklen); + buf2 = malloc (sb2.linklen); + + if (H5Gget_linkval (file1_id, path1, sb1.linklen, buf1) < 0) + goto out; + if (H5Gget_linkval (file2_id, path2, sb1.linklen, buf2) < 0) + goto out; + + ret = HDstrcmp (buf1, buf2); + + /* if "buf1" != "buf2" then the links are "different" */ + nfound = (ret != 0) ? 1 : 0; + + if (print_objname (options, nfound)) + parallel_print("Link: <%s> and <%s>\n", path1, path2); + + if (buf1) + { + free (buf1); + buf1 = NULL; + } + + if (buf2) + { + free (buf2); + buf2 = NULL; + } + + break; + + + default: + nfound = 0; + if (options->m_verbose) + { + parallel_print("Comparison not supported: <%s> and <%s> are of type %s\n", + path1, path2, get_type (type)); + options->not_cmp=1; + } + + break; } @@ -1005,18 +1008,18 @@ out: /* disable error reporting */ H5E_BEGIN_TRY { - H5Tclose (type1_id); - H5Tclose (type2_id); - H5Gclose (grp1_id); - H5Tclose (grp2_id); - /* enable error reporting */ + H5Tclose (type1_id); + H5Tclose (type2_id); + H5Gclose (grp1_id); + H5Tclose (grp2_id); + /* enable error reporting */ } H5E_END_TRY; if (buf1) - free (buf1); + free (buf1); if (buf2) - free (buf2); + free (buf2); return nfound; } diff --git a/tools/lib/h5diff.h b/tools/lib/h5diff.h index a9d8458..cdaabaa 100644 --- a/tools/lib/h5diff.h +++ b/tools/lib/h5diff.h @@ -62,6 +62,7 @@ typedef struct { int count; /* count value */ int err_stat; /* an error ocurred (1, error, 0, no error) */ int cmn_objs; /* do we have comparable objects */ + int not_cmp; /* are the objects comparable */ } diff_opt_t; diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c index 60060e4..1ed4ab2 100644 --- a/tools/lib/h5diff_array.c +++ b/tools/lib/h5diff_array.c @@ -607,6 +607,7 @@ hsize_t diff_datum(void *_mem1, default: parallel_print("Warning: Comparison not possible of object types referenced: <%s> and <%s>", obj1, obj2); + options->not_cmp=1; break; } diff --git a/tools/lib/h5diff_attr.c b/tools/lib/h5diff_attr.c index 24ade01..56e2af1 100644 --- a/tools/lib/h5diff_attr.c +++ b/tools/lib/h5diff_attr.c @@ -146,7 +146,10 @@ int diff_attr(hid_t loc1_id, name1, name2, options)!=1) + { cmp=0; + options->not_cmp=1; + } /*------------------------------------------------------------------------- * only attempt to compare if possible *------------------------------------------------------------------------- diff --git a/tools/lib/h5diff_dset.c b/tools/lib/h5diff_dset.c index 1887df8..c4b4a4b 100644 --- a/tools/lib/h5diff_dset.c +++ b/tools/lib/h5diff_dset.c @@ -206,9 +206,10 @@ hsize_t diff_datasetid( hid_t dset1_id, storage_size2=H5Dget_storage_size(dset2_id); if (storage_size1<=0 && storage_size2<=0) { - if (options->m_verbose && obj1_name && obj2_name) - parallel_print("<%s> and <%s> are empty datasets\n", obj1_name, obj2_name); - cmp=0; + if (options->m_verbose && obj1_name && obj2_name) + parallel_print("<%s> and <%s> are empty datasets\n", obj1_name, obj2_name); + cmp=0; + options->not_cmp=1; } @@ -228,7 +229,10 @@ hsize_t diff_datasetid( hid_t dset1_id, obj1_name, obj2_name, options)!=1) + { cmp=0; + options->not_cmp=1; + } /*------------------------------------------------------------------------- * get number of elements *------------------------------------------------------------------------- @@ -245,7 +249,9 @@ hsize_t diff_datasetid( hid_t dset1_id, nelmts2 *= dims2[i]; } - assert(nelmts1==nelmts2); + if (cmp) + /* onnly assert if the space is the same */ + assert(nelmts1==nelmts2); /*------------------------------------------------------------------------- * check for equal file datatype; warning only @@ -296,6 +302,7 @@ hsize_t diff_datasetid( hid_t dset1_id, } cmp=0; + options->not_cmp=1; } /*------------------------------------------------------------------------- diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c index 34686c6..d29434c 100644 --- a/tools/lib/h5diff_util.c +++ b/tools/lib/h5diff_util.c @@ -284,7 +284,7 @@ diff_basename(const char *name) size_t i; if (name==NULL) - return; + return NULL; /* Find the end of the base name */ i = strlen(name); |