main.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /****************************************************************************
  2. *
  3. * MODULE: g.list
  4. *
  5. * AUTHOR(S): Huidae Cho
  6. * Based on general/manage/cmd/list.c by Michael Shapiro.
  7. *
  8. * PURPOSE: Lists available GRASS data base files of the
  9. * user-specified data type to standard output
  10. *
  11. * COPYRIGHT: (C) 1999-2014 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. *****************************************************************************/
  18. #include "global.h"
  19. #include <stdlib.h>
  20. #include <unistd.h>
  21. #include <string.h>
  22. #include <grass/gis.h>
  23. #include <grass/manage.h>
  24. #include <grass/glocale.h>
  25. #include <grass/spawn.h>
  26. int main(int argc, char *argv[])
  27. {
  28. struct GModule *module;
  29. struct
  30. {
  31. struct Option *type;
  32. struct Option *pattern;
  33. struct Option *exclude;
  34. struct Option *separator;
  35. struct Option *mapset;
  36. struct Option *region;
  37. struct Option *output;
  38. } opt;
  39. struct
  40. {
  41. struct Flag *ignorecase;
  42. struct Flag *regex;
  43. struct Flag *extended;
  44. struct Flag *type;
  45. struct Flag *mapset;
  46. struct Flag *pretty;
  47. struct Flag *full;
  48. } flag;
  49. int i, j, n, all, num_types, nlist;
  50. void *filter, *exclude;
  51. struct Popen pager;
  52. FILE *fp;
  53. char *separator;
  54. int use_region, use_pager;
  55. struct Cell_head window;
  56. struct elist *el;
  57. int lcount, lalloc;
  58. G_gisinit(argv[0]);
  59. module = G_define_module();
  60. G_add_keyword(_("general"));
  61. G_add_keyword(_("map management"));
  62. G_add_keyword(_("list"));
  63. G_add_keyword(_("search"));
  64. module->description =
  65. _("Lists available GRASS data base files of "
  66. "the user-specified data type optionally using the search pattern.");
  67. M_read_list(FALSE, &nlist);
  68. opt.type = G_define_standard_option(G_OPT_M_DATATYPE);
  69. opt.type->multiple = YES;
  70. opt.type->options = M_get_options(TRUE);
  71. opt.type->descriptions = M_get_option_desc(TRUE);
  72. opt.type->guidependency = "pattern,exclude";
  73. opt.pattern = G_define_option();
  74. opt.pattern->key = "pattern";
  75. opt.pattern->type = TYPE_STRING;
  76. opt.pattern->required = NO;
  77. opt.pattern->multiple = NO;
  78. opt.pattern->description = _("Map name search pattern (default: all)");
  79. opt.pattern->guisection = _("Pattern");
  80. opt.exclude = G_define_option();
  81. opt.exclude->key = "exclude";
  82. opt.exclude->type = TYPE_STRING;
  83. opt.exclude->required = NO;
  84. opt.exclude->multiple = NO;
  85. opt.exclude->description = _("Map name exclusion pattern (default: none)");
  86. opt.exclude->guisection = _("Pattern");
  87. opt.mapset = G_define_standard_option(G_OPT_M_MAPSET);
  88. opt.mapset->multiple = YES;
  89. opt.mapset->label =
  90. _("Name of mapset to list (default: current search path)");
  91. opt.mapset->description =
  92. _("'.' for current mapset; '*' for all mapsets in location");
  93. opt.separator = G_define_standard_option(G_OPT_F_SEP);
  94. opt.separator->answer = "newline";
  95. opt.separator->guisection = _("Print");
  96. opt.region = G_define_standard_option(G_OPT_M_REGION);
  97. opt.region->label = _("Name of saved region for map search (default: not restricted)");
  98. opt.region->description =
  99. _("'.' for current region; '*' for default region");
  100. opt.output = G_define_standard_option(G_OPT_F_OUTPUT);
  101. opt.output->required = NO;
  102. opt.output->label = _("Name for output file");
  103. opt.output->description = _("If not given or '-' then standard output");
  104. opt.output->guisection = _("Print");
  105. flag.ignorecase = G_define_flag();
  106. flag.ignorecase->key = 'i';
  107. flag.ignorecase->description = _("Ignore case");
  108. flag.ignorecase->guisection = _("Pattern");
  109. flag.regex = G_define_flag();
  110. flag.regex->key = 'r';
  111. flag.regex->description =
  112. _("Use basic regular expressions instead of wildcards");
  113. flag.regex->guisection = _("Pattern");
  114. flag.extended = G_define_flag();
  115. flag.extended->key = 'e';
  116. flag.extended->description =
  117. _("Use extended regular expressions instead of wildcards");
  118. flag.extended->guisection = _("Pattern");
  119. flag.type = G_define_flag();
  120. flag.type->key = 't';
  121. flag.type->description = _("Print data types");
  122. flag.type->guisection = _("Print");
  123. flag.mapset = G_define_flag();
  124. flag.mapset->key = 'm';
  125. flag.mapset->description = _("Print fully-qualified map names (including mapsets)");
  126. flag.mapset->guisection = _("Print");
  127. flag.pretty = G_define_flag();
  128. flag.pretty->key = 'p';
  129. flag.pretty->description = _("Pretty printing in human readable format");
  130. flag.pretty->guisection = _("Print");
  131. flag.full = G_define_flag();
  132. flag.full->key = 'f';
  133. flag.full->description = _("Verbose listing (also list map titles)");
  134. flag.full->guisection = _("Print");
  135. G_option_excludes(opt.region, flag.pretty, flag.full, NULL);
  136. G_option_excludes(flag.pretty, flag.mapset, flag.type, NULL);
  137. G_option_excludes(flag.full, flag.mapset, flag.type, NULL);
  138. G_option_exclusive(flag.pretty, flag.full, NULL);
  139. G_option_exclusive(flag.regex, flag.extended, NULL);
  140. if (G_parser(argc, argv))
  141. exit(EXIT_FAILURE);
  142. if (opt.pattern->answer) {
  143. if (flag.regex->answer || flag.extended->answer)
  144. filter = G_ls_regex_filter(opt.pattern->answer, 0,
  145. (int)flag.extended->answer,
  146. (int)flag.ignorecase->answer);
  147. else {
  148. /* handle individual map names */
  149. if (strchr(opt.pattern->answer, ',')) {
  150. char *pattern;
  151. pattern = (char *)G_malloc(strlen(opt.pattern->answer) + 3);
  152. sprintf(pattern, "{%s}", opt.pattern->answer);
  153. filter = G_ls_glob_filter(pattern, 0,
  154. (int)flag.ignorecase->answer);
  155. }
  156. else
  157. filter = G_ls_glob_filter(opt.pattern->answer, 0,
  158. (int)flag.ignorecase->answer);
  159. }
  160. if (!filter)
  161. G_fatal_error(_("Unable to compile pattern <%s>"),
  162. opt.pattern->answer);
  163. }
  164. else
  165. filter = NULL;
  166. if (opt.exclude->answer) {
  167. if (flag.regex->answer || flag.extended->answer)
  168. exclude = G_ls_regex_filter(opt.exclude->answer, 1,
  169. (int)flag.extended->answer,
  170. (int)flag.ignorecase->answer);
  171. else {
  172. /* handle individual map names */
  173. if (strchr(opt.exclude->answer, ',')) {
  174. char *pattern;
  175. pattern = (char *)G_malloc(strlen(opt.exclude->answer) + 3);
  176. sprintf(pattern, "{%s}", opt.exclude->answer);
  177. exclude = G_ls_glob_filter(pattern, 1,
  178. (int)flag.ignorecase->answer);
  179. }
  180. else
  181. exclude = G_ls_glob_filter(opt.exclude->answer, 1,
  182. (int)flag.ignorecase->answer);
  183. }
  184. if (!exclude)
  185. G_fatal_error(_("Unable to compile pattern <%s>"),
  186. opt.exclude->answer);
  187. }
  188. else
  189. exclude = NULL;
  190. separator = G_option_to_separator(opt.separator);
  191. if (opt.region->answer) {
  192. use_region = 1;
  193. if (strcmp(opt.region->answer, "*") == 0)
  194. G_get_default_window(&window);
  195. else if (strcmp(opt.region->answer, ".") == 0)
  196. G_get_window(&window);
  197. else {
  198. char name[GNAME_MAX], mapset[GMAPSET_MAX];
  199. if (G_name_is_fully_qualified(opt.region->answer, name, mapset))
  200. G_get_element_window(&window, "windows", name, mapset);
  201. else
  202. G_get_element_window(&window, "windows", opt.region->answer, "");
  203. }
  204. }
  205. else
  206. use_region = 0;
  207. for (i = 0; opt.type->answers[i]; i++) {
  208. if (strcmp(opt.type->answers[i], "all") == 0)
  209. break;
  210. }
  211. if (opt.type->answers[i]) {
  212. all = 1;
  213. num_types = nlist;
  214. }
  215. else {
  216. all = 0;
  217. num_types = i;
  218. }
  219. if (opt.mapset->answers && opt.mapset->answers[0]) {
  220. const char *mapset;
  221. G_create_alt_search_path();
  222. for (i = 0; (mapset = opt.mapset->answers[i]); i++) {
  223. if (strcmp(mapset, "*") == 0) {
  224. /* all mapsets from current location */
  225. char **ms;
  226. ms = G_get_available_mapsets();
  227. for (j = 0; (mapset = ms[j]); j++)
  228. G_add_mapset_to_search_path(mapset);
  229. continue;
  230. }
  231. else if (strcmp(mapset, ".") == 0)
  232. mapset = G_mapset();
  233. else if (G_mapset_permissions(mapset) == -1)
  234. G_fatal_error(_("Mapset <%s> does not exist"), mapset);
  235. G_add_mapset_to_search_path(mapset);
  236. }
  237. }
  238. use_pager = !opt.output->answer || !opt.output->answer[0] ||
  239. strcmp(opt.output->answer, "-") == 0;
  240. if (use_pager)
  241. fp = G_open_pager(&pager);
  242. else
  243. fp = G_open_option_file(opt.output);
  244. if (flag.pretty->answer || flag.full->answer)
  245. dup2(fileno(fp), STDOUT_FILENO);
  246. lcount = 0;
  247. lalloc = 0;
  248. el = NULL;
  249. for (i = 0; i < num_types; i++) {
  250. const struct list *elem;
  251. n = all ? i : M_get_element(opt.type->answers[i]);
  252. elem = M_get_list(n);
  253. if (flag.full->answer) {
  254. char lister[GPATH_MAX];
  255. sprintf(lister, "%s/etc/lister/%s", G_gisbase(), elem->element[0]);
  256. G_debug(3, "lister CMD: %s", lister);
  257. if (access(lister, X_OK) == 0) { /* execute permission? */
  258. const char **args;
  259. const char *mapset;
  260. for (j = 0; (mapset = G_get_mapset_name(j)); j++);
  261. args = (const char **)G_calloc(j + 2, sizeof(char *));
  262. args[0] = lister;
  263. for (j = 0; (mapset = G_get_mapset_name(j)); j++)
  264. args[j + 1] = mapset;
  265. args[j + 1] = NULL;
  266. G_vspawn_ex(lister, args);
  267. } else
  268. M_do_list(n, "");
  269. }
  270. else if (flag.pretty->answer)
  271. M_do_list(n, "");
  272. else {
  273. const char *mapset;
  274. for (j = 0; (mapset = G_get_mapset_name(j)); j++)
  275. make_list(&el, &lcount, &lalloc, elem, mapset,
  276. use_region ? &window : NULL);
  277. }
  278. }
  279. if (!flag.pretty->answer && !flag.full->answer) {
  280. print_list(fp, el, lcount, separator, flag.type->answer,
  281. flag.mapset->answer);
  282. }
  283. if (el)
  284. G_free(el);
  285. if (flag.pretty->answer || flag.full->answer)
  286. fclose(stdout);
  287. else if (lcount)
  288. fprintf(fp, "\n");
  289. if (use_pager)
  290. G_close_pager(&pager);
  291. else
  292. G_close_option_file(fp);
  293. if (filter)
  294. G_free_ls_filter(filter);
  295. if (exclude)
  296. G_free_ls_filter(exclude);
  297. exit(EXIT_SUCCESS);
  298. }