main.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /****************************************************************************
  2. *
  3. * MODULE: g.remove
  4. *
  5. * AUTHOR(S): Huidae Cho <grass4u gmail.com>
  6. *
  7. * Based on general/manage/cmd/remove.c by
  8. * CERL (original contributor),
  9. * Radim Blazek <radim.blazek gmail.com>,
  10. * Cedric Shock <cedricgrass shockfamily.net>,
  11. * Glynn Clements <glynn gclements.plus.com>,
  12. * Jachym Cepicky <jachym les-ejk.cz>,
  13. * Markus Neteler <neteler itc.it>,
  14. * Martin Landa <landa.martin gmail.com>
  15. *
  16. * PURPOSE: Lets users remove GRASS database files
  17. *
  18. * COPYRIGHT: (C) 1999-2014 by the GRASS Development Team
  19. *
  20. * This program is free software under the GNU General
  21. * Public License (>=v2). Read the file COPYING that
  22. * comes with GRASS for details.
  23. *
  24. *****************************************************************************/
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <grass/gis.h>
  29. #include <grass/manage.h>
  30. #include <grass/glocale.h>
  31. /* construct_pattern.c */
  32. char *construct_pattern(char **);
  33. /* check_reclass.c */
  34. int check_reclass(const char *, const char *, int);
  35. int main(int argc, char *argv[])
  36. {
  37. struct GModule *module;
  38. struct
  39. {
  40. struct Option *type;
  41. struct Option *pattern;
  42. struct Option *exclude;
  43. struct Option *name;
  44. struct Option *ignore;
  45. } opt;
  46. struct
  47. {
  48. struct Flag *ignorecase;
  49. struct Flag *regex;
  50. struct Flag *extended;
  51. struct Flag *force;
  52. struct Flag *basemap;
  53. } flag;
  54. char *pattern, *exclude;
  55. const char *mapset;
  56. int result;
  57. int i, all, num_types, nlist, num_removed;
  58. void *filter, *exclude_filter;
  59. G_gisinit(argv[0]);
  60. result = EXIT_SUCCESS;
  61. module = G_define_module();
  62. G_add_keyword(_("general"));
  63. G_add_keyword(_("map management"));
  64. G_add_keyword(_("remove"));
  65. module->description =
  66. _("Removes data base element files from "
  67. "the user's current mapset using the search pattern.");
  68. M_read_list(FALSE, &nlist);
  69. opt.type = G_define_standard_option(G_OPT_M_DATATYPE);
  70. opt.type->multiple = YES;
  71. opt.type->options = M_get_options(TRUE);
  72. opt.type->descriptions = M_get_option_desc(TRUE);
  73. opt.type->guidependency = "pattern,exclude,name,ignore";
  74. opt.type->guisection = _("Basic");
  75. opt.name = G_define_option();
  76. opt.name->key = "name";
  77. opt.name->type = TYPE_STRING;
  78. opt.name->multiple = YES;
  79. opt.name->gisprompt = "old,element,element";
  80. opt.name->description = _("Name of file(s) to remove");
  81. opt.name->guisection = _("Basic");
  82. opt.ignore = G_define_option();
  83. opt.ignore->key = "ignore";
  84. opt.ignore->type = TYPE_STRING;
  85. opt.ignore->multiple = YES;
  86. opt.ignore->gisprompt = "old,element,element";
  87. opt.ignore->description =
  88. _("Name of file(s) to ignore (default: none)");
  89. opt.ignore->guisection = _("Pattern");
  90. opt.pattern = G_define_option();
  91. opt.pattern->key = "pattern";
  92. opt.pattern->type = TYPE_STRING;
  93. opt.pattern->description = _("File name search pattern");
  94. opt.pattern->guisection = _("Pattern");
  95. opt.exclude = G_define_option();
  96. opt.exclude->key = "exclude";
  97. opt.exclude->type = TYPE_STRING;
  98. opt.exclude->description = _("File name exclusion pattern (default: none)");
  99. opt.exclude->guisection = _("Pattern");
  100. flag.ignorecase = G_define_flag();
  101. flag.ignorecase->key = 'i';
  102. flag.ignorecase->description = _("Ignore case");
  103. flag.ignorecase->guisection = _("Pattern");
  104. flag.regex = G_define_flag();
  105. flag.regex->key = 'r';
  106. flag.regex->description =
  107. _("Use basic regular expressions instead of wildcards");
  108. flag.regex->guisection = _("Pattern");
  109. flag.extended = G_define_flag();
  110. flag.extended->key = 'e';
  111. flag.extended->description =
  112. _("Use extended regular expressions instead of wildcards");
  113. flag.extended->guisection = _("Pattern");
  114. flag.force = G_define_flag();
  115. flag.force->key = 'f';
  116. flag.force->guisection = _("Basic");
  117. flag.force->description =
  118. _("Force removal (required for actual deletion of files)");
  119. flag.basemap = G_define_flag();
  120. flag.basemap->key = 'b';
  121. flag.basemap->description = _("Remove base raster maps");
  122. G_option_exclusive(flag.regex, flag.extended, NULL);
  123. G_option_exclusive(opt.pattern, opt.name, NULL);
  124. G_option_exclusive(opt.exclude, opt.ignore, NULL);
  125. G_option_required(opt.pattern, opt.name, NULL);
  126. if (G_parser(argc, argv))
  127. exit(EXIT_FAILURE);
  128. if (opt.pattern->answer)
  129. pattern = opt.pattern->answer;
  130. else
  131. pattern = construct_pattern(opt.name->answers);
  132. if (opt.exclude->answer)
  133. exclude = opt.exclude->answer;
  134. else if (opt.ignore->answer)
  135. exclude = construct_pattern(opt.ignore->answers);
  136. else
  137. exclude = NULL;
  138. if ((flag.regex->answer || flag.extended->answer) && opt.pattern->answer)
  139. filter = G_ls_regex_filter(pattern, 0, (int)flag.extended->answer,
  140. (int)flag.ignorecase->answer);
  141. else {
  142. /* handle individual map names */
  143. if (strchr(pattern, ',')) {
  144. char *buf;
  145. buf = (char *)G_malloc(strlen(pattern) + 3);
  146. sprintf(buf, "{%s}", pattern);
  147. filter = G_ls_glob_filter(buf, 0, (int)flag.ignorecase->answer);
  148. }
  149. else
  150. filter = G_ls_glob_filter(pattern, 0, (int)flag.ignorecase->answer);
  151. }
  152. if (!filter)
  153. G_fatal_error(_("Unable to compile pattern <%s>"), pattern);
  154. if (exclude) {
  155. if ((flag.regex->answer || flag.extended->answer) &&
  156. opt.exclude->answer)
  157. exclude_filter = G_ls_regex_filter(exclude, 1,
  158. (int)flag.extended->answer,
  159. (int)flag.ignorecase->answer);
  160. else {
  161. /* handle individual map names */
  162. if (strchr(exclude, ',')) {
  163. char *buf;
  164. buf = (char *)G_malloc(strlen(exclude) + 3);
  165. sprintf(buf, "{%s}", exclude);
  166. exclude_filter = G_ls_glob_filter(buf, 1,
  167. (int)flag.ignorecase->answer);
  168. }
  169. else
  170. exclude_filter = G_ls_glob_filter(exclude, 1,
  171. (int)flag.ignorecase->answer);
  172. }
  173. if (!exclude_filter)
  174. G_fatal_error(_("Unable to compile pattern <%s>"), exclude);
  175. }
  176. else
  177. exclude_filter = NULL;
  178. if (!flag.force->answer)
  179. G_message(_("The following data base element files would be deleted:"));
  180. mapset = G_mapset();
  181. for (i = 0; opt.type->answers[i]; i++) {
  182. if (strcmp(opt.type->answers[i], "all") == 0)
  183. break;
  184. }
  185. if (opt.type->answers[i]) {
  186. all = 1;
  187. num_types = nlist;
  188. }
  189. else {
  190. all = 0;
  191. num_types = i;
  192. }
  193. num_removed = 0;
  194. for (i = 0; i < num_types; i++) {
  195. int n, rast, num_files, j;
  196. const struct list *elem;
  197. char path[GPATH_MAX];
  198. char **files;
  199. n = all ? i : M_get_element(opt.type->answers[i]);
  200. elem = M_get_list(n);
  201. G_file_name(path, elem->element[0], "", mapset);
  202. if (access(path, 0) != 0)
  203. continue;
  204. rast = !G_strcasecmp(elem->alias, "raster");
  205. files = G_ls2(path, &num_files);
  206. for (j = 0; j < num_files; j++) {
  207. if (!flag.force->answer) {
  208. fprintf(stdout, "%s/%s@%s\n", elem->alias, files[j], mapset);
  209. num_removed++;
  210. continue;
  211. }
  212. if (rast && check_reclass(files[j], mapset, flag.basemap->answer))
  213. continue;
  214. if (M_do_remove(n, (char *)files[j]) == 1)
  215. result = EXIT_FAILURE;
  216. num_removed++;
  217. }
  218. }
  219. if (num_removed < 1)
  220. G_warning(_("No data base element files found"));
  221. G_free_ls_filter(filter);
  222. if (exclude_filter)
  223. G_free_ls_filter(exclude_filter);
  224. if (!flag.force->answer && num_removed > 0)
  225. G_warning(_("Nothing removed. You must use the force flag (-%c) to actually "
  226. "remove them. Exiting."), flag.force->key);
  227. exit(result);
  228. }