GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ls.c
Go to the documentation of this file.
1 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <unistd.h>
22 
23 #include <grass/gis.h>
24 #include <grass/config.h>
25 #include <grass/glocale.h>
26 
27 #ifdef HAVE_SYS_IOCTL_H
28 # include <sys/ioctl.h>
29 #endif
30 
31 typedef int ls_filter_func(const char * /*filename */ , void * /*closure */ );
32 
33 static ls_filter_func *ls_filter;
34 static void *ls_closure;
35 
36 static ls_filter_func *ls_ex_filter;
37 static void *ls_ex_closure;
38 
39 static int cmp_names(const void *aa, const void *bb)
40 {
41  char *const *a = (char *const *)aa;
42  char *const *b = (char *const *)bb;
43 
44  return strcmp(*a, *b);
45 }
46 
60 void G_set_ls_filter(ls_filter_func *func, void *closure)
61 {
62  ls_filter = func;
63  ls_closure = closure;
64 }
65 
66 void G_set_ls_exclude_filter(ls_filter_func *func, void *closure)
67 {
68  ls_ex_filter = func;
69  ls_ex_closure = closure;
70 }
71 
88 char **G__ls(const char *dir, int *num_files)
89 {
90  struct dirent *dp;
91  DIR *dfd;
92  char **dir_listing = NULL;
93  int n = 0;
94 
95  if ((dfd = opendir(dir)) == NULL)
96  G_fatal_error(_("Unable to open directory %s"), dir);
97 
98  while ((dp = readdir(dfd)) != NULL) {
99  if (dp->d_name[0] == '.') /* Don't list hidden files */
100  continue;
101  if (ls_filter && !(*ls_filter)(dp->d_name, ls_closure))
102  continue;
103  if (ls_ex_filter && (*ls_ex_filter)(dp->d_name, ls_ex_closure))
104  continue;
105  dir_listing = (char **)G_realloc(dir_listing, (1 + n) * sizeof(char *));
106  dir_listing[n] = G_store(dp->d_name);
107  n++;
108  }
109 
110  /* Sort list of filenames alphabetically */
111  qsort(dir_listing, n, sizeof(char *), cmp_names);
112 
113  *num_files = n;
114  return dir_listing;
115 }
116 
129 void G_ls(const char *dir, FILE * stream)
130 {
131  int i, n;
132  char **dir_listing = G__ls(dir, &n);
133 
134  G_ls_format(dir_listing, n, 0, stream);
135 
136  for (i = 0; i < n; i++)
137  G_free(dir_listing[i]);
138 
139  G_free(dir_listing);
140 
141  return;
142 }
143 
159 void G_ls_format(char **list, int num_items, int perline, FILE * stream)
160 {
161  int i;
162 
163  int field_width, column_height;
164  int screen_width = 80; /* Default width of 80 columns */
165 
166  if (num_items < 1)
167  return; /* Nothing to print */
168 
169 #ifdef TIOCGWINSZ
170  /* Determine screen_width if possible */
171  {
172  struct winsize size;
173 
174  if (ioctl(fileno(stream), TIOCGWINSZ, (char *)&size) == 0)
175  screen_width = size.ws_col;
176  }
177 #endif
178 
179  if (perline == 0) {
180  int max_len = 0;
181 
182  for (i = 0; i < num_items; i++) {
183  /* Find maximum filename length */
184  if (strlen(list[i]) > max_len)
185  max_len = strlen(list[i]);
186  }
187  /* Auto-fit the number of items that will
188  * fit per line (+1 because of space after item) */
189  perline = screen_width / (max_len + 1);
190  if (perline < 1)
191  perline = 1;
192  }
193 
194  /* Field width to accomodate longest filename */
195  field_width = screen_width / perline;
196  /* Longest column height (i.e. num_items <= perline * column_height) */
197  column_height = (num_items / perline) + ((num_items % perline) > 0);
198 
199  {
200  const int max
201  = num_items + column_height - (num_items % column_height);
202  char **next;
203 
204  for (i = 1, next = list; i <= num_items; i++) {
205  char **cur = next;
206 
207  next += column_height;
208  if (next >= list + num_items) {
209  /* the next item has to be on the other line */
210  next -= (max - 1 - (next < list + max ? column_height : 0));
211  fprintf(stream, "%s\n", *cur);
212  }
213  else {
214  fprintf(stream, "%-*s", field_width, *cur);
215  }
216  }
217  }
218 
219  return;
220 }
DIR * opendir()
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
float b
Definition: named_colr.c:8
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
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:159
char ** G__ls(const char *dir, int *num_files)
Stores a sorted directory listing in an array.
Definition: ls.c:88
void G_ls(const char *dir, FILE *stream)
Prints a directory listing to a stream, in prettified column format.
Definition: ls.c:129
#define max(x, y)
Definition: draw2.c:69
dir_entry * readdir()
void G_set_ls_filter(ls_filter_func *func, void *closure)
Sets a function and its complementary data for G__ls filtering.
Definition: ls.c:60
return NULL
Definition: dbfopen.c:1394
int ls_filter_func(const char *, void *)
Definition: ls.c:31
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int n
Definition: dataquad.c:291
void G_set_ls_exclude_filter(ls_filter_func *func, void *closure)
Definition: ls.c:66