GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
find_file.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/find_file.c
3
4 \brief GIS library - Find GRASS data base files
5
6 (C) 2001-2009 by the GRASS Development Team
7
8 This program is free software under the
9 GNU General Public License (>=v2).
10 Read the file COPYING that comes with GRASS
11 for details.
12
13 \author Original author CERL
14 */
15
16#include <string.h>
17#include <unistd.h>
18#include <grass/gis.h>
19#include <grass/glocale.h>
20
21static const char *find_element(int misc, const char *dir, const char *element)
22{
23 static const char *cell_elements[] = {"cellhd", "cell", "cats",
24 "colr", "hist", "cell_misc",
25 "fcell", "g3dcell", NULL};
26 static const char *dig_elements[] = {
27 "dig", "dig_att", "dig_plus", "dig_cats", "dig_misc", "reg", NULL};
28 const char *search = misc ? dir : element;
29 int i;
30
31 for (i = 1; cell_elements[i]; i++)
32 if (strcmp(search, cell_elements[i]) == 0)
33 return cell_elements[0];
34 for (i = 1; dig_elements[i]; i++)
35 if (strcmp(search, dig_elements[i]) == 0)
36 return dig_elements[0];
37 return element;
38}
39
40static const char *find_file(int misc, const char *dir, const char *element,
41 const char *name, const char *mapset)
42{
43 char path[GPATH_MAX];
44 char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
45 const char *pname, *pmapset;
46 int n;
47
48 if (*name == 0)
49 return NULL;
50 *path = 0;
51
52 /*
53 * if name is in the fully qualified format, split it into
54 * name, mapset (overrides what was in mapset)
55 */
56 if (G_name_is_fully_qualified(name, xname, xmapset)) {
57 pname = xname;
58 pmapset = xmapset;
59 }
60 else {
61 pname = name;
62 pmapset = mapset;
63 }
64
65 if (strcmp(element, "vector") == 0 && pmapset &&
66 strcasecmp(pmapset, "ogr") == 0) {
67 /* don't check for virtual OGR mapset */
68 return G_store(pmapset);
69 }
70
71 /*
72 * reject illegal names and mapsets
73 */
74 if (G_legal_filename(pname) == -1)
75 return NULL;
76
77 if (pmapset && *pmapset && G_legal_filename(pmapset) == -1)
78 return NULL;
79
80 /*
81 * if no specific mapset is to be searched
82 * then search all mapsets in the mapset search list
83 */
84 if (pmapset == NULL || *pmapset == 0) {
85 int cnt = 0;
86 const char *pselmapset = NULL;
87 const char *pelement = find_element(misc, dir, element);
88
89 for (n = 0; (pmapset = G_get_mapset_name(n)); n++) {
90 if (misc && element == pelement)
91 G_file_name_misc(path, dir, pelement, pname, pmapset);
92 else
93 G_file_name(path, pelement, pname, pmapset);
94 if (access(path, 0) == 0) {
95 if (!pselmapset)
96 pselmapset = pmapset;
97 else if (element == pelement)
98 G_important_message(_("Data element '%s/%s' was found in "
99 "more mapsets (also found in <%s>)"),
100 element, pname, pmapset);
101 cnt++;
102 }
103 }
104 if (cnt > 0) {
105 if (misc)
106 G_file_name_misc(path, dir, element, pname, pselmapset);
107 else
108 G_file_name(path, element, name, pselmapset);
109 if (access(path, 0) == 0) {
110 /* If the same name exists in more mapsets and print a warning
111 */
112 if (cnt > 1 && element == pelement)
113 G_important_message(_("Using <%s@%s>..."), pname,
114 pselmapset);
115
116 return G_store(pselmapset);
117 }
118 }
119 }
120 /*
121 * otherwise just look for the file in the specified mapset.
122 * since the name may have been qualified, mapset may point
123 * to the xmapset, so we must should it to
124 * permanent storage via G_store().
125 */
126 else {
127 if (misc)
128 G_file_name_misc(path, dir, element, pname, pmapset);
129 else
130 G_file_name(path, element, pname, pmapset);
131
132 if (access(path, 0) == 0)
133 return G_store(pmapset);
134 }
135
136 return NULL;
137}
138
139static const char *find_file1(int misc, const char *dir, const char *element,
140 char *name, const char *mapset)
141{
142 char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
143 const char *pname, *pmapset;
144 const char *mp;
145
146 if (G_name_is_fully_qualified(name, xname, xmapset)) {
147 pname = xname;
148 pmapset = xmapset;
149 }
150 else {
151 pname = name;
152 pmapset = mapset;
153 }
154
155 mp = find_file(misc, dir, element, pname, pmapset);
156
157 if (mp && name != pname)
158 strcpy(name, pname);
159
160 return mp;
161}
162
163/*!
164 * \brief Searches for a file from the mapset search list or in a
165 * specified mapset.
166 *
167 * Returns the mapset name where the file was found.
168 *
169 * If the user specifies a fully qualified element (name@mapset)
170 * which exists, then G_find_file() modifies "name"
171 * by removing the "@mapset" part.
172 *
173 * Rejects all names that begin with "."
174 *
175 * If <i>name</i> is of the form nnn in ppp then only mapset ppp
176 * is searched.
177 *
178 * \param element database element (eg, "cell", "cellhd", "colr", etc)
179 * \param name file name to look for
180 * \param mapset mapset to search. if mapset is "" will search in mapset search
181 * list
182 *
183 * \return pointer to a string with name of mapset where file was
184 * found, or NULL if not found
185 */
186const char *G_find_file(const char *element, char *name, const char *mapset)
187{
188 return find_file1(0, NULL, element, name, mapset);
189}
190
191/*!
192 * \brief Searches for a misc file from the mapset search list or in a
193 * specified mapset.
194 *
195 * Returns the mapset name where the misc file was found.
196 * Paths to misc files currently follow structure:
197 * mapset/dir/name/element
198 *
199 * \param dir file directory
200 * \param element database element (eg, "cell", "cellhd", "colr", etc)
201 * \param name file name to look for
202 * \param mapset mapset to search. if mapset is "" will search in mapset search
203 * list
204 *
205 * \return pointer to a string with name of mapset where file was
206 * found, or NULL if not found
207 */
208const char *G_find_file_misc(const char *dir, const char *element, char *name,
209 const char *mapset)
210{
211 return find_file1(1, dir, element, name, mapset);
212}
213
214/*!
215 * \brief Searches for a file from the mapset search list or in a
216 * specified mapset. (look but don't touch)
217 *
218 * Returns the mapset name where the file was found.
219 *
220 * Exactly the same as G_find_file() except that if <i>name</i> is in
221 * the form "<i>name@mapset</i>", and is found, G_find_file2() will
222 * not alter <i>name</i> by removing the "@<i>mapset</i>" part.
223 *
224 * Rejects all names that begin with "."
225 *
226 * \param element database element (eg, "cell", "cellhd", "colr", etc)
227 * \param name file name to look for
228 * \param mapset mapset to search. if mapset is "" will search in mapset
229 * search list
230 *
231 * \return pointer to a string with name of mapset where file was
232 * found, or NULL if not found
233 */
234const char *G_find_file2(const char *element, const char *name,
235 const char *mapset)
236{
237 return find_file(0, NULL, element, name, mapset);
238}
239
240/*!
241 * \brief Searches for a misc file from the mapset search list or in a
242 * specified mapset. (look but don't touch)
243 *
244 * Returns the mapset name where the misc file was found.
245 * Paths to misc files currently follow structure:
246 * mapset/dir/name/element
247 *
248 * \param dir file directory
249 * \param element database element (eg, "cell", "cellhd", "colr", etc)
250 * \param name file name to look for
251 * \param mapset mapset to search. if mapset is "" will search in mapset
252 * search list
253 *
254 * \return pointer to a string with name of mapset where file was
255 * found, or NULL if not found
256 */
257const char *G_find_file2_misc(const char *dir, const char *element,
258 const char *name, const char *mapset)
259{
260 return find_file(1, dir, element, name, mapset);
261}
#define NULL
Definition ccmath.h:32
char * G_file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
Definition file_name.c:61
char * G_file_name_misc(char *path, const char *dir, const char *element, const char *name, const char *mapset)
Builds full path names to GIS misc data files.
Definition file_name.c:101
const char * G_find_file2(const char *element, const char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:234
const char * G_find_file_misc(const char *dir, const char *element, char *name, const char *mapset)
Searches for a misc file from the mapset search list or in a specified mapset.
Definition find_file.c:208
const char * G_find_file2_misc(const char *dir, const char *element, const char *name, const char *mapset)
Searches for a misc file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:257
const char * G_find_file(const char *element, char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset.
Definition find_file.c:186
void G_important_message(const char *msg,...)
Print a message to stderr even in brief mode (verbosity=1)
Definition gis/error.c:130
int G_legal_filename(const char *s)
Check for legal database file name.
Definition legal_name.c:34
const char * G_get_mapset_name(int n)
Get name of the n'th mapset from the current mapset search path.
Definition mapset_nme.c:44
const char * name
Definition named_colr.c:6
int G_name_is_fully_qualified(const char *fullname, char *name, char *mapset)
Check if map name is fully qualified (map @ mapset)
Definition nme_in_mps.c:36
char * G_store(const char *s)
Copy string to allocated memory.
Definition strings.c:87
Definition path.h:15