GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
manage_signatures.c
Go to the documentation of this file.
1/*!
2 \file lib/imagery/manage_signatures.c
3
4 \brief Imagery Library - Signature file management functions
5
6 (C) 2021 by Maris Nartiss and the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10
11 \author Maris Nartiss
12 */
13
14#include <unistd.h>
15#include <string.h>
16
17#include <grass/gis.h>
18#include <grass/imagery.h>
19#include <grass/glocale.h>
20
21/*!
22 \brief Get signature directory
23
24 The directory will be in a form "signatures/<type>".
25
26 \param dir [GNAME_MAX] allocated string buffer
27 \param type I_SIGFILE_TYPE
28 */
30{
31 if (type == I_SIGFILE_TYPE_SIG) {
32 sprintf(dir, "signatures%csig", HOST_DIRSEP);
33 }
34 else if (type == I_SIGFILE_TYPE_SIGSET) {
35 sprintf(dir, "signatures%csigset", HOST_DIRSEP);
36 }
37 else if (type == I_SIGFILE_TYPE_LIBSVM) {
38 sprintf(dir, "signatures%clibsvm", HOST_DIRSEP);
39 }
40 else {
41 G_fatal_error("Programming error: unknown signature file type");
42 }
43}
44
45/*!
46 \brief Make signature dir
47
48 Creates directories for storage of signature files of specified type.
49 E.g. "<location>/<mapset>/signatures/<type>/"
50
51 \param type I_SIGFILE_TYPE
52 */
54{
55 char dir[GNAME_MAX];
56
57 G_make_mapset_object_group("signatures");
58 I_get_signatures_dir(dir, type);
60}
61
62static int list_by_type(I_SIGFILE_TYPE, const char *, int, char ***);
63
64/*!
65 * \brief Remove a signature file
66 *
67 * If removal fails, prints a warning and returns 1.
68 * It is safe to pass fully qualified names.
69 *
70 * \param type I_SIGFILE_TYPE signature type
71 * \param name of signature to remove
72 * \return 0 on success
73 * \return 1 on failure
74 */
76{
78 char dir[GNAME_MAX];
79
80 G_debug(1, "I_signatures_remove(%d, %s);", type, name);
81
82 /* Remove only if file is in the current mapset */
84 strcmp(xmapset, G_mapset()) != 0) {
85 G_warning(_("%s is not in the current mapset (%s)"), name, G_mapset());
86 return 1;
87 }
88 if (I_find_signature2(type, name, G_mapset())) {
89 I_get_signatures_dir(dir, type);
90 if (G_remove(dir, name) == 1) {
91 G_verbose_message(_("%s removed"), name);
92 return 0;
93 }
94 G_warning(_("Unable to remove %s signature"), name);
95 }
96 else
97 G_warning(_("%s is missing"), name);
98 return 1;
99}
100
101/*!
102 * \brief Copy a signature file
103 *
104 * If copy fails, prints warning messages and returns 1.
105 * It is safe to pass fully qualified names.
106 *
107 * \param type I_SIGFILE_TYPE signature type
108 * \param old_name of old signature
109 * \param old_mapset of old signature
110 * \param new_name of new signature
111 * \return 0 on success
112 * \return 1 on failure
113 */
115 const char *old_mapset, const char *new_name)
116{
119 char dir[GNAME_MAX];
120 const char *smapset;
122
123 G_debug(1, "I_signatures_copy(%d, %s@%s, %s);", type, old_name, old_mapset,
124 new_name);
125
126 /* Copy only if mapset of new name is the current mapset */
128 if (strcmp(tmapset, G_mapset()) != 0) {
129 G_warning(_("%s is not in the current mapset (%s)"), new_name,
130 G_mapset());
131 return 1;
132 }
133 }
134 else
136
138 if (!smapset) {
139 G_warning(_("%s is missing"), old_name);
140 return 1;
141 }
143
145
146 I_get_signatures_dir(dir, type);
147 /* Note – we need whole directory not just an element in it thus
148 G_file_name and not G_file_name_misc */
151
154 G_warning(_("Unable to copy <%s> to current mapset as <%s>"), mname,
155 tname);
156 G_free(mname);
157 return 1;
158 }
159 return 0;
160}
161
162/*!
163 * \brief Rename a signature file
164 *
165 * If rename fails, prints warning messages and returns 1.
166 * It is safe to pass fully qualified names.
167 *
168 * \param type I_SIGFILE_TYPE signature type
169 * \param old_name name of old signature
170 * \param new_name name of new signature
171 * \return 0 on success
172 * \return 1 on failure
173 */
175 const char *new_name)
176{
178 char dir[GNAME_MAX];
179 const char *smapset;
181
182 G_debug(1, "I_signatures_rename(%d, %s, %s);", type, old_name, new_name);
183
184 /* Rename only if source and destination mapset is the current mapset */
186 if (strcmp(tmapset, G_mapset()) != 0) {
187 G_warning(_("%s is not in the current mapset (%s)"), old_name,
188 G_mapset());
189 return 1;
190 }
191 }
192 else
195 if (strcmp(tmapset, G_mapset()) != 0) {
196 G_warning(_("%s is not in the current mapset (%s)"), new_name,
197 G_mapset());
198 return 1;
199 }
200 }
201 else
203
205 if (!smapset) {
206 G_warning(_("%s is missing"), old_name);
207 return 1;
208 }
209
210 I_get_signatures_dir(dir, type);
211 /* Note – we need whole directory not just an element in it thus
212 G_file_name and not G_file_name_misc */
215
216 if (G_rename_file(old_path, new_path) != 0) {
217 G_warning(_("Unable to rename <%s> to <%s>"), old_name, new_name);
218 return 1;
219 }
220 return 0;
221}
222
223/*!
224 * \brief Get list of existing signatures by type
225 *
226 * Fills passed list with fully qualified names of existing signatures.
227 *
228 * If no mapset is passed, all mapsets in the search path are used.
229 * If no signatures are found, returns 0 and list is set to NULL.
230 *
231 * The function will assign memory for the list. It is up to callee to
232 * free the memory of each list item and the list itself.
233 *
234 * \param type I_SIGFILE_TYPE signature type
235 * \param mapset optional mapset to search in or NULL
236 * \param out_list pointer to array of found signature strings or NULL if none
237 * found
238 * \return count of signature strings in the array
239 */
240int I_signatures_list_by_type(I_SIGFILE_TYPE type, const char *mapset,
241 char ***out_list)
242{
243 int base = 0;
244
245 *out_list = NULL;
246 if (mapset == NULL) {
247 for (int n = 0; (mapset = G_get_mapset_name(n)); n++) {
248 base += list_by_type(type, mapset, base, out_list);
249 }
250 }
251 else {
252 base += list_by_type(type, mapset, base, out_list);
253 }
254
255 return base;
256}
257
258/*!
259 * \brief Free memory allocated by I_signatures_list_by_type
260 *
261 * Calls G_free for all list items returned by I_signatures_list_by_type()
262 * Sets pointer to NULL to prevent accidental use after free.
263 *
264 * \param int Return value of I_signatures_list_by_type()
265 * \param pointer to array filled by I_signatures_list_by_type()
266 */
267void I_free_signatures_list(int count, char ***list)
268{
269 for (int n = 0; n < count; n++) {
270 G_free((*list)[n]);
271 }
272 G_free(*list);
273 *list = NULL;
274}
275
276static int list_by_type(I_SIGFILE_TYPE type, const char *mapset, int base,
277 char ***out_list)
278{
279 int count = 0;
280 char path[GPATH_MAX];
281 char dir[GNAME_MAX];
282 char **dirlist;
283
284 I_get_signatures_dir(dir, type);
285 G_file_name(path, dir, "", mapset);
286
287 if (access(path, 0) != 0) {
288 return count;
289 }
290
291 dirlist = G_ls2(path, &count);
292 if (count == 0) {
294 return count;
295 }
296
297 /* Make items fully qualified names */
298 int mapset_len = strlen(mapset);
299
300 *out_list = (char **)G_realloc(*out_list, (base + count) * sizeof(char *));
301 for (int i = 0; i < count; i++) {
302 size_t len = (strlen(dirlist[i]) + 1 + mapset_len + 1) * sizeof(char);
303 (*out_list)[base + i] = (char *)G_malloc(len);
304 snprintf((*out_list)[base + i], len, "%s@%s", dirlist[i], mapset);
305 G_free(dirlist[i]);
306 }
308
309 return count;
310}
#define NULL
Definition ccmath.h:32
int G_name_is_fully_qualified(const char *, char *, char *)
Check if map name is fully qualified (map @ mapset)
Definition nme_in_mps.c:36
int G_recursive_copy(const char *, const char *)
Copy recursively source directory to destination directory.
Definition copy_dir.c:69
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_realloc(p, n)
Definition defs/gis.h:141
int G_unqualified_name(const char *, const char *, char *, char *)
Returns unqualified map name (without @ mapset)
Definition nme_in_mps.c:134
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_rename_file(const char *, const char *)
Rename a file or a directory in the filesystem.
Definition rename.c:31
#define G_malloc(n)
Definition defs/gis.h:139
int G_make_mapset_object_group(const char *)
Create directory for group of elements of a given type.
Definition mapset_msc.c:75
void void G_verbose_message(const char *,...) __attribute__((format(printf
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition file_name.c:61
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition nme_in_mps.c:101
int G_remove(const char *, const char *)
Remove a database file.
Definition remove.c:43
const char * G_get_mapset_name(int)
Get name of the n'th mapset from the current mapset search path.
Definition mapset_nme.c:44
char ** G_ls2(const char *, int *)
Stores a sorted directory listing in an array.
Definition ls.c:94
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:33
const char * I_find_signature2(I_SIGFILE_TYPE, const char *, const char *)
Find mapset containing signature (look but don't touch)
#define GMAPSET_MAX
Definition gis.h:197
#define GPATH_MAX
Definition gis.h:199
#define GNAME_MAX
Definition gis.h:196
#define HOST_DIRSEP
Definition gis.h:240
#define _(str)
Definition glocale.h:10
I_SIGFILE_TYPE
Definition imagery.h:193
@ I_SIGFILE_TYPE_LIBSVM
Definition imagery.h:196
@ I_SIGFILE_TYPE_SIGSET
Definition imagery.h:195
@ I_SIGFILE_TYPE_SIG
Definition imagery.h:194
int count
int I_signatures_rename(I_SIGFILE_TYPE type, const char *old_name, const char *new_name)
Rename a signature file.
void I_free_signatures_list(int count, char ***list)
Free memory allocated by I_signatures_list_by_type.
void I_get_signatures_dir(char *dir, I_SIGFILE_TYPE type)
Get signature directory.
int I_signatures_remove(I_SIGFILE_TYPE type, const char *name)
Remove a signature file.
int I_signatures_list_by_type(I_SIGFILE_TYPE type, const char *mapset, char ***out_list)
Get list of existing signatures by type.
int I_signatures_copy(I_SIGFILE_TYPE type, const char *old_name, const char *old_mapset, const char *new_name)
Copy a signature file.
void I_make_signatures_dir(I_SIGFILE_TYPE type)
Make signature dir.
const char * name
Definition named_colr.c:6
Definition manage.h:4
Definition path.h:15
#define access
Definition unistd.h:7