GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
gis/list.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/list.c
3
4 \brief List elements
5
6 \author Unknown (probably CERL)
7
8 (C) 2000, 2010 by the GRASS Development Team
9
10 This program is free software under the GNU General Public License
11 (>=v2). Read the file COPYING that comes with GRASS for details.
12 */
13
14#include <stdlib.h>
15#include <unistd.h>
16#include <signal.h>
17#include <string.h>
18#include <sys/types.h>
19#include <dirent.h>
20
21#include <grass/gis.h>
22#include <grass/glocale.h>
23
24static int list_element(FILE *, const char *, const char *, const char *,
25 int (*)(const char *, const char *, char *));
26
27/*!
28 \brief General purpose list function
29
30 Will list files from all mapsets in the mapset list for a specified
31 database element.
32
33 Note: output is to stdout piped thru the more utility
34
35 \code
36 lister (char *name char *mapset, char* buf)
37 \endcode
38
39 Given file <em>name</em>, and <em>mapset</em>, lister() should
40 copy a string into 'buf' when called with name == "", should set
41 buf to general title for mapset list.
42
43 \param element database element (eg, "cell", "cellhd", etc.)
44 \param desc description for element (if NULL, element is used)
45 \param mapset mapset to be listed "" to list all mapsets in mapset search
46 list
47 "." will list current mapset
48 \param lister if given will call this routine to get a list title.
49 NULL if no titles desired.
50 */
51void G_list_element(const char *element, const char *desc, const char *mapset,
52 int (*lister)(const char *, const char *, char *))
53{
54 struct Popen pager;
55 int n;
56 FILE *more;
57 int count;
58
59 count = 0;
60 if (desc == 0 || *desc == 0)
61 desc = element;
62
63 /*
64 * G_popen() the more command to page the output
65 */
66 more = G_open_pager(&pager);
67 fprintf(more, "----------------------------------------------\n");
68
69 /*
70 * if no specific mapset is requested, list the mapsets
71 * from the mapset search list
72 * otherwise just list the specified mapset
73 */
74 if (mapset == 0 || *mapset == 0)
75 for (n = 0; (mapset = G_get_mapset_name(n)); n++)
76 count += list_element(more, element, desc, mapset, lister);
77 else
78 count += list_element(more, element, desc, mapset, lister);
79
80 if (count == 0) {
81 if (mapset == 0 || *mapset == 0)
82 fprintf(more, _("no %s files available in current mapset\n"), desc);
83 else
84 fprintf(more, _("no %s files available in mapset <%s>\n"), desc,
85 mapset);
86
87 fprintf(more, "----------------------------------------------\n");
88 }
89 /*
90 * close the more
91 */
92 G_close_pager(&pager);
93}
94
95static int list_element(FILE *out, const char *element, const char *desc,
96 const char *mapset,
97 int (*lister)(const char *, const char *, char *))
98{
99 char path[GPATH_MAX];
100 int count = 0;
101 char **list;
102 int i;
103
104 /*
105 * convert . to current mapset
106 */
107 if (strcmp(mapset, ".") == 0)
108 mapset = G_mapset();
109
110 /*
111 * get the full name of the GIS directory within the mapset
112 * and list its contents (if it exists)
113 *
114 * if lister() routine is given, the ls command must give 1 name
115 */
116 G_file_name(path, element, "", mapset);
117 if (access(path, 0) != 0) {
118 fprintf(out, "\n");
119 return count;
120 }
121
122 /*
123 * if a title so that we can call lister() with the names
124 * otherwise the ls must be forced into columnar form.
125 */
126
127 list = G_ls2(path, &count);
128
129 if (count > 0) {
130 fprintf(out, _("%s files available in mapset <%s>:\n"), desc, mapset);
131 if (lister) {
132 char title[400];
133 char name[GNAME_MAX];
134
135 *name = *title = 0;
136 lister(name, mapset, title);
137 if (*title)
138 fprintf(out, "\n%-18s %-.60s\n", name, title);
139 }
140 }
141
142 if (lister) {
143 for (i = 0; i < count; i++) {
144 char title[400];
145
146 lister(list[i], mapset, title);
147 fprintf(out, "%-18s %-.60s\n", list[i], title);
148 }
149 }
150 else
151 G_ls_format(list, count, 0, out);
152
153 fprintf(out, "\n");
154
155 for (i = 0; i < count; i++)
156 G_free((char *)list[i]);
157 if (list)
158 G_free(list);
159
160 return count;
161}
162
163/*!
164 \brief List specified type of elements. Application must release
165 the allocated memory.
166
167 \param element element type (G_ELEMENT_RASTER, G_ELEMENT_VECTOR,
168 G_ELEMENT_REGION ) \param gisbase path to GISBASE \param location location
169 name \param mapset mapset name
170
171 \return zero terminated array of element names
172 */
173char **G_list(int element, const char *gisbase, const char *location,
174 const char *mapset)
175{
176 char *el;
177 char *buf;
178 DIR *dirp;
179 struct dirent *dp;
180 int count;
181 char **list;
182
183 switch (element) {
184 case G_ELEMENT_RASTER:
185 el = "cell";
186 break;
187
188 case G_ELEMENT_GROUP:
189 el = "group";
190 break;
191
192 case G_ELEMENT_VECTOR:
193 el = "vector";
194 break;
195
196 case G_ELEMENT_REGION:
197 el = "windows";
198 break;
199
200 default:
201 G_fatal_error(_("G_list: Unknown element type"));
202 }
203
204 buf = (char *)G_malloc(strlen(gisbase) + strlen(location) + strlen(mapset) +
205 strlen(el) + 4);
206
207 sprintf(buf, "%s/%s/%s/%s", gisbase, location, mapset, el);
208
209 dirp = opendir(buf);
210 G_free(buf);
211
212 if (dirp == NULL) { /* this can happen if element does not exist */
213 list = (char **)G_calloc(1, sizeof(char *));
214 return list;
215 }
216
217 count = 0;
218 while ((dp = readdir(dirp)) != NULL) {
219 if (dp->d_name[0] == '.')
220 continue;
221 count++;
222 }
223 rewinddir(dirp);
224
225 list = (char **)G_calloc(count + 1, sizeof(char *));
226
227 count = 0;
228 while ((dp = readdir(dirp)) != NULL) {
229 if (dp->d_name[0] == '.')
230 continue;
231
232 list[count] = (char *)G_malloc(strlen(dp->d_name) + 1);
233 strcpy(list[count], dp->d_name);
234 count++;
235 }
236 closedir(dirp);
237
238 return list;
239}
240
241/*!
242 \brief Free list
243
244 \param list char* array to be freed
245
246 \return
247 */
248void G_free_list(char **list)
249{
250 int i = 0;
251
252 if (!list)
253 return;
254
255 while (list[i]) {
256 G_free(list[i]);
257 i++;
258 }
259 G_free(list);
260}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:150
#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
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition gis/error.c:159
void G_list_element(const char *element, const char *desc, const char *mapset, int(*lister)(const char *, const char *, char *))
General purpose list function.
Definition gis/list.c:51
char ** G_list(int element, const char *gisbase, const char *location, const char *mapset)
List specified type of elements. Application must release the allocated memory.
Definition gis/list.c:173
void G_free_list(char **list)
Free list.
Definition gis/list.c:248
int count
void G_ls_format(char **list, int num_items, int perline, FILE *stream)
Prints a listing of items to a stream, in prettified column format.
Definition ls.c:165
char ** G_ls2(const char *dir, int *num_files)
Stores a sorted directory listing in an array.
Definition ls.c:94
const char * G_mapset(void)
Get current mapset name.
Definition mapset.c:33
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
FILE * G_open_pager(struct Popen *pager)
Definition pager.c:13
void G_close_pager(struct Popen *pager)
Definition pager.c:35
struct list * list
Definition read_list.c:24
Definition path.h:15