GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-835afb4352
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 
24 static 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  */
51 void 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 
95 static 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  */
173 char **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  */
248 void 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 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_calloc(m, n)
Definition: defs/gis.h:95
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
FILE * G_open_pager(struct Popen *)
Definition: pager.c:13
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition: file_name.c:61
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
void G_close_pager(struct Popen *)
Definition: pager.c:35
#define G_malloc(n)
Definition: defs/gis.h:94
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
void G_ls_format(char **, int, int, FILE *)
Prints a listing of items to a stream, in prettified column format.
Definition: ls.c:165
char ** G_ls2(const char *, int *)
Stores a sorted directory listing in an array.
Definition: ls.c:94
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_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
void G_free_list(char **list)
Free list.
Definition: gis/list.c:248
#define GPATH_MAX
Definition: gis.h:194
@ G_ELEMENT_RASTER
Definition: gis.h:423
@ G_ELEMENT_VECTOR
Definition: gis.h:425
@ G_ELEMENT_GROUP
Definition: gis.h:429
@ G_ELEMENT_REGION
Definition: gis.h:428
#define GNAME_MAX
Definition: gis.h:191
#define _(str)
Definition: glocale.h:10
int count
const char * name
Definition: named_colr.c:6
#define strcpy
Definition: parson.c:62
struct list * list
Definition: read_list.c:24
Definition: gis.h:620
Definition: lidar.h:85
Definition: manage.h:4
Definition: path.h:15