00001
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <sys/types.h>
00020 #include <dirent.h>
00021 #include <unistd.h>
00022
00023 #include <grass/gis.h>
00024 #include <grass/config.h>
00025 #include <grass/glocale.h>
00026
00027 #ifdef HAVE_SYS_IOCTL_H
00028 # include <sys/ioctl.h>
00029 #endif
00030
00031 typedef int ls_filter_func(const char * , void * );
00032
00033 static ls_filter_func *ls_filter;
00034 static void *ls_closure;
00035
00036 static ls_filter_func *ls_ex_filter;
00037 static void *ls_ex_closure;
00038
00039 static int cmp_names(const void *aa, const void *bb)
00040 {
00041 char *const *a = (char *const *)aa;
00042 char *const *b = (char *const *)bb;
00043
00044 return strcmp(*a, *b);
00045 }
00046
00060 void G_set_ls_filter(ls_filter_func *func, void *closure)
00061 {
00062 ls_filter = func;
00063 ls_closure = closure;
00064 }
00065
00066 void G_set_ls_exclude_filter(ls_filter_func *func, void *closure)
00067 {
00068 ls_ex_filter = func;
00069 ls_ex_closure = closure;
00070 }
00071
00088 char **G__ls(const char *dir, int *num_files)
00089 {
00090 struct dirent *dp;
00091 DIR *dfd;
00092 char **dir_listing = NULL;
00093 int n = 0;
00094
00095 if ((dfd = opendir(dir)) == NULL)
00096 G_fatal_error(_("Unable to open directory %s"), dir);
00097
00098 while ((dp = readdir(dfd)) != NULL) {
00099 if (dp->d_name[0] == '.')
00100 continue;
00101 if (ls_filter && !(*ls_filter)(dp->d_name, ls_closure))
00102 continue;
00103 if (ls_ex_filter && (*ls_ex_filter)(dp->d_name, ls_ex_closure))
00104 continue;
00105 dir_listing = (char **)G_realloc(dir_listing, (1 + n) * sizeof(char *));
00106 dir_listing[n] = G_store(dp->d_name);
00107 n++;
00108 }
00109
00110
00111 qsort(dir_listing, n, sizeof(char *), cmp_names);
00112
00113 *num_files = n;
00114 return dir_listing;
00115 }
00116
00129 void G_ls(const char *dir, FILE * stream)
00130 {
00131 int i, n;
00132 char **dir_listing = G__ls(dir, &n);
00133
00134 G_ls_format(dir_listing, n, 0, stream);
00135
00136 for (i = 0; i < n; i++)
00137 G_free(dir_listing[i]);
00138
00139 G_free(dir_listing);
00140
00141 return;
00142 }
00143
00159 void G_ls_format(char **list, int num_items, int perline, FILE * stream)
00160 {
00161 int i;
00162
00163 int field_width, column_height;
00164 int screen_width = 80;
00165
00166 if (num_items < 1)
00167 return;
00168
00169 #ifdef TIOCGWINSZ
00170
00171 {
00172 struct winsize size;
00173
00174 if (ioctl(fileno(stream), TIOCGWINSZ, (char *)&size) == 0)
00175 screen_width = size.ws_col;
00176 }
00177 #endif
00178
00179 if (perline == 0) {
00180 int max_len = 0;
00181
00182 for (i = 0; i < num_items; i++) {
00183
00184 if (strlen(list[i]) > max_len)
00185 max_len = strlen(list[i]);
00186 }
00187
00188
00189 perline = screen_width / (max_len + 1);
00190 if (perline < 1)
00191 perline = 1;
00192 }
00193
00194
00195 field_width = screen_width / perline;
00196
00197 column_height = (num_items / perline) + ((num_items % perline) > 0);
00198
00199 {
00200 const int max
00201 = num_items + column_height - (num_items % column_height);
00202 char **next;
00203
00204 for (i = 1, next = list; i <= num_items; i++) {
00205 char **cur = next;
00206
00207 next += column_height;
00208 if (next >= list + num_items) {
00209
00210 next -= (max - 1 - (next < list + max ? column_height : 0));
00211 fprintf(stream, "%s\n", *cur);
00212 }
00213 else {
00214 fprintf(stream, "%-*s", field_width, *cur);
00215 }
00216 }
00217 }
00218
00219 return;
00220 }