GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
ls.c
Go to the documentation of this file.
1
/**
2
\file lib/gis/ls.c
3
4
\brief Functions to list the files in a directory.
5
6
\author Paul Kelly
7
8
(C) 2007, 2008 by the GRASS Development Team
9
10
This program is free software under the GNU General Public
11
License (>=v2). Read the file COPYING that comes with GRASS
12
for details.
13
*/
14
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <string.h>
18
#include <sys/types.h>
19
#include <dirent.h>
20
#include <unistd.h>
21
22
#include <grass/gis.h>
23
#include <grass/config.h>
24
#include <grass/glocale.h>
25
26
#ifdef HAVE_TERMIOS_H
27
#include <termios.h>
28
#endif
29
30
#ifdef HAVE_SYS_IOCTL_H
31
#include <sys/ioctl.h>
32
#endif
33
34
typedef
int
ls_filter_func
(
const
char
*
/*filename */
,
void
*
/*closure */
);
35
36
static
struct
state {
37
ls_filter_func
*ls_filter;
38
void
*ls_closure;
39
ls_filter_func
*ls_ex_filter;
40
void
*ls_ex_closure;
41
} state;
42
43
static
struct
state *st = &state;
44
45
static
int
cmp_names(
const
void
*aa,
const
void
*bb)
46
{
47
char
*
const
*a = (
char
*
const
*)aa;
48
char
*
const
*
b
= (
char
*
const
*)bb;
49
50
return
strcmp(*a, *
b
);
51
}
52
53
/**
54
* \brief Sets a function and its complementary data for G_ls2 filtering.
55
*
56
* Defines a filter function and its rule data that allow G_ls2 to filter out
57
* unwanted file names. Call this function before G_ls2.
58
*
59
* \param func Filter callback function to compare a file name and closure
60
* pattern (if NULL, no filter will be used).
61
* func(filename, closure) should return 1 on success, 0 on
62
* failure.
63
* \param closure Data used to determine if a file name matches the rule.
64
**/
65
66
void
G_set_ls_filter
(
ls_filter_func
*func,
void
*closure)
67
{
68
st->ls_filter = func;
69
st->ls_closure = closure;
70
}
71
72
void
G_set_ls_exclude_filter
(
ls_filter_func
*func,
void
*closure)
73
{
74
st->ls_ex_filter = func;
75
st->ls_ex_closure = closure;
76
}
77
78
/**
79
* \brief Stores a sorted directory listing in an array
80
*
81
* The filenames in the specified directory are stored in an array of
82
* strings, then sorted alphabetically. Each filename has space allocated
83
* using G_store(), which can be freed using G_free() if necessary. The
84
* same goes for the array itself.
85
*
86
*
87
* \param dir Directory to list
88
* \param num_files Pointer to an integer in which the total number of
89
* files listed will be stored
90
*
91
* \return Pointer to array of strings containing the listing
92
**/
93
94
char
**
G_ls2
(
const
char
*dir,
int
*num_files)
95
{
96
struct
dirent *dp;
97
DIR *dfd;
98
char
**dir_listing =
NULL
;
99
int
n = 0;
100
101
if
((dfd = opendir(dir)) ==
NULL
)
102
G_fatal_error
(_(
"Unable to open directory %s"
), dir);
103
104
while
((dp = readdir(dfd)) !=
NULL
) {
105
if
(dp->d_name[0] ==
'.'
)
/* Don't list hidden files */
106
continue
;
107
if
(st->ls_filter && !(*st->ls_filter)(dp->d_name, st->ls_closure))
108
continue
;
109
if
(st->ls_ex_filter &&
110
(*st->ls_ex_filter)(dp->d_name, st->ls_ex_closure))
111
continue
;
112
dir_listing = (
char
**)G_realloc(dir_listing, (1 + n) *
sizeof
(
char
*));
113
dir_listing[n] =
G_store
(dp->d_name);
114
n++;
115
}
116
closedir(dfd);
117
118
/* Sort list of filenames alphabetically */
119
qsort(dir_listing, n,
sizeof
(
char
*), cmp_names);
120
121
*num_files = n;
122
return
dir_listing;
123
}
124
125
/**
126
* \brief Prints a directory listing to a stream, in prettified column format
127
*
128
* A replacement for system("ls -C"). Lists the contents of the directory
129
* specified to the given stream, e.g. stderr. Tries to determine an
130
* appropriate column width to keep the number of lines used to a minimum
131
* and look pretty on the screen.
132
*
133
* \param dir Directory to list
134
* \param stream Stream to print listing to
135
**/
136
137
void
G_ls
(
const
char
*dir, FILE *stream)
138
{
139
int
i, n;
140
char
**dir_listing =
G_ls2
(dir, &n);
141
142
G_ls_format
(dir_listing, n, 0, stream);
143
144
for
(i = 0; i < n; i++)
145
G_free
(dir_listing[i]);
146
147
G_free
(dir_listing);
148
}
149
150
/**
151
* \brief Prints a listing of items to a stream, in prettified column format
152
*
153
* Lists the contents of the array passed to the given stream, e.g. stderr.
154
* Prints the number of items specified by "perline" to each line, unless
155
* perline is given as 0 in which case the function tries to determine an
156
* appropriate column width to keep the number of lines used to a minimum
157
* and look pretty on the screen.
158
*
159
* \param list Array of strings containing items to be printed
160
* \param num_items Number of items in the array
161
* \param perline Number of items to print per line, 0 for autodetect
162
* \param stream Stream to print listing to
163
**/
164
165
void
G_ls_format
(
char
**
list
,
int
num_items,
int
perline, FILE *stream)
166
{
167
int
i;
168
169
int
field_width, column_height;
170
int
screen_width
= 80;
/* Default width of 80 columns */
171
172
if
(num_items < 1)
173
return
;
/* Nothing to print */
174
175
#ifdef TIOCGWINSZ
176
/* Determine screen_width if possible */
177
{
178
struct
winsize size;
179
180
if
(ioctl(fileno(stream), TIOCGWINSZ, (
char
*)&size) == 0)
181
screen_width
= size.ws_col;
182
}
183
#endif
184
185
if
(perline == 0) {
186
unsigned
int
max_len = 0;
187
188
for
(i = 0; i < num_items; i++) {
189
/* Find maximum filename length */
190
if
(strlen(
list
[i]) > max_len)
191
max_len = strlen(
list
[i]);
192
}
193
/* Auto-fit the number of items that will
194
* fit per line (+1 because of space after item) */
195
perline =
screen_width
/ (max_len + 1);
196
if
(perline < 1)
197
perline = 1;
198
}
199
200
/* Field width to accommodate longest filename */
201
field_width =
screen_width
/ perline;
202
/* Longest column height (i.e. num_items <= perline * column_height) */
203
column_height = (num_items / perline) + ((num_items % perline) > 0);
204
205
{
206
const
int
max
= num_items + column_height - (num_items % column_height);
207
char
**next;
208
209
for
(i = 1, next =
list
; i <= num_items; i++) {
210
char
**cur = next;
211
212
next += column_height;
213
if
(next >=
list
+ num_items) {
214
/* the next item has to be on the other line */
215
next -= (
max
- 1 - (next <
list
+
max
? column_height : 0));
216
fprintf(stream,
"%s\n"
, *cur);
217
}
218
else
{
219
fprintf(stream,
"%-*s"
, field_width, *cur);
220
}
221
}
222
}
223
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition
alloc.c:147
NULL
#define NULL
Definition
ccmath.h:32
b
double b
Definition
driver/set_window.c:5
screen_width
int screen_width
Definition
driver/init.c:29
G_fatal_error
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition
gis/error.c:159
G_ls
void G_ls(const char *dir, FILE *stream)
Prints a directory listing to a stream, in prettified column format.
Definition
ls.c:137
G_ls_format
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
G_set_ls_filter
void G_set_ls_filter(ls_filter_func *func, void *closure)
Sets a function and its complementary data for G_ls2 filtering.
Definition
ls.c:66
G_ls2
char ** G_ls2(const char *dir, int *num_files)
Stores a sorted directory listing in an array.
Definition
ls.c:94
ls_filter_func
int ls_filter_func(const char *, void *)
Definition
ls.c:34
G_set_ls_exclude_filter
void G_set_ls_exclude_filter(ls_filter_func *func, void *closure)
Definition
ls.c:72
max
#define max(a, b)
Definition
pngdriver/draw_bitmap.c:22
list
struct list * list
Definition
read_list.c:24
G_store
char * G_store(const char *s)
Copy string to allocated memory.
Definition
strings.c:87
gis
ls.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0