GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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 *, 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 */
50 void 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 
97 static 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 */
176 char **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 */
251 void 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 }
#define G_malloc(n)
Definition: defs/gis.h:112
DIR * opendir()
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition: file_name.c:61
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
int count
char ** G_ls2(const char *, int *)
Stores a sorted directory listing in an array.
Definition: ls.c:95
FILE * G_open_pager(struct Popen *)
Definition: pager.c:13
#define NULL
Definition: ccmath.h:32
#define G_calloc(m, n)
Definition: defs/gis.h:113
Definition: lidar.h:86
dir_entry * readdir()
Definition: gis.h:608
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
struct list * list
Definition: read_list.c:24
void G_close_pager(struct Popen *)
Definition: pager.c:35
#define GPATH_MAX
Definition: gis.h:180
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
Definition: manage.h:4
#define GNAME_MAX
Definition: gis.h:177
Definition: path.h:16
#define _(str)
Definition: glocale.h:10
const char * name
Definition: named_colr.c:7
void G_ls_format(char **, int, int, FILE *)
Prints a listing of items to a stream, in prettified column format.
Definition: ls.c:165
const char * G_get_mapset_name(int)
Get name of the n&#39;th mapset from the current mapset search path.
Definition: mapset_nme.c:44
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