1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF.  The full HDF copyright notice, including       *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 #include "hdiff.h"
15 #include "hdiff_list.h"
16 #include "hdiff_mattbl.h"
17 
18 #include "vgint.h"
19 
20 static void fmt_print(uint8 *x, int32 type);
21 static uint32 vdata_cmp(int32  vs1, int32  vs2, char   *gname, char   *cname, diff_opt_t * opt);
22 
23 
24 /*-------------------------------------------------------------------------
25  * Function: diff_vs
26  *
27  * Purpose: diff for VS
28  *
29  * Return: Number of differences found
30  *
31  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
32  *
33  * Date: August 26, 2003
34  *
35  *-------------------------------------------------------------------------
36  */
37 
diff_vs(int32 file1_id,int32 file2_id,int32 ref1,int32 ref2,diff_opt_t * opt)38 uint32 diff_vs( int32 file1_id,
39                 int32 file2_id,
40                 int32 ref1,
41                 int32 ref2,
42                 diff_opt_t * opt)
43 {
44  int32 vdata1_id,             /* vdata identifier */
45        n_records1,            /* number of records */
46        vdata1_size,
47        interlace1_mode,
48        vdata2_id=-1,          /* vdata identifier */
49        n_records2,            /* number of records */
50        vdata2_size,
51        interlace2_mode;
52  char  vdata1_name [VSNAMELENMAX];
53  char  vdata1_class[VSNAMELENMAX];
54  char  fieldname1_list[VSFIELDMAX*FIELDNAMELENMAX];
55  char  vdata2_name [VSNAMELENMAX];
56  char  vdata2_class[VSNAMELENMAX];
57  char  fieldname2_list[VSFIELDMAX*FIELDNAMELENMAX];
58  uint32 nfound=0;
59 
60 
61 
62 /*-------------------------------------------------------------------------
63  * object 1
64  *-------------------------------------------------------------------------
65  */
66 
67  if (Vstart (file1_id)==FAIL) {
68   printf("Error: Could not start VS interface in VS ref %ld\n", ref1);
69   goto out;
70  }
71 
72  if ((vdata1_id  = VSattach (file1_id, ref1, "r")) == FAIL ){
73   printf( "Failed to attach VS ref %ld\n", ref1);
74   goto out;
75  }
76  if (VSgetname  (vdata1_id, vdata1_name) == FAIL ){
77   printf( "Failed to name for VS ref %ld\n", ref1);
78   goto out;
79  }
80  if (VSgetclass (vdata1_id, vdata1_class) == FAIL ){
81   printf( "Failed to name for VS ref %ld\n", ref1);
82   goto out;
83  }
84 
85  if (VSinquire(vdata1_id, &n_records1, &interlace1_mode, fieldname1_list,
86   &vdata1_size, vdata1_name) == FAIL) {
87   printf( "Failed to get info for VS ref %ld\n", ref1);
88   goto out;
89  }
90 
91  if (VFnfields(vdata1_id)== FAIL ){
92   printf( "Failed getting fields forVS ref %ld\n", ref1);
93   goto out;
94  }
95 
96 
97 /*-------------------------------------------------------------------------
98  * object 2
99  *-------------------------------------------------------------------------
100  */
101 
102  if (Vstart (file2_id)==FAIL) {
103   printf("Error: Could not start VS interface in VS ref %ld\n", ref1);
104   goto out;
105  }
106 
107  if ((vdata2_id  = VSattach (file2_id, ref2, "r")) == FAIL ){
108   printf( "Failed to attach VS ref %ld\n", ref2);
109   goto out;
110  }
111  if (VSgetname  (vdata2_id, vdata2_name) == FAIL ){
112   printf( "Failed to name for VS ref %ld\n", ref2);
113   goto out;
114  }
115  if (VSgetclass (vdata2_id, vdata2_class) == FAIL ){
116   printf( "Failed to name for VS ref %ld\n", ref2);
117   goto out;
118  }
119 
120  if (VSinquire(vdata2_id, &n_records2, &interlace2_mode, fieldname2_list,
121   &vdata2_size, vdata2_name) == FAIL) {
122   printf( "Failed to get info for VS ref %ld\n", ref2);
123   goto out;
124  }
125 
126  if (VFnfields(vdata2_id)== FAIL ){
127   printf( "Failed getting fields forVS ref %ld\n", ref2);
128   goto out;
129  }
130 
131 /*-------------------------------------------------------------------------
132  * check for input VSs
133  *-------------------------------------------------------------------------
134  */
135 
136  if (opt->nuvars > 0)   /* if specified vdata is selected */
137  {
138   int imatch = 0, j;
139   for (j = 0; j < opt->nuvars; j++)
140   {
141    if (strcmp(vdata1_name, opt->uvars[j]) == 0)
142    {
143     imatch = 1;
144     break;
145    }
146   }
147   if (imatch == 0)
148   {
149    goto do_nothing;
150   }
151  }
152 
153 
154 /*-------------------------------------------------------------------------
155  * Comparing
156  *-------------------------------------------------------------------------
157  */
158 
159  if (opt->verbose)
160   printf("Comparing <%s>\n",vdata1_name);
161 
162  nfound=vdata_cmp(vdata1_id,vdata2_id,vdata1_name,vdata1_class,opt);
163 
164 do_nothing:
165 
166  /* terminate access to the VSs */
167  if (VSdetach (vdata1_id)==FAIL) {
168      printf( "Failed to dettach VS ref %ld\n", ref1);
169      goto out;
170  }
171  if (vdata2_id!=-1)
172  {
173      if (VSdetach (vdata2_id)==FAIL) {
174          printf( "Failed to dettach VS ref %ld\n", ref2);
175          goto out;
176      }
177  }
178 
179 
180  return nfound;
181 
182 out:
183 
184  opt->err_stat = 1;
185  return 0;
186 }
187 
188 
189 
190 /*-------------------------------------------------------------------------
191  * Function: vdata_cmp
192  *
193  * Purpose: compare vdata
194  *
195  *-------------------------------------------------------------------------
196  */
197 
vdata_cmp(int32 vs1,int32 vs2,char * gname,char * cname,diff_opt_t * opt)198 static uint32 vdata_cmp(int32  vs1,
199                         int32  vs2,
200                         char   *gname,
201                         char   *cname,
202                         diff_opt_t * opt)
203 {
204  int32   i, j, k, iflag;
205  uint32  err_cnt;
206  int32   nv1, interlace1, vsize1;
207  int32   vsotag1;
208  char    fields1[VSFIELDMAX*FIELDNAMELENMAX];
209  char    vsclass1[VSNAMELENMAX], vsname1[VSNAMELENMAX];
210  int32   nv2, interlace2, vsize2;
211  int32   vsotag2;
212  char    fields2[VSFIELDMAX*FIELDNAMELENMAX];
213  char    vsclass2[VSNAMELENMAX], vsname2[VSNAMELENMAX];
214  uint8   *buf1, *buf2, *b1, *b2;
215  int32   off1[60], off2[60];
216  DYN_VWRITELIST *w1, *w2;
217  uint32  nfound=0;
218  uint32  max_err_cnt = opt->max_err_cnt;
219 
220  VSinquire(vs1, &nv1, &interlace1, fields1, &vsize1, vsname1);
221  VSinquire(vs2, &nv2, &interlace2, fields2, &vsize2, vsname2);
222 
223  vsotag1 = VSQuerytag(vs1);
224  VSgetclass(vs1,vsclass1);
225 
226  vsotag2 = VSQuerytag(vs2);
227  VSgetclass(vs2,vsclass2);
228 
229  if (vsotag1 != vsotag2 || nv1 != nv2 || interlace1 != interlace2 ||
230   strcmp(fields1, fields2) != 0 || strcmp(vsclass1, vsclass2) != 0 ||
231   (strcmp(vsclass1, "Attr0.0") != 0 && vsize1 != vsize2))
232  {
233   printf("\n---------------------------\n");
234   printf("Vdata Name: %s <%s/%s> (Different attributes)\n",
235    vsname1, gname, cname);
236   printf("> <%ld> nrec=%ld interlace=%ld fld=[%s] vsize=%ld class={%s})\n",
237    vsotag1, nv1, interlace1, fields1, vsize1, vsclass1);
238   printf("< <%ld> nrec=%ld interlace=%ld fld=[%s] vsize=%ld class={%s})\n",
239    vsotag2, nv2, interlace2, fields2, vsize2, vsclass2);
240   return 0;
241  }
242 
243 
244  /* compare the data */
245 
246     buf1 = (uint8 *)HDmalloc((unsigned) (nv1 * vsize1));
247     buf2 = (uint8 *)HDmalloc((unsigned) (nv2 * vsize2));
248  if (!buf1 || !buf2)
249  {
250   printf("Out of memory!");
251   opt->err_stat = 1;
252   return 0;
253  }
254 
255  VSsetfields(vs1, fields1);
256  VSread(vs1, buf1, nv1, interlace1);
257  w1 = (DYN_VWRITELIST*) vswritelist(vs1);
258 
259  VSsetfields(vs2, fields2);
260  VSread(vs2, buf2, nv2, interlace2);
261  w2 = (DYN_VWRITELIST*) vswritelist(vs2);
262 
263  b1 = buf1;
264  b2 = buf2;
265 
266  for (j=0; j < w1->n; j++)
267   off1[j] = DFKNTsize(w1->type[j] | DFNT_NATIVE);
268 
269  for (j=0; j < w2->n; j++)
270   off2[j] = DFKNTsize(w2->type[j] | DFNT_NATIVE);
271 
272  iflag = 0;
273 
274  err_cnt = 0;
275 
276  if (vsize1 == vsize2)
277  {
278   for (i=0; i<nv1; i++)
279   {
280             if (HDmemcmp(b1, b2, (size_t)vsize1) == 0)
281    {
282     b1 += vsize1;
283     b2 += vsize2;
284     continue;
285    }
286    if (iflag == 0)
287    {
288     iflag = 1;         /* there is a difference */
289     printf("\n---------------------------\n");
290     printf("Vdata Name: %s (Data record comparison)\n",
291      vsname1);
292     nfound ++;
293    }
294 
295    printf("> %ld: ", i);
296    for (j=0; j<w1->n; j++)
297    {
298     for (k=0; k<w1->order[j]; k++)
299     {
300      fmt_print(b1, w1->type[j]);
301      b1 += off1[j];
302      if (w1->type[j] != DFNT_CHAR)
303       putchar(' ');
304     }
305    }
306    putchar('\n');
307    printf("< %ld: ", i);
308    for (j=0; j<w2->n; j++)
309    {
310     for (k=0; k<w2->order[j]; k++)
311     {
312      fmt_print(b2, w2->type[j]);
313      b2 += off2[j];
314      if (w2->type[j] != DFNT_CHAR)
315       putchar(' ');
316     }
317    }
318    putchar('\n');
319 
320    if (max_err_cnt > 0)
321    {
322     err_cnt++;
323     if (err_cnt >= max_err_cnt)
324      break;
325    }
326   }
327  }
328  else
329  {
330   printf("****....\n");
331   for (i=0; i<nv1; i++)
332   {
333    if (iflag == 0)
334    {
335     iflag = 1;         /* there is a difference */
336     printf("\n---------------------------\n");
337     printf("Vdata Name: %s (Data record comparison)\n",
338      vsname1);
339     nfound ++;
340    }
341    printf("> %ld: ", i);
342    for (j=0; j<w1->n; j++)
343    {
344     for (k=0; k<w1->order[j]; k++)
345     {
346      fmt_print(b1, w1->type[j]);
347      b1 += off1[j];
348      if (w1->type[j] != DFNT_CHAR)
349       putchar(' ');
350     }
351    }
352    putchar('\n');
353    printf("< %ld: ", i);
354    for (j=0; j<w2->n; j++)
355    {
356     for (k=0; k<w2->order[j]; k++)
357     {
358      fmt_print(b2, w2->type[j]);
359      b1 += off2[j];
360      if (w2->type[j] != DFNT_CHAR)
361       putchar(' ');
362     }
363    }
364    putchar('\n');
365 
366    if (max_err_cnt > 0)
367    {
368     err_cnt++;
369     if (err_cnt >= max_err_cnt)
370      break;
371    }
372   }
373 
374  }
375 
376     if (buf1) HDfree((char *) buf1);
377     if (buf2) HDfree((char *) buf2);
378 
379  return nfound;
380 }
381 
382 
383 /*-------------------------------------------------------------------------
384  * Function: fmt_print
385  *
386  * Purpose: print HDF types
387  *
388  *-------------------------------------------------------------------------
389  */
390 
391 void
fmt_print(uint8 * x,int32 type)392 fmt_print(uint8 *x, int32 type)
393 {
394  int16    s = 0;
395  int32    l = 0;
396  float32  f = 0;
397  float64  d = 0;
398 
399  switch(type)
400  {
401  case DFNT_CHAR:
402   putchar(*x);
403   break;
404 
405  case DFNT_UINT8:
406  case DFNT_INT8:
407   printf("%02x ", *x);
408   break;
409 
410  case DFNT_UINT16:
411  case DFNT_INT16:
412   HDmemcpy(&s, x, sizeof(int16));
413   printf("%d", s);
414   break;
415 
416  case DFNT_UINT32:
417   HDmemcpy(&l, x, sizeof(int32));
418   printf("%lu", l);
419   break;
420 
421  case DFNT_INT32:
422   HDmemcpy(&l, x, sizeof(int32));
423   printf("%ld", l);
424   break;
425 
426  case DFNT_FLOAT32:
427   HDmemcpy(&f, x, sizeof(float32));
428   printf("%f", f);
429   break;
430 
431  case DFNT_FLOAT64:
432   HDmemcpy(&d, x, sizeof(float64));
433   printf("%f", d);
434   break;
435 
436  default:
437   fprintf(stderr,"sorry, type [%ld] not supported\n", type);
438   break;
439 
440  }
441 }
442