2003-10-23 05:30:19 +08:00
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
2007-02-07 22:56:24 +08:00
|
|
|
* Copyright by The HDF Group. *
|
2003-10-23 05:30:19 +08:00
|
|
|
* Copyright by the Board of Trustees of the University of Illinois. *
|
|
|
|
* All rights reserved. *
|
|
|
|
* *
|
|
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
|
|
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
|
|
|
* of the source code distribution tree; Copyright.html can be found at the *
|
|
|
|
* root level of an installed copy of the electronic HDF5 document set and *
|
|
|
|
* is linked from the top-level documents page. It can also be found at *
|
2007-02-07 22:56:24 +08:00
|
|
|
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
|
|
|
* access to either file, you may request a copy from help@hdfgroup.org. *
|
2003-10-23 05:30:19 +08:00
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
|
|
|
|
#include "h5diff.h"
|
2005-01-27 07:03:29 +08:00
|
|
|
#include "ph5diff.h"
|
2003-12-03 22:26:51 +08:00
|
|
|
#include "H5private.h"
|
|
|
|
|
2005-02-01 12:13:42 +08:00
|
|
|
/* global variables */
|
2005-02-03 07:01:42 +08:00
|
|
|
int g_nTasks = 1;
|
2006-03-23 04:53:05 +08:00
|
|
|
unsigned char g_Parallel = 0; /*0 for serial, 1 for parallel */
|
|
|
|
char outBuff[OUTBUFF_SIZE];
|
|
|
|
int outBuffOffset;
|
|
|
|
FILE* overflow_file = NULL;
|
2003-10-23 05:30:19 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: parallel_print
|
|
|
|
*
|
|
|
|
* Purpose: wrapper for printf for use in parallel mode.
|
|
|
|
*
|
|
|
|
* Programmer: Leon Arber
|
|
|
|
*
|
|
|
|
* Date: December 1, 2004
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void parallel_print(const char* format, ...)
|
|
|
|
{
|
2006-03-23 04:53:05 +08:00
|
|
|
int bytes_written;
|
|
|
|
va_list ap;
|
2006-06-27 22:45:06 +08:00
|
|
|
|
2006-03-23 04:53:05 +08:00
|
|
|
va_start(ap, format);
|
2006-06-27 22:45:06 +08:00
|
|
|
|
2006-03-23 04:53:05 +08:00
|
|
|
if(!g_Parallel)
|
|
|
|
vprintf(format, ap);
|
|
|
|
else
|
|
|
|
{
|
2006-06-27 22:45:06 +08:00
|
|
|
|
2006-03-23 04:53:05 +08:00
|
|
|
if(overflow_file == NULL) /*no overflow has occurred yet */
|
|
|
|
{
|
2005-08-18 03:21:36 +08:00
|
|
|
#if 0
|
2006-03-23 04:53:05 +08:00
|
|
|
printf("calling HDvsnprintf: OUTBUFF_SIZE=%ld, outBuffOffset=%ld, ", (long)OUTBUFF_SIZE, (long)outBuffOffset);
|
2005-08-18 03:21:36 +08:00
|
|
|
#endif
|
2006-03-23 04:53:05 +08:00
|
|
|
bytes_written = HDvsnprintf(outBuff+outBuffOffset, OUTBUFF_SIZE-outBuffOffset, format, ap);
|
2005-08-18 03:21:36 +08:00
|
|
|
#if 0
|
2006-03-23 04:53:05 +08:00
|
|
|
printf("bytes_written=%ld\n", (long)bytes_written);
|
2005-08-18 03:21:36 +08:00
|
|
|
#endif
|
2006-03-23 04:53:05 +08:00
|
|
|
va_end(ap);
|
|
|
|
va_start(ap, format);
|
2006-06-27 22:45:06 +08:00
|
|
|
|
2005-08-18 03:21:36 +08:00
|
|
|
#if 0
|
2006-03-23 04:53:05 +08:00
|
|
|
printf("Result: bytes_written=%ld, OUTBUFF_SIZE-outBuffOffset=%ld\n", (long)bytes_written, (long)OUTBUFF_SIZE-outBuffOffset);
|
2005-08-18 03:21:36 +08:00
|
|
|
#endif
|
2006-06-27 22:45:06 +08:00
|
|
|
|
2006-03-23 04:53:05 +08:00
|
|
|
if ((bytes_written < 0) ||
|
2005-03-14 08:22:35 +08:00
|
|
|
#ifdef H5_VSNPRINTF_WORKS
|
2006-03-23 04:53:05 +08:00
|
|
|
(bytes_written >= (OUTBUFF_SIZE-outBuffOffset))
|
2005-03-14 07:38:11 +08:00
|
|
|
#else
|
2006-03-23 04:53:05 +08:00
|
|
|
((bytes_written+1) == (OUTBUFF_SIZE-outBuffOffset))
|
2005-08-14 04:53:35 +08:00
|
|
|
#endif
|
2006-03-23 04:53:05 +08:00
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Terminate the outbuff at the end of the previous output */
|
|
|
|
outBuff[outBuffOffset] = '\0';
|
2006-06-27 22:45:06 +08:00
|
|
|
|
2006-03-23 04:53:05 +08:00
|
|
|
overflow_file = HDtmpfile();
|
|
|
|
if(overflow_file == NULL)
|
2006-04-07 02:29:53 +08:00
|
|
|
fprintf(stderr, "warning: could not create overflow file. Output may be truncated.\n");
|
2006-03-23 04:53:05 +08:00
|
|
|
else
|
|
|
|
bytes_written = HDvfprintf(overflow_file, format, ap);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
outBuffOffset += bytes_written;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bytes_written = HDvfprintf(overflow_file, format, ap);
|
2006-06-27 22:45:06 +08:00
|
|
|
|
2006-03-23 04:53:05 +08:00
|
|
|
}
|
|
|
|
va_end(ap);
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
|
|
|
|
2003-10-23 05:30:19 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
2007-02-22 04:05:04 +08:00
|
|
|
* Function: print_dimensions
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
2008-09-16 23:52:51 +08:00
|
|
|
* Purpose: print dimensions
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2007-02-22 04:05:04 +08:00
|
|
|
void
|
|
|
|
print_dimensions (int rank, hsize_t *dims)
|
2003-10-23 05:30:19 +08:00
|
|
|
{
|
2007-02-22 04:05:04 +08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
parallel_print("[" );
|
|
|
|
for ( i = 0; i < rank-1; i++)
|
|
|
|
{
|
|
|
|
parallel_print("%"H5_PRINTF_LL_WIDTH"u", (unsigned long_long)dims[i]);
|
|
|
|
parallel_print("x");
|
|
|
|
}
|
|
|
|
parallel_print("%"H5_PRINTF_LL_WIDTH"u", (unsigned long_long)dims[rank-1]);
|
|
|
|
parallel_print("]" );
|
2008-09-16 23:52:51 +08:00
|
|
|
|
2003-10-23 05:30:19 +08:00
|
|
|
}
|
|
|
|
|
2007-02-22 04:05:04 +08:00
|
|
|
|
2003-10-23 05:30:19 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
2003-10-29 01:40:05 +08:00
|
|
|
* Function: print_type
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
2005-08-14 04:53:35 +08:00
|
|
|
* Purpose: Print name of datatype
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
2003-10-29 01:40:05 +08:00
|
|
|
* Return: void
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
|
|
|
* Date: May 9, 2003
|
|
|
|
*
|
|
|
|
* Comments: Adapted from h5dump for H5T_INTEGER and H5T_FLOAT classes only
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2003-10-29 01:40:05 +08:00
|
|
|
void print_type(hid_t type)
|
2003-10-23 05:30:19 +08:00
|
|
|
{
|
2008-05-01 03:51:13 +08:00
|
|
|
switch (H5Tget_class(type))
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
case H5T_INTEGER:
|
|
|
|
if (H5Tequal(type, H5T_STD_I8BE)) {
|
|
|
|
printf("H5T_STD_I8BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_I8LE)) {
|
|
|
|
printf("H5T_STD_I8LE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_I16BE)) {
|
|
|
|
printf("H5T_STD_I16BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_I16LE)) {
|
|
|
|
printf("H5T_STD_I16LE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_I32BE)) {
|
|
|
|
printf("H5T_STD_I32BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_I32LE)) {
|
|
|
|
printf("H5T_STD_I32LE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_I64BE)) {
|
|
|
|
printf("H5T_STD_I64BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_I64LE)) {
|
|
|
|
printf("H5T_STD_I64LE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U8BE)) {
|
|
|
|
printf("H5T_STD_U8BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U8LE)) {
|
|
|
|
printf("H5T_STD_U8LE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U16BE)) {
|
|
|
|
printf("H5T_STD_U16BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U16LE)) {
|
|
|
|
printf("H5T_STD_U16LE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U32BE)) {
|
|
|
|
printf("H5T_STD_U32BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U32LE)) {
|
|
|
|
printf("H5T_STD_U32LE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U64BE)) {
|
|
|
|
printf("H5T_STD_U64BE");
|
|
|
|
} else if (H5Tequal(type, H5T_STD_U64LE)) {
|
|
|
|
printf("H5T_STD_U64LE");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_SCHAR)) {
|
|
|
|
printf("H5T_NATIVE_SCHAR");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_UCHAR)) {
|
|
|
|
printf("H5T_NATIVE_UCHAR");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_SHORT)) {
|
|
|
|
printf("H5T_NATIVE_SHORT");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_USHORT)) {
|
|
|
|
printf("H5T_NATIVE_USHORT");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_INT)) {
|
|
|
|
printf("H5T_NATIVE_INT");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_UINT)) {
|
|
|
|
printf("H5T_NATIVE_UINT");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_LONG)) {
|
|
|
|
printf("H5T_NATIVE_LONG");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_ULONG)) {
|
|
|
|
printf("H5T_NATIVE_ULONG");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_LLONG)) {
|
|
|
|
printf("H5T_NATIVE_LLONG");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_ULLONG)) {
|
|
|
|
printf("H5T_NATIVE_ULLONG");
|
|
|
|
} else {
|
|
|
|
printf("undefined integer");
|
|
|
|
}
|
|
|
|
break;
|
2008-09-16 23:52:51 +08:00
|
|
|
|
2008-05-01 03:51:13 +08:00
|
|
|
case H5T_FLOAT:
|
|
|
|
if (H5Tequal(type, H5T_IEEE_F32BE)) {
|
|
|
|
printf("H5T_IEEE_F32BE");
|
|
|
|
} else if (H5Tequal(type, H5T_IEEE_F32LE)) {
|
|
|
|
printf("H5T_IEEE_F32LE");
|
|
|
|
} else if (H5Tequal(type, H5T_IEEE_F64BE)) {
|
|
|
|
printf("H5T_IEEE_F64BE");
|
|
|
|
} else if (H5Tequal(type, H5T_IEEE_F64LE)) {
|
|
|
|
printf("H5T_IEEE_F64LE");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_FLOAT)) {
|
|
|
|
printf("H5T_NATIVE_FLOAT");
|
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_DOUBLE)) {
|
|
|
|
printf("H5T_NATIVE_DOUBLE");
|
2005-07-23 09:55:12 +08:00
|
|
|
#if H5_SIZEOF_LONG_DOUBLE !=0
|
2008-05-01 03:51:13 +08:00
|
|
|
} else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) {
|
|
|
|
printf("H5T_NATIVE_LDOUBLE");
|
2005-07-23 09:55:12 +08:00
|
|
|
#endif
|
2008-05-01 03:51:13 +08:00
|
|
|
} else {
|
|
|
|
printf("undefined float");
|
|
|
|
}
|
|
|
|
break;
|
2008-09-16 23:52:51 +08:00
|
|
|
|
2008-05-01 03:51:13 +08:00
|
|
|
}/*switch*/
|
2003-10-23 05:30:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
2003-10-29 01:40:05 +08:00
|
|
|
* Function: diff_basename
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
2005-08-14 04:53:35 +08:00
|
|
|
* Purpose: Returns a pointer to the last component absolute name
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
|
|
|
* Date: May 9, 2003
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
const char*
|
2003-10-29 01:40:05 +08:00
|
|
|
diff_basename(const char *name)
|
2003-10-23 05:30:19 +08:00
|
|
|
{
|
2008-05-01 03:51:13 +08:00
|
|
|
size_t i;
|
2008-09-16 23:52:51 +08:00
|
|
|
|
2008-05-01 03:51:13 +08:00
|
|
|
if (name==NULL)
|
|
|
|
return NULL;
|
2008-09-16 23:52:51 +08:00
|
|
|
|
2008-05-01 03:51:13 +08:00
|
|
|
/* Find the end of the base name */
|
|
|
|
i = strlen(name);
|
|
|
|
while (i>0 && '/'==name[i-1])
|
|
|
|
--i;
|
2008-09-16 23:52:51 +08:00
|
|
|
|
2008-05-01 03:51:13 +08:00
|
|
|
/* Skip backward over base name */
|
|
|
|
while (i>0 && '/'!=name[i-1])
|
|
|
|
--i;
|
2008-09-16 23:52:51 +08:00
|
|
|
|
2008-05-01 03:51:13 +08:00
|
|
|
return(name+i);
|
2003-10-23 05:30:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: get_type
|
|
|
|
*
|
|
|
|
* Purpose: Returns the type as a string
|
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
|
|
|
* Date: May 9, 2003
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
const char*
|
[svn-r14154] Description:
Finish deprecating last H5G symbol (H5G_obj_t) - yay!
Lots of misc. library fixes to remove confusion between links and
objects. The tools could still use another pass, to remove h5trav_type_t type
and make the correct distinction between links & objects.
Tested on:
FreeBSD/32 6.2 (duty) in debug mode
FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN,
in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
AIX/32 5.3 (copper) w/FORTRAN, w/parallel, in production mode
Mac OS X/32 10.4.10 (amazon) in debug mode
2007-09-26 06:18:33 +08:00
|
|
|
get_type(h5trav_type_t type)
|
2003-10-23 05:30:19 +08:00
|
|
|
{
|
[svn-r14154] Description:
Finish deprecating last H5G symbol (H5G_obj_t) - yay!
Lots of misc. library fixes to remove confusion between links and
objects. The tools could still use another pass, to remove h5trav_type_t type
and make the correct distinction between links & objects.
Tested on:
FreeBSD/32 6.2 (duty) in debug mode
FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN,
in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
AIX/32 5.3 (copper) w/FORTRAN, w/parallel, in production mode
Mac OS X/32 10.4.10 (amazon) in debug mode
2007-09-26 06:18:33 +08:00
|
|
|
switch(type) {
|
|
|
|
case H5TRAV_TYPE_DATASET:
|
|
|
|
return("H5G_DATASET");
|
|
|
|
case H5TRAV_TYPE_GROUP:
|
|
|
|
return("H5G_GROUP");
|
|
|
|
case H5TRAV_TYPE_NAMED_DATATYPE:
|
|
|
|
return("H5G_TYPE");
|
|
|
|
case H5TRAV_TYPE_LINK:
|
|
|
|
return("H5G_LINK");
|
|
|
|
case H5TRAV_TYPE_UDLINK:
|
|
|
|
return("H5G_UDLINK");
|
|
|
|
default:
|
|
|
|
return("unknown type");
|
|
|
|
}
|
2003-10-23 05:30:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: get_sign
|
|
|
|
*
|
|
|
|
* Purpose: Returns the sign as a string
|
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
|
|
|
* Date: May 9, 2003
|
|
|
|
*
|
2005-08-14 04:53:35 +08:00
|
|
|
* Comments:
|
2003-10-23 05:30:19 +08:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
const char*
|
|
|
|
get_sign(H5T_sign_t sign)
|
|
|
|
{
|
2008-05-01 03:51:13 +08:00
|
|
|
switch (sign)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
return("H5T_SGN_ERROR");
|
|
|
|
case H5T_SGN_NONE:
|
|
|
|
return("H5T_SGN_NONE");
|
|
|
|
case H5T_SGN_2:
|
|
|
|
return("H5T_SGN_2");
|
|
|
|
}
|
2003-10-23 05:30:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: get_class
|
|
|
|
*
|
|
|
|
* Purpose: Returns the class as a string
|
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
|
|
|
* Date: May 9, 2003
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
const char*
|
|
|
|
get_class(H5T_class_t tclass)
|
|
|
|
{
|
2008-05-01 03:51:13 +08:00
|
|
|
switch (tclass)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
return("Invalid class");
|
|
|
|
case H5T_TIME:
|
|
|
|
return("H5T_TIME");
|
|
|
|
case H5T_INTEGER:
|
|
|
|
return("H5T_INTEGER");
|
|
|
|
case H5T_FLOAT:
|
|
|
|
return("H5T_FLOAT");
|
|
|
|
case H5T_STRING:
|
|
|
|
return("H5T_STRING");
|
|
|
|
case H5T_BITFIELD:
|
|
|
|
return("H5T_BITFIELD");
|
|
|
|
case H5T_OPAQUE:
|
|
|
|
return("H5T_OPAQUE");
|
|
|
|
case H5T_COMPOUND:
|
|
|
|
return("H5T_COMPOUND");
|
|
|
|
case H5T_REFERENCE:
|
|
|
|
return("H5T_REFERENCE");
|
|
|
|
case H5T_ENUM:
|
|
|
|
return("H5T_ENUM");
|
|
|
|
case H5T_VLEN:
|
|
|
|
return("H5T_VLEN");
|
|
|
|
case H5T_ARRAY:
|
|
|
|
return("H5T_ARRAY");
|
|
|
|
}
|
2003-10-23 05:30:19 +08:00
|
|
|
}
|
|
|
|
|
2004-07-21 03:21:03 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: print_found
|
|
|
|
*
|
|
|
|
* Purpose: print number of differences found
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void print_found(hsize_t nfound)
|
|
|
|
{
|
2006-03-23 04:53:05 +08:00
|
|
|
if(g_Parallel)
|
|
|
|
parallel_print("%"H5_PRINTF_LL_WIDTH"u differences found\n", (unsigned long_long)nfound);
|
|
|
|
else
|
|
|
|
HDfprintf(stdout,"%Hu differences found\n",nfound);
|
2004-07-21 03:21:03 +08:00
|
|
|
}
|
|
|
|
|
2003-10-23 05:30:19 +08:00
|
|
|
|
|
|
|
|