-
Notifications
You must be signed in to change notification settings - Fork 376
/
Copy pathgshhg_version.c
166 lines (143 loc) · 5.22 KB
/
gshhg_version.c
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
156
157
158
159
160
161
162
163
164
165
166
/*--------------------------------------------------------------------
*
* Copyright (c) 1991-2025 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
* See LICENSE.TXT file for copying and redistribution conditions.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 3 or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* Contact info: www.generic-mapping-tools.org
*--------------------------------------------------------------------*/
/*
* gshhg_version.c contains helper functions to access the GSHHG version
*
* Author: Florian Wobbe
* Date: 5-APR-2012
* Version: 5
*
* Modules in this file:
*
* gshhg_get_version Obtain version information struct from GSHHG file
* gshhg_require_min_version Check if GSHHG file meets the min version
* requirement
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netcdf.h>
#include "gshhg_version.h"
#define BUF_SIZE 64
#define VERSION_ATT_NAME "version"
#define FAILURE_PREFIX "gshhg_version: "
#ifdef _MSC_VER
# pragma warning( disable : 4996 ) /* Suppress Visual Studio deprecation warnings */
# define PRIuS "Iu" /* size_t length specifier */
#else
# define PRIuS "zu" /* size_t length specifier */
#endif
/* Get value from VERSION_ATT_NAME of netCDF file and populate gshhg_version,
* gshhg_version_major, gshhg_version_minor, and gshhg_version_patch */
static int gshhg_get_version (const char* filename, struct GSHHG_VERSION *gshhg_version) {
int status; /* error status */
int ncid; /* netCDF ID */
size_t v_len; /* version length */
char gshhg_version_string[BUF_SIZE]; /* GSHHG version string */
/* open shoreline file */
status = nc_open(filename, NC_NOWRITE, &ncid);
if (status != NC_NOERR) {
fprintf(stderr, FAILURE_PREFIX "cannot open file \"%s\" (%d).\n", filename, status);
return 0;
}
/* get length of version string */
status = nc_inq_attlen (ncid, NC_GLOBAL, VERSION_ATT_NAME, &v_len);
if (status != NC_NOERR) {
nc_close(ncid);
fprintf(stderr, FAILURE_PREFIX "cannot inquire version attribute length from file \"%s\" (%d).\n", filename, status);
return 0;
}
if (v_len == 0 || v_len > BUF_SIZE-1) {
nc_close(ncid);
fprintf(stderr, FAILURE_PREFIX "invalid version attribute length: %" PRIuS "\n", v_len);
return 0;
}
/* get version string */
status = nc_get_att_text (ncid, NC_GLOBAL, VERSION_ATT_NAME, gshhg_version_string);
if (status != NC_NOERR) {
nc_close(ncid);
fprintf(stderr, FAILURE_PREFIX "cannot read version attribute from file \"%s\" (%d).\n", filename, status);
return 0;
}
/* close shoreline file */
nc_close(ncid);
/* null-terminate version string */
gshhg_version_string[v_len] = '\0';
/* parse version major, minor, and patch */
status = sscanf (gshhg_version_string, "%u.%u.%u",
&gshhg_version->major, &gshhg_version->minor, &gshhg_version->patch);
if (status != 3) {
fprintf(stderr, FAILURE_PREFIX "cannot parse version string \"%s\" (%d).\n", gshhg_version_string, status);
return 0;
}
return 1;
}
/* Check if GSHHG file meets the min version requirement */
int gshhg_require_min_version (const char* filename, const struct GSHHG_VERSION min_version) {
struct GSHHG_VERSION version;
/* get version of file */
if ( ! gshhg_get_version (filename, &version) )
return 0;
/* compare versions */
if ( version.major < min_version.major )
return 0;
if ( version.minor < min_version.minor )
return 0;
if ( version.patch < min_version.patch )
return 0;
#ifdef GSHHG_VERSION_DEBUG
fprintf (stderr, FAILURE_PREFIX "%s\n", filename);
#endif
return 1;
}
#ifdef STANDALONE
/* Compile with -DSTANDALONE to make an executable.
* This code is executed by CMake to check the installed GSHHG version. */
int main (int argc, char *argv[]) {
struct GSHHG_VERSION gshhg_version;
int status;
if (argc < 2 || argc > 3) {
fprintf(stderr, FAILURE_PREFIX "usage: gshhg_version file [min_required_version]\n");
return EXIT_FAILURE;
}
if ( ! gshhg_get_version (argv[1], &gshhg_version) )
return EXIT_FAILURE;
/* return version string and exit */
fprintf(stdout, "%d.%d.%d\n",
gshhg_version.major,
gshhg_version.minor,
gshhg_version.patch);
if (argc > 2) {
/* do min version check */
struct GSHHG_VERSION required_version;
status = sscanf (argv[2], "%u.%u.%u",
&required_version.major,
&required_version.minor,
&required_version.patch);
if ( status != 3 ) {
fprintf (stderr, FAILURE_PREFIX "cannot parse version string \"%s\" (%d).\n", argv[2], status);
}
if ( ! gshhg_require_min_version (argv[1], required_version) ) {
/* version too old */
fprintf (stderr, FAILURE_PREFIX "version of %s < min required version %s.\n", argv[1], argv[2]);
return -1;
}
}
/* version >= min required version */
return EXIT_SUCCESS;
}
#endif /* STANDALONE */