GRASS GIS 8 Programmer's Manual 8.2.1RC1(2022)-exported
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 *, const 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 list
46 "." will list current mapset
47 \param lister if given will call this routine to get a list title.
48 NULL if no titles desired.
49*/
50void G_list_element(const char *element,
51 const char *desc,
52 const char *mapset,
53 int (*lister) (const char *, const char *, const char *))
54{
55 struct Popen pager;
56 int n;
57 FILE *more;
58 int count;
59
60 count = 0;
61 if (desc == 0 || *desc == 0)
62 desc = element;
63
64 /*
65 * G_popen() the more command to page the output
66 */
67 more = G_open_pager(&pager);
68 fprintf(more, "----------------------------------------------\n");
69
70 /*
71 * if no specific mapset is requested, list the mapsets
72 * from the mapset search list
73 * otherwise just list the specified mapset
74 */
75 if (mapset == 0 || *mapset == 0)
76 for (n = 0; (mapset = G_get_mapset_name(n)); n++)
77 count += list_element(more, element, desc, mapset, lister);
78 else
79 count += list_element(more, element, desc, mapset, lister);
80
81 if (count == 0) {
82 if (mapset == 0 || *mapset == 0)
83 fprintf(more, _("no %s files available in current mapset\n"),
84 desc);
85 else
86 fprintf(more, _("no %s files available in mapset <%s>\n"),
87 desc, mapset);
88
89 fprintf(more, "----------------------------------------------\n");
90 }
91 /*
92 * close the more
93 */
94 G_close_pager(&pager);
95}
96
97static int list_element(FILE *out, const char *element, const char *desc, const char *mapset,
98 int (*lister)(const char *, const char *, const char *))
99{
100 char path[GPATH_MAX];
101 int count = 0;
102 char **list;
103 int i;
104
105 /*
106 * convert . to current mapset
107 */
108 if (strcmp(mapset, ".") == 0)
109 mapset = G_mapset();
110
111
112 /*
113 * get the full name of the GIS directory within the mapset
114 * and list its contents (if it exists)
115 *
116 * if lister() routine is given, the ls command must give 1 name
117 */
118 G_file_name(path, element, "", mapset);
119 if (access(path, 0) != 0) {
120 fprintf(out, "\n");
121 return count;
122 }
123
124 /*
125 * if a title so that we can call lister() with the names
126 * otherwise the ls must be forced into columnar form.
127 */
128
129 list = G_ls2(path, &count);
130
131 if (count > 0) {
132 fprintf(out, _("%s files available in mapset <%s>:\n"), desc, mapset);
133 if (lister) {
134 char title[400];
135 char name[GNAME_MAX];
136
137 *name = *title = 0;
138 lister(name, mapset, title);
139 if (*title)
140 fprintf(out, "\n%-18s %-.60s\n", name, title);
141 }
142 }
143
144 if (lister) {
145 for (i = 0; i < count; i++) {
146 char title[400];
147
148 lister(list[i], mapset, title);
149 fprintf(out, "%-18s %-.60s\n", list[i], title);
150 }
151 }
152 else
153 G_ls_format(list, count, 0, out);
154
155 fprintf(out, "\n");
156
157 for (i = 0; i < count; i++)
158 G_free((char *)list[i]);
159 if (list)
160 G_free(list);
161
162 return count;
163}
164
165/*!
166 \brief List specified type of elements. Application must release
167 the allocated memory.
168
169 \param element element type (G_ELEMENT_RASTER, G_ELEMENT_VECTOR, G_ELEMENT_REGION )
170 \param gisbase path to GISBASE
171 \param location location name
172 \param mapset mapset name
173
174 \return zero terminated array of element names
175*/
176char **G_list(int element, const char *gisbase, const char *location,
177 const char *mapset)
178{
179 char *el;
180 char *buf;
181 DIR *dirp;
182 struct dirent *dp;
183 int count;
184 char **list;
185
186 switch (element) {
187 case G_ELEMENT_RASTER:
188 el = "cell";
189 break;
190
191 case G_ELEMENT_GROUP:
192 el = "group";
193 break;
194
195 case G_ELEMENT_VECTOR:
196 el = "vector";
197 break;
198
199 case G_ELEMENT_REGION:
200 el = "windows";
201 break;
202
203 default:
204 G_fatal_error(_("G_list: Unknown element type"));
205 }
206
207 buf = (char *)G_malloc(strlen(gisbase) + strlen(location)
208 + strlen(mapset) + strlen(el) + 4);
209
210 sprintf(buf, "%s/%s/%s/%s", gisbase, location, mapset, el);
211
212 dirp = opendir(buf);
213 G_free(buf);
214
215 if (dirp == NULL) { /* this can happen if element does not exist */
216 list = (char **)G_calloc(1, sizeof(char *));
217 return list;
218 }
219
220 count = 0;
221 while ((dp = readdir(dirp)) != NULL) {
222 if (dp->d_name[0] == '.')
223 continue;
224 count++;
225 }
226 rewinddir(dirp);
227
228 list = (char **)G_calloc(count + 1, sizeof(char *));
229
230 count = 0;
231 while ((dp = readdir(dirp)) != NULL) {
232 if (dp->d_name[0] == '.')
233 continue;
234
235 list[count] = (char *)G_malloc(strlen(dp->d_name) + 1);
236 strcpy(list[count], dp->d_name);
237 count++;
238 }
239 closedir(dirp);
240
241 return list;
242}
243
244/*!
245 \brief Free list
246
247 \param list char* array to be freed
248
249 \return
250*/
251void G_free_list(char **list)
252{
253 int i = 0;
254
255 if (!list)
256 return;
257
258 while (list[i]) {
259 G_free(list[i]);
260 i++;
261 }
262 G_free(list);
263}
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
#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:160
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:176
void G_free_list(char **list)
Free list.
Definition: gis/list.c:251
void G_list_element(const char *element, const char *desc, const char *mapset, int(*lister)(const char *, const char *, const char *))
General purpose list function.
Definition: gis/list.c:50
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:95
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:7
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: lidar.h:87
Definition: path.h:16