File: g2c_test_util.c

package info (click to toggle)
g2clib 2.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,524 kB
  • sloc: ansic: 28,287; python: 76; sh: 46; makefile: 26
file content (155 lines) | stat: -rw-r--r-- 4,985 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* This part of the NCEPLIBS-g2c project.
 *
 * These are utility functions for tests.
 *
 * Ed Hartnett 11/26/22
 */
#include "grib2_int.h"

#define MAX_VALUE_LEN 25
#define NUM_MATCHING 5
#define MAX_LINE_LEN 256

/* Compare two strings, ignoring leading spaces.
 *
 * Ed Hartnett 10/6/22
 */
static int
cmpString(const void *p, const void *q)
{
    const char *pp = (const char *)p;
    const char *qq = (const char *)q;
    int i, j;
    for (i = 0; isblank(pp[i]); ++i)
        ;
    for (j = 0; isblank(qq[j]); ++j)
        ;
    return strcmp(pp + i, qq + j);
}

/* Return 0 if two lines of the DEGRIB2 output are euqal.
 *
 * For most lines this means they must be exactly equal. Lines that
 * show the min, avg, and max values may be slightly different from
 * the reference file, because the intel compiler produces slight
 * different results.
 *
 * All the sscanf calls cause the code scanner to complain about
 * possible overflow. Hence all the memcpys to convince the scanner
 * that we are not going to overwrite any memory.
 *
 * Ed Hartnett 10/6/22
 */
int
degrib2_lines_not_equal(int cnt, char *line1, char *l2)
{
    char long_abbrev[MAX_LINE_LEN + 1], long_cmin[MAX_LINE_LEN + 1];
    char long_cavg[MAX_LINE_LEN + 1], long_cmax[MAX_LINE_LEN + 1];
    char abbrev1[G2C_MAX_NOAA_ABBREV_LEN + 1];
    char abbrev2[G2C_MAX_NOAA_ABBREV_LEN + 1];
    char cmin1[MAX_VALUE_LEN + 1], cavg1[MAX_VALUE_LEN + 1], cmax1[MAX_VALUE_LEN + 1];
    char cmin2[MAX_VALUE_LEN + 1], cavg2[MAX_VALUE_LEN + 1], cmax2[MAX_VALUE_LEN + 1];
    char my_line[MAX_LINE_LEN + 1];
    int len;

    /* If the lines are the same, we're done. */
    if (!cmpString(line1, l2))
        return 0;

    /* If the lines are different, is it a line like this:
       ( PARM= WIND ) :  MIN=               0.09999998 AVE=               5.64625024 MAX=              16.43000032
    */

    /* We have to go through some business to convince the code
     * scanner we are not going to overwrite any memory in our sscanf
     * calls. */
    len = strlen(line1) < MAX_LINE_LEN ? strlen(line1) : MAX_LINE_LEN;
    memcpy(my_line, line1, len);
    my_line[len] = 0;
    if (sscanf(my_line, "( PARM= %s ) :  MIN=               %s AVE=               %s MAX=              %s",
               long_abbrev, long_cmin, long_cavg, long_cmax) == 4)
    {
        memcpy(abbrev1, long_abbrev, G2C_MAX_NOAA_ABBREV_LEN);
        abbrev1[G2C_MAX_NOAA_ABBREV_LEN] = 0;
        memcpy(cmin1, long_cmin, MAX_VALUE_LEN);
        cmin1[MAX_VALUE_LEN] = 0;
        memcpy(cavg1, long_cavg, MAX_VALUE_LEN);
        cavg1[MAX_VALUE_LEN] = 0;
        memcpy(cmax1, long_cmax, MAX_VALUE_LEN);
        cmax1[MAX_VALUE_LEN] = 0;

        /* Wow, that was annoying. And now we have to do it again! */
        len = strlen(l2) < MAX_LINE_LEN ? strlen(l2) : MAX_LINE_LEN;
        memcpy(my_line, l2, len);
        my_line[len] = 0;
        if (sscanf(my_line, "( PARM= %s ) :  MIN=               %s AVE=               %s MAX=              %s",
                   long_abbrev, long_cmin, long_cavg, long_cmax) != 4)
            return G2C_ERROR;
        memcpy(abbrev2, long_abbrev, G2C_MAX_NOAA_ABBREV_LEN);
        abbrev2[G2C_MAX_NOAA_ABBREV_LEN] = 0;
        memcpy(cmin2, long_cmin, MAX_VALUE_LEN);
        cmin2[MAX_VALUE_LEN] = 0;
        memcpy(cavg2, long_cavg, MAX_VALUE_LEN);
        cavg2[MAX_VALUE_LEN] = 0;
        memcpy(cmax2, long_cmax, MAX_VALUE_LEN);
        cmax2[MAX_VALUE_LEN] = 0;

        /* Print results. */
        printf("\nabbrev1 %s min1 %s avg1 %s max1 %s\n", abbrev1, cmin1, cavg1, cmax1);
        printf("abbrev2 %s min2 %s avg2 %s max2 %s\n", abbrev2, cmin2, cavg2, cmax2);

        /* Check that results match. */
        if (strcmp(abbrev1, abbrev2))
            return G2C_ERROR;
        if (strncmp(cmin1, cmin2, NUM_MATCHING))
            return G2C_ERROR;
        if (strncmp(cavg1, cavg2, NUM_MATCHING))
            return G2C_ERROR;
        if (strncmp(cmax1, cmax2, NUM_MATCHING))
            return G2C_ERROR;
    }
    else
    {
        printf("\nline %d\n", cnt);
        printf("\n%s\n", line1);
        printf("expected:\n%s\n", l2);
        return G2C_ERROR;
    }

    return G2C_NOERROR;
}

/* Return 0 if two degrib2 files are the same.
 *
 * Ed Hartnett 10/6/22
 */
int
compare_degrib2_files2(char *fname1, char *fname2)
{
    FILE *fp1, *fp2;
    char l1[MAX_LINE_LEN + 1], l2[MAX_LINE_LEN + 1];
    int cnt = 1;

    /* Open the two files. */
    if (!(fp1 = fopen(fname1, "r")))
        return G2C_ERROR;
    if (!(fp2 = fopen(fname2, "r")))
        return G2C_ERROR;

    /* Check each line in the file. */
    while (fgets(l1, MAX_LINE_LEN, fp1))
    {
        if (!fgets(l2, MAX_LINE_LEN, fp2))
            return G2C_ERROR;
        /* printf("l1: %s\n", l1); */
        /* printf("l2: %s\n", l2); */
        if (degrib2_lines_not_equal(cnt++, l1, l2))
            return G2C_ERROR;
    }

    /* Close files. */
    fclose(fp1);
    fclose(fp2);

    return G2C_NOERROR;
}