GRASS Programmer's Manual 6.4.1(2011)
|
00001 00016 #include <stdlib.h> 00017 #include <unistd.h> 00018 #include <signal.h> 00019 #include <string.h> 00020 #include <sys/types.h> 00021 #include <dirent.h> 00022 00023 #include <grass/gis.h> 00024 #include <grass/glocale.h> 00025 00026 static int broken_pipe; 00027 static int hit_return = 0; 00028 static int list_element(FILE *, const char *, const char *, const char *, 00029 int (*)(const char *, const char *, const char *)); 00030 static RETSIGTYPE sigpipe_catch(int); 00031 00032 int G_set_list_hit_return(int flag) 00033 { 00034 hit_return = flag; 00035 return 0; 00036 } 00037 00060 int G_list_element(const char *element, 00061 const char *desc, 00062 const char *mapset, 00063 int (*lister) (const char *, const char *, const char *)) 00064 { 00065 int n; 00066 FILE *more; 00067 int count; 00068 00069 #ifdef SIGPIPE 00070 RETSIGTYPE (*sigpipe)(int); 00071 #endif 00072 00073 /* must catch broken pipe in case "more" quits */ 00074 broken_pipe = 0; 00075 #ifdef SIGPIPE 00076 sigpipe = signal(SIGPIPE, sigpipe_catch); 00077 #endif 00078 00079 count = 0; 00080 if (desc == 0 || *desc == 0) 00081 desc = element; 00082 00083 #ifndef __MINGW32__ 00084 /* 00085 * popen() the more command to page the output 00086 */ 00087 if (isatty(1)) { 00088 #ifdef __MINGW32__ 00089 more = popen("%GRASS_PAGER%", "w"); 00090 #else 00091 more = popen("$GRASS_PAGER", "w"); 00092 #endif 00093 if (!more) 00094 more = stdout; 00095 } 00096 else 00097 #endif 00098 more = stdout; 00099 fprintf(more, "----------------------------------------------\n"); 00100 00101 /* 00102 * if no specific mapset is requested, list the mapsets 00103 * from the mapset search list 00104 * otherwise just list the specified mapset 00105 */ 00106 if (mapset == 0 || *mapset == 0) 00107 for (n = 0; !broken_pipe && (mapset = G__mapset_name(n)); n++) 00108 count += list_element(more, element, desc, mapset, lister); 00109 else 00110 count += list_element(more, element, desc, mapset, lister); 00111 00112 if (!broken_pipe) { 00113 if (count == 0) { 00114 if (mapset == 0 || *mapset == 0) 00115 fprintf(more, _("no %s files available in current mapset\n"), 00116 desc); 00117 else 00118 fprintf(more, _("no %s files available in mapset <%s>\n"), 00119 desc, mapset); 00120 } 00121 00122 fprintf(more, "----------------------------------------------\n"); 00123 } 00124 /* 00125 * close the more 00126 */ 00127 if (more != stdout) 00128 pclose(more); 00129 #ifdef SIGPIPE 00130 signal(SIGPIPE, sigpipe); 00131 #endif 00132 if (hit_return && isatty(1)) { 00133 fprintf(stderr, _("hit RETURN to continue -->")); 00134 while (getchar() != '\n') ; 00135 } 00136 00137 return 0; 00138 } 00139 00140 static RETSIGTYPE sigpipe_catch(int n) 00141 { 00142 broken_pipe = 1; 00143 signal(n, sigpipe_catch); 00144 } 00145 00146 static int list_element(FILE * out, 00147 const char *element, const char *desc, 00148 const char *mapset, int (*lister) (const char *, 00149 const char *, 00150 const char *)) 00151 { 00152 char path[GPATH_MAX]; 00153 int count = 0; 00154 char **list; 00155 int i; 00156 00157 /* 00158 * convert . to current mapset 00159 */ 00160 if (strcmp(mapset, ".") == 0) 00161 mapset = G_mapset(); 00162 00163 00164 /* 00165 * get the full name of the GIS directory within the mapset 00166 * and list its contents (if it exists) 00167 * 00168 * if lister() routine is given, the ls command must give 1 name 00169 */ 00170 G__file_name(path, element, "", mapset); 00171 if (access(path, 0) != 0) { 00172 fprintf(out, "\n"); 00173 return count; 00174 } 00175 00176 /* 00177 * if a title so that we can call lister() with the names 00178 * otherwise the ls must be forced into columnar form. 00179 */ 00180 00181 list = G__ls(path, &count); 00182 00183 if (count > 0) { 00184 fprintf(out, _("%s files available in mapset <%s>:\n"), desc, mapset); 00185 if (lister) { 00186 char title[400]; 00187 char name[GNAME_MAX]; 00188 00189 *name = *title = 0; 00190 lister(name, mapset, title); 00191 if (*title) 00192 fprintf(out, "\n%-18s %-.60s\n", name, title); 00193 } 00194 } 00195 00196 if (lister) { 00197 for (i = 0; i < count; i++) { 00198 char title[400]; 00199 00200 lister(list[i], mapset, title); 00201 fprintf(out, "%-18s %-.60s\n", list[i], title); 00202 } 00203 } 00204 else 00205 G_ls_format(list, count, 0, out); 00206 00207 fprintf(out, "\n"); 00208 00209 for (i = 0; i < count; i++) 00210 G_free((char *)list[i]); 00211 if (list) 00212 G_free(list); 00213 00214 return count; 00215 } 00216 00227 char **G_list(int element, const char *gisbase, const char *location, 00228 const char *mapset) 00229 { 00230 char *el; 00231 char *buf; 00232 DIR *dirp; 00233 struct dirent *dp; 00234 int count; 00235 char **list; 00236 00237 switch (element) { 00238 case G_ELEMENT_RASTER: 00239 el = "cell"; 00240 break; 00241 00242 case G_ELEMENT_GROUP: 00243 el = "group"; 00244 break; 00245 00246 case G_ELEMENT_VECTOR: 00247 el = "vector"; 00248 break; 00249 00250 case G_ELEMENT_REGION: 00251 el = "windows"; 00252 break; 00253 00254 default: 00255 G_fatal_error(_("G_list: Unknown element type")); 00256 } 00257 00258 buf = (char *)G_malloc(strlen(gisbase) + strlen(location) 00259 + strlen(mapset) + strlen(el) + 4); 00260 00261 sprintf(buf, "%s/%s/%s/%s", gisbase, location, mapset, el); 00262 00263 dirp = opendir(buf); 00264 G_free(buf); 00265 00266 if (dirp == NULL) { /* this can happen if element does not exist */ 00267 list = (char **)G_calloc(1, sizeof(char *)); 00268 return list; 00269 } 00270 00271 count = 0; 00272 while ((dp = readdir(dirp)) != NULL) { 00273 if (dp->d_name[0] == '.') 00274 continue; 00275 count++; 00276 } 00277 rewinddir(dirp); 00278 00279 list = (char **)G_calloc(count + 1, sizeof(char *)); 00280 00281 count = 0; 00282 while ((dp = readdir(dirp)) != NULL) { 00283 if (dp->d_name[0] == '.') 00284 continue; 00285 00286 list[count] = (char *)G_malloc(strlen(dp->d_name) + 1); 00287 strcpy(list[count], dp->d_name); 00288 count++; 00289 } 00290 closedir(dirp); 00291 00292 return list; 00293 } 00294 00302 void G_free_list(char **list) 00303 { 00304 int i = 0; 00305 00306 if (!list) 00307 return; 00308 00309 while (list[i]) { 00310 G_free(list[i]); 00311 i++; 00312 } 00313 G_free(list); 00314 }