[GRASS-SVN] r31881 - in grass-addons/general: . g.xlist g.xremove
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Jun 29 07:44:57 EDT 2008
Author: hcho
Date: 2008-06-29 07:44:57 -0400 (Sun, 29 Jun 2008)
New Revision: 31881
Added:
grass-addons/general/g.xlist/
grass-addons/general/g.xlist/Makefile
grass-addons/general/g.xlist/description.html
grass-addons/general/g.xlist/gisdefs.h
grass-addons/general/g.xlist/global.h
grass-addons/general/g.xlist/join.c
grass-addons/general/g.xlist/ls.c
grass-addons/general/g.xlist/main.c
grass-addons/general/g.xlist/read_list.c
grass-addons/general/g.xlist/wc2regex.c
grass-addons/general/g.xremove/
grass-addons/general/g.xremove/Makefile
grass-addons/general/g.xremove/check_reclass.c
grass-addons/general/g.xremove/description.html
grass-addons/general/g.xremove/do_remove.c
grass-addons/general/g.xremove/gisdefs.h
grass-addons/general/g.xremove/global.h
grass-addons/general/g.xremove/join.c
grass-addons/general/g.xremove/ls.c
grass-addons/general/g.xremove/main.c
grass-addons/general/g.xremove/read_list.c
grass-addons/general/g.xremove/sighold.c
grass-addons/general/g.xremove/wc2regex.c
Log:
Added g.xlist/g.xremove:
- C implementations of g.mlist/g.mremove
- No dependency on g.list/g.remove
- Requires POSIX regex(3) functions.
- Extended G__ls function.
- Added G_(set|get)_ls_filter and G_join_element functions.
Added: grass-addons/general/g.xlist/Makefile
===================================================================
--- grass-addons/general/g.xlist/Makefile (rev 0)
+++ grass-addons/general/g.xlist/Makefile 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../../../grass
+
+PGM = g.xlist
+
+LIBES = $(GISLIB)
+DEPENDENCIES = $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: grass-addons/general/g.xlist/description.html
===================================================================
--- grass-addons/general/g.xlist/description.html (rev 0)
+++ grass-addons/general/g.xlist/description.html 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,65 @@
+<h2>DESCRIPTION</h2>
+
+<em>g.xlist</em> searches for data files matching a pattern given by wildcards or POSIX Extended Regular Expressions.
+
+<h2>EXAMPLES</h2>
+
+List all available GRASS data base files:
+<div class="code"><pre>
+ g.xlist type=all
+</pre></div>
+
+List all raster and vector maps:
+<div class="code"><pre>
+ g.xlist type=rast,vect
+</pre></div>
+
+<h3>Wildcards:</h3>
+
+List all vector maps starting with letter "r":
+<div class="code"><pre>
+ g.xlist type=vect pattern="r*"
+</pre></div>
+
+List certain raster maps with one variable character/number:
+<div class="code"><pre>
+ g.xlist type=rast pattern="N45E00?.meters"
+</pre></div>
+
+<h3>Regular expressions:</h3>
+
+Print out all soils map with "soils" in their name:
+<div class="code"><pre>
+ g.xlist -r type=rast pattern='^soils'
+</pre></div>
+
+Print out "tmp" if "tmp" raster map exists:
+<div class="code"><pre>
+ g.xlist -r pattern='^tmp$'
+</pre></div>
+
+Print out "tmp0" ..."tmp9" if corresponding vector map exists (each map name linewise):
+<div class="code"><pre>
+ g.xlist -r type=vect pattern='^tmp[0-9]$'
+</pre></div>
+
+Print out "tmp0" ..."tmp9" if corresponding vector map exists (each map name comma separated):
+<div class="code"><pre>
+ g.xlist -r type=vect separator=, pattern='^tmp[0-9]$'
+</pre></div>
+
+This may be useful for other programs' parameter input
+(e.g. <em><a href="r.series.html">r.series</a></em>).
+
+<h2>SEE ALSO</h2>
+
+<em><a href="g.list.html">g.list</a></em>
+<p>
+<a href="http://en.wikipedia.org/wiki/Regular_expression">Regular expression</a> (from Wikipedia, the free encyclopedia)
+
+<h2>AUTHOR</h2>
+
+Huidae Cho<br>
+grass4u at gmail.com
+
+<p><i>Last changed: $Date: 2008-06-28 04:37:22 -0500 (Sat, 28 Jun 2008) $</i>
Added: grass-addons/general/g.xlist/gisdefs.h
===================================================================
--- grass-addons/general/g.xlist/gisdefs.h (rev 0)
+++ grass-addons/general/g.xlist/gisdefs.h 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,16 @@
+#ifndef GISDEFS_H
+#define GISDEFS_H
+
+#define G_JOIN_ELEMENT_TYPE 0x1
+#define G_JOIN_ELEMENT_MAPSET 0x2
+
+/* join.c */
+const char *G_join_element(const char *, const char *, const char *,
+ const char *, int, int *);
+
+/* ls.c */
+void G_set_ls_filter(const char *);
+const char *G_get_ls_filter(void);
+const char **G__ls(const char *, int *);
+
+#endif
Added: grass-addons/general/g.xlist/global.h
===================================================================
--- grass-addons/general/g.xlist/global.h (rev 0)
+++ grass-addons/general/g.xlist/global.h 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,29 @@
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+struct list
+{
+ char **element; /* list of related elements */
+ char *alias; /* element alias */
+ char **desc; /* description of elements */
+ char *text; /* menu text */
+ int nelem; /* number of elements */
+ char status;
+ char *mainelem; /* main element */
+ char *maindesc; /* main element description */
+};
+
+/* read_list.c */
+int read_list(int);
+
+/* wc2regex.c */
+char *wc2regex(const char *);
+
+#ifdef MAIN
+# define GLOBAL
+#else
+# define GLOBAL extern
+#endif
+
+GLOBAL int nlist;
+GLOBAL struct list *list;
Added: grass-addons/general/g.xlist/join.c
===================================================================
--- grass-addons/general/g.xlist/join.c (rev 0)
+++ grass-addons/general/g.xlist/join.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,158 @@
+
+/**
+ \file join.c
+
+ \brief Return a string that contains elements
+
+ \author Huidae Cho
+
+ (C) 2008 by the GRASS Development Team
+
+ This program is free software under the GNU General Public
+ License (>=v2). Read the file COPYING that comes with GRASS
+ for details.
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "gisdefs.h"
+
+static int join_element(const char *, const char *, const char *,
+ const char *, int, const char **);
+
+/**
+ \brief General purpose join function.
+
+ Will collect file names from all mapsets
+ in the mapset list for a specified database element
+ and join them into a string.
+
+ Note: Use G_(set|get)_ls_filter functions to filter out unwanted file names.
+
+ \param element Database element (eg, "cell", "cellhd", etc)
+ \param alias Alias for element (if NULL, element is used)
+ \param mapset Mapset to be listed "" to list all mapsets in mapset search list
+ "." will list current mapset
+ \param separator Map name separator
+ \param flags G_JOIN_ELEMENT_TYPE Include alias
+ G_JOIN_ELEMENT_MAPSET Include mapset name
+ \param count Return the number of elements (if NULL, ignored)
+
+ \return String pointer
+*/
+const char *G_join_element(const char *element,
+ const char *alias,
+ const char *mapset,
+ const char *separator, int flags, int *count)
+{
+ int c, n;
+ const char *buf;
+
+ c = 0;
+ if (alias == 0 || *alias == 0)
+ alias = element;
+
+ /*
+ * if no specific mapset is requested, list the mapsets
+ * from the mapset search list
+ * otherwise just list the specified mapset
+ */
+ buf = G_strdup("");
+ if (mapset == 0 || *mapset == 0)
+ for (n = 0; (mapset = G__mapset_name(n)); n++)
+ c += join_element(element, alias, mapset, separator, flags, &buf);
+ else
+ c = join_element(element, alias, mapset, separator, flags, &buf);
+
+ if (count)
+ *count = c;
+ return buf;
+}
+
+static int join_element(const char *element,
+ const char *alias,
+ const char *mapset,
+ const char *separator, int flags, const char **buf)
+{
+ char path[GPATH_MAX], *p;
+ int i, count = 0;
+ int buf_len, alias_len, list_len, sep_len = strlen(separator), mapset_len;
+ const char **list;
+
+ /*
+ * convert . to current mapset
+ */
+ if (strcmp(mapset, ".") == 0)
+ mapset = G_mapset();
+
+ mapset_len = strlen(mapset);
+
+ /*
+ * get the full name of the GIS directory within the mapset
+ * and list its contents (if it exists)
+ */
+ G__file_name(path, element, "", mapset);
+ if (access(path, 0) != 0)
+ return count;
+
+ list = G__ls(path, &count);
+
+ alias_len = strlen(alias);
+ for (i = 0; i < count; i++) {
+ buf_len = strlen(*buf);
+ list_len = strlen(list[i]);
+ *buf = (char *)G_realloc((char *)*buf,
+ (buf_len ? buf_len + sep_len : 0) +
+ (flags & G_JOIN_ELEMENT_TYPE ? alias_len +
+ 1 : 0) + list_len +
+ (flags & G_JOIN_ELEMENT_MAPSET ? mapset_len +
+ 1 : 0) + 1);
+ p = (char *)*buf + buf_len;
+
+ /* looks dirty but fast! */
+ if (buf_len) {
+ if (flags & G_JOIN_ELEMENT_TYPE) {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s%s/%s@%s", separator, alias, list[i],
+ mapset);
+ else
+ sprintf(p, "%s%s/%s", separator, alias, list[i]);
+ }
+ else {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s%s@%s", separator, list[i], mapset);
+ else
+ sprintf(p, "%s%s", separator, list[i]);
+ }
+ }
+ else {
+ if (flags & G_JOIN_ELEMENT_TYPE) {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s/%s@%s", alias, list[i], mapset);
+ else
+ sprintf(p, "%s/%s", alias, list[i]);
+ }
+ else {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s@%s", list[i], mapset);
+ else
+ sprintf(p, "%s", list[i]);
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++)
+ G_free((char *)list[i]);
+ if (list)
+ G_free(list);
+
+ return count;
+}
Added: grass-addons/general/g.xlist/ls.c
===================================================================
--- grass-addons/general/g.xlist/ls.c (rev 0)
+++ grass-addons/general/g.xlist/ls.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,133 @@
+
+/**
+ \file ls.c
+
+ \brief Functions to list the files in a directory.
+
+ \author Paul Kelly, Huidae Cho
+
+ (C) 2007, 2008 by the GRASS Development Team
+
+ This program is free software under the GNU General Public
+ License (>=v2). Read the file COPYING that comes with GRASS
+ for details.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <regex.h>
+
+#include <grass/gis.h>
+#include <grass/config.h>
+#include <grass/glocale.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+
+#define LS_FILTER_FLAGS REG_EXTENDED|REG_NOSUB
+static char *ls_filter = NULL;
+
+static int cmp_names(const void *aa, const void *bb)
+{
+ char *const *a = (char *const *)aa;
+ char *const *b = (char *const *)bb;
+
+ return strcmp(*a, *b);
+}
+
+/**
+ * \brief Sets a filter for G__ls using POSIX Extended Regular Expressions.
+ *
+ * Defines the pattern that allows G__ls to filter out unwanted file names.
+ * Call this function before G__ls.
+ *
+ * \param pattern POSIX Extended Regular Expressions
+ * (if NULL, no filter will be used)
+ **/
+void G_set_ls_filter(const char *pattern)
+{
+ regex_t reg;
+
+ if (ls_filter)
+ G_free(ls_filter);
+ if (pattern) {
+ ls_filter = G_strdup(pattern);
+ if (regcomp(®, ls_filter, LS_FILTER_FLAGS) != 0)
+ G_fatal_error(_("Unable to compile regular expression %s"),
+ ls_filter);
+ regfree(®);
+ }
+ else
+ ls_filter = NULL;
+
+ return;
+}
+
+/**
+ * \brief Gets a filter string for G__ls.
+ *
+ * Returns the filter pattern defined by G_set_ls_filter.
+ *
+ * \return Filter pattern
+ **/
+const char *G_get_ls_filter(void)
+{
+ return ls_filter;
+}
+
+/**
+ * \brief Stores a sorted directory listing in an array
+ *
+ * The filenames in the specified directory are stored in an array of
+ * strings, then sorted alphabetically. Each filename has space allocated
+ * using G_store(), which can be freed using G_free() if necessary. The
+ * same goes for the array itself.
+ *
+ *
+ * \param dir Directory to list
+ * \param num_files Pointer to an integer in which the total number of
+ * files listed will be stored
+ *
+ * \return Pointer to array of strings containing the listing
+ **/
+
+const char **G__ls(const char *dir, int *num_files)
+{
+ struct dirent *dp;
+ DIR *dfd;
+ const char **dir_listing = NULL;
+ int n = 0;
+ regex_t reg;
+
+ if ((dfd = opendir(dir)) == NULL)
+ G_fatal_error(_("Unable to open directory %s"), dir);
+
+ if (ls_filter && regcomp(®, ls_filter, LS_FILTER_FLAGS) != 0)
+ G_fatal_error(_("Unable to compile regular expression %s"),
+ ls_filter);
+
+ while ((dp = readdir(dfd)) != NULL) {
+ if (dp->d_name[0] != '.' && /* Don't list hidden files */
+ (ls_filter == NULL || regexec(®, dp->d_name, 0, NULL, 0) == 0)) {
+ dir_listing = (const char **)G_realloc(dir_listing,
+ (1 + n) * sizeof(char *));
+ dir_listing[n] = G_store(dp->d_name);
+ n++;
+ }
+ }
+
+ if (ls_filter)
+ regfree(®);
+
+ /* Sort list of filenames alphabetically */
+ qsort(dir_listing, n, sizeof(char *), cmp_names);
+
+ *num_files = n;
+ return dir_listing;
+}
Added: grass-addons/general/g.xlist/main.c
===================================================================
--- grass-addons/general/g.xlist/main.c (rev 0)
+++ grass-addons/general/g.xlist/main.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,247 @@
+
+/****************************************************************************
+ *
+ * MODULE: g.xlist
+ *
+ * AUTHOR(S): Huidae Cho
+ * Based on general/manage/cmd/list.c by Michael Shapiro.
+ *
+ * PURPOSE: Lists available GRASS data base files of the
+ * user-specified data type to standard output
+ *
+ * COPYRIGHT: (C) 1999-2008 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ *****************************************************************************/
+
+#define MAIN
+#include <stdlib.h>
+#include <string.h>
+#include <grass/spawn.h>
+#include "gisdefs.h"
+#include "global.h"
+
+static int parse(const char *);
+static int do_list(int, const char *, const char *, int, const char *, int);
+
+int main(int argc, char *argv[])
+{
+ struct GModule *module;
+ struct
+ {
+ struct Option *type;
+ struct Option *pattern;
+ struct Option *separator;
+ struct Option *mapset;
+ } opt;
+ struct
+ {
+ struct Flag *regex;
+ struct Flag *type;
+ struct Flag *mapset;
+ struct Flag *pretty;
+ struct Flag *full;
+ } flag;
+ int i, n, all, num_types, any, flags = 0;
+ char **types, *pattern = NULL, separator[2];
+
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+ module->keywords = _("general, map management");
+ module->description =
+ _("Lists available GRASS data base files "
+ "of the user-specified data type to standard output.");
+
+ read_list(0);
+
+ opt.type = G_define_option();
+ opt.type->key = "type";
+ opt.type->key_desc = "datatype";
+ opt.type->type = TYPE_STRING;
+ opt.type->required = YES;
+ opt.type->multiple = YES;
+ opt.type->answer = "rast";
+ opt.type->description = "Data type";
+ for (i = 0, n = 0; n < nlist; n++)
+ i += strlen(list[n].alias) + 1;
+ opt.type->options = G_malloc(i + 4);
+
+ opt.type->options[0] = 0;
+ for (n = 0; n < nlist; n++) {
+ G_strcat(opt.type->options, list[n].alias);
+ G_strcat(opt.type->options, ",");
+ }
+ G_strcat(opt.type->options, "all");
+#define TYPES opt.type->answers
+
+ opt.pattern = G_define_option();
+ opt.pattern->key = "pattern";
+ opt.pattern->type = TYPE_STRING;
+ opt.pattern->required = NO;
+ opt.pattern->multiple = NO;
+ opt.pattern->answer = "*";
+ opt.pattern->description = _("Map name search pattern (default: all)");
+#define PATTERN opt.pattern->answer
+
+ opt.separator = G_define_option();
+ opt.separator->key = "separator";
+ opt.separator->type = TYPE_STRING;
+ opt.separator->required = NO;
+ opt.separator->multiple = NO;
+ opt.separator->answer = "newline";
+ opt.separator->description =
+ _("One-character output separator, newline, space, or tab");
+#define SEPARATOR opt.separator->answer
+
+ opt.mapset = G_define_option();
+ opt.mapset->key = "mapset";
+ opt.mapset->type = TYPE_STRING;
+ opt.mapset->required = NO;
+ opt.mapset->multiple = NO;
+ opt.mapset->description =
+ _("Mapset to list (default: current search path)");
+#define MAPSET opt.mapset->answer
+
+ flag.regex = G_define_flag();
+ flag.regex->key = 'r';
+ flag.regex->description =
+ _("Use extended regular expressions instead of wildcards");
+#define FREGEX flag.regex->answer
+
+ flag.type = G_define_flag();
+ flag.type->key = 't';
+ flag.type->description = _("Print data types");
+#define FTYPE flag.type->answer
+
+ flag.mapset = G_define_flag();
+ flag.mapset->key = 'm';
+ flag.mapset->description = _("Print mapset names");
+#define FMAPSET flag.mapset->answer
+
+ flag.pretty = G_define_flag();
+ flag.pretty->key = 'p';
+ flag.pretty->description = _("Pretty printing in human readable format");
+#define FPRETTY flag.pretty->answer
+
+ flag.full = G_define_flag();
+ flag.full->key = 'f';
+ flag.full->description = _("Verbose listing (also list map titles)");
+#define FFULL flag.full->answer
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ if (!FREGEX) {
+ pattern = wc2regex(PATTERN);
+ G_free(PATTERN);
+ PATTERN = pattern;
+ }
+
+ G_set_ls_filter(PATTERN);
+#if 0
+ fprintf(stderr, "%s\n", G_get_ls_filter());
+#endif
+
+ if (strcmp(SEPARATOR, "newline") == 0)
+ separator[0] = '\n';
+ else if (strcmp(SEPARATOR, "space") == 0)
+ separator[0] = ' ';
+ else if (strcmp(SEPARATOR, "tab") == 0)
+ separator[0] = '\t';
+ else
+ separator[0] = SEPARATOR[0];
+ separator[1] = 0;
+
+ if (MAPSET == NULL)
+ MAPSET = "";
+
+ if (G_strcasecmp(MAPSET, ".") == 0)
+ MAPSET = G_mapset();
+
+ for (i = 0; TYPES[i]; i++) {
+ if (strcmp(TYPES[i], "all") == 0)
+ break;
+ }
+ if (TYPES[i]) {
+ all = 1;
+ num_types = nlist;
+ }
+ else {
+ all = 0;
+ num_types = i;
+ }
+
+ if (FTYPE)
+ flags |= G_JOIN_ELEMENT_TYPE;
+ if (FMAPSET)
+ flags |= G_JOIN_ELEMENT_MAPSET;
+
+ for (i = 0; i < num_types; i++) {
+ n = all ? i : parse(TYPES[i]);
+
+ if (FFULL) {
+ char lister[300];
+
+ sprintf(lister, "%s/etc/lister/%s", G_gisbase(),
+ list[n].element[0]);
+ G_debug(3, "lister CMD: %s", lister);
+ if (access(lister, 1) == 0) /* execute permission? */
+ G_spawn(lister, lister, MAPSET, NULL);
+ else
+ any = do_list(n, PATTERN, MAPSET, FPRETTY, separator, flags);
+ }
+ else
+ any = do_list(n, PATTERN, MAPSET, FPRETTY, separator, flags);
+ }
+ if (!FPRETTY && any)
+ fprintf(stdout, "\n");
+
+ if (pattern)
+ G_free(pattern);
+
+ exit(EXIT_SUCCESS);
+}
+
+static int parse(const char *data_type)
+{
+ int n;
+
+ for (n = 0; n < nlist; n++) {
+ if (G_strcasecmp(list[n].alias, data_type) == 0)
+ break;
+ }
+
+ return n;
+}
+
+static int do_list(int n, const char *pattern, const char *mapset,
+ int pretty, const char *separator, int flags)
+{
+ static int any = 0;
+ const char *buf;
+ int len;
+
+ if (pretty) {
+ G_list_element(list[n].element[0], list[n].alias, mapset,
+ (int (*)())0);
+ return 1;
+ }
+
+ buf =
+ G_join_element(list[n].element[0], list[n].alias, mapset, separator,
+ flags, NULL);
+ len = strlen(buf);
+ if (any && len)
+ fprintf(stdout, "%s", separator);
+ if (len)
+ fprintf(stdout, "%s", buf);
+ G_free((char *)buf);
+
+ any += len > 0;
+
+ return any;
+}
Added: grass-addons/general/g.xlist/read_list.c
===================================================================
--- grass-addons/general/g.xlist/read_list.c (rev 0)
+++ grass-addons/general/g.xlist/read_list.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,148 @@
+/* Copied from general/manage */
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include "global.h"
+
+/*******************************************************************
+read the element list file
+
+ format is:
+
+ # ... comments
+ main element:alias:description:menu text
+ sub element:description
+ sub element:description
+ .
+ .
+ .
+******************************************************************/
+
+static int add_element(const char *, const char *);
+static int empty(const char *);
+static int format_error(const char *, int, const char *);
+
+int read_list(int check_if_empty)
+{
+ FILE *fd;
+ char element_list[600], buf[1024], elem[100], alias[100], desc[100],
+ text[100], *env;
+ int any, line;
+
+ nlist = 0;
+ list = 0;
+ any = 0;
+
+ if ((env = G__getenv("ELEMENT_LIST")))
+ G_strcpy(element_list, env);
+ else
+ sprintf(element_list, "%s/etc/element_list", G_gisbase());
+ fd = fopen(element_list, "r");
+
+ if (!fd)
+ G_fatal_error("can't open database element list <%s>", element_list);
+
+ line = 0;
+ while (G_getl(buf, sizeof(buf), fd)) {
+ line++;
+ if (*buf == '#')
+ continue;
+ if (*buf == ' ' || *buf == '\t') { /* support element */
+ *desc = 0;
+ if (sscanf(buf, "%[^:]:%[^\n]", elem, desc) < 1)
+ continue;
+ if (*elem == '#')
+ continue;
+ if (nlist == 0)
+ format_error(element_list, line, buf);
+
+ G_strip(elem);
+ G_strip(desc);
+ add_element(elem, desc);
+ }
+ else { /* main element */
+
+ if (sscanf
+ (buf, "%[^:]:%[^:]:%[^:]:%[^\n]", elem, alias, desc,
+ text) != 4)
+ format_error(element_list, line, buf);
+
+ G_strip(elem);
+ G_strip(alias);
+ G_strip(desc);
+ G_strip(text);
+
+ list =
+ (struct list *)G_realloc(list, (nlist + 1) * sizeof(*list));
+ list[nlist].mainelem = G_store(elem);
+ list[nlist].alias = G_store(alias);
+ list[nlist].maindesc = G_store(desc);
+ list[nlist].text = G_store(text);
+ list[nlist].nelem = 0;
+ list[nlist].element = 0;
+ list[nlist].desc = 0;
+ list[nlist].status = 0;
+ if (!check_if_empty || !empty(elem)) {
+ list[nlist].status = 1;
+ any = 1;
+ }
+ nlist++;
+ add_element(elem, desc);
+ }
+ }
+
+ fclose(fd);
+
+ return any;
+}
+
+static int add_element(const char *elem, const char *desc)
+{
+ int n;
+ int nelem;
+
+ if (*desc == 0)
+ desc = elem;
+
+ n = nlist - 1;
+ nelem = list[n].nelem++;
+ list[n].element =
+ (char **)G_realloc(list[n].element, (nelem + 1) * sizeof(char *));
+ list[n].element[nelem] = G_store(elem);
+ list[n].desc =
+ (char **)G_realloc(list[n].desc, (nelem + 1) * sizeof(char *));
+ list[n].desc[nelem] = G_store(desc);
+
+ return 0;
+}
+
+static int empty(const char *elem)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ char dir[1024];
+ int any;
+
+ G__file_name(dir, elem, "", G_mapset());
+
+ any = 0;
+ if ((dirp = opendir(dir)) != NULL) {
+ while (!any && (dp = readdir(dirp)) != NULL) {
+ if (dp->d_name[0] != '.')
+ any = 1;
+ }
+ closedir(dirp);
+ }
+
+ return any == 0;
+}
+
+static int format_error(const char *element_list, int line, const char *buf)
+{
+ G_fatal_error(_("Format error: <%s>\nLine: %d\n%s"), element_list, line,
+ buf);
+
+ return 1;
+}
Added: grass-addons/general/g.xlist/wc2regex.c
===================================================================
--- grass-addons/general/g.xlist/wc2regex.c (rev 0)
+++ grass-addons/general/g.xlist/wc2regex.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,46 @@
+#include <grass/gis.h>
+
+char *wc2regex(const char *wc)
+{
+ int i, j;
+ char *regex;
+
+ for (i = 0, j = 2; wc[i]; i++, j++) {
+ switch (wc[i]) {
+ case '.':
+ case '*':
+ j++;
+ break;
+ }
+ }
+ regex = (char *)G_malloc(j + 1);
+ j = 0;
+ regex[j++] = '^';
+ for (i = 0; wc[i]; i++) {
+ switch (wc[i]) {
+ case '.':
+ regex[j++] = '\\';
+ break;
+ case '*':
+ regex[j++] = '.';
+ break;
+ case '?':
+ regex[j++] = '.';
+ continue;
+ case '{':
+ regex[j++] = '(';
+ continue;
+ case '}':
+ regex[j++] = ')';
+ continue;
+ case ',':
+ regex[j++] = '|';
+ continue;
+ }
+ regex[j++] = wc[i];
+ }
+ regex[j++] = '$';
+ regex[j] = 0;
+
+ return regex;
+}
Added: grass-addons/general/g.xremove/Makefile
===================================================================
--- grass-addons/general/g.xremove/Makefile (rev 0)
+++ grass-addons/general/g.xremove/Makefile 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../../../grass
+
+PGM = g.xremove
+
+LIBES = $(GISLIB) $(VECTLIB) $(G3DLIB)
+DEPENDENCIES = $(GISDEP) $(VECTDEP) $(G3DDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: grass-addons/general/g.xremove/check_reclass.c
===================================================================
--- grass-addons/general/g.xremove/check_reclass.c (rev 0)
+++ grass-addons/general/g.xremove/check_reclass.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,62 @@
+#include <string.h>
+#include "global.h"
+
+int check_reclass(const char *name, const char *mapset, int force)
+{
+ char rname[GNAME_MAX], rmapset[GMAPSET_MAX];
+ char **rmaps;
+ int nrmaps;
+
+ if (G_is_reclassed_to(name, mapset, &nrmaps, &rmaps) > 0) {
+ for (; *rmaps; rmaps++) {
+ /* force remove */
+ if (force)
+ G_warning(_("[%s@%s] is a base map for [%s]. Remove forced."),
+ name, mapset, *rmaps);
+ else
+ G_warning(_
+ ("[%s@%s] is a base map. Remove reclassed map first: %s"),
+ name, mapset, *rmaps);
+ }
+
+ if (!force)
+ return 1;
+ }
+
+ if (G_is_reclass(name, mapset, rname, rmapset) > 0 &&
+ G_is_reclassed_to(rname, rmapset, &nrmaps, &rmaps) > 0) {
+ char path[GPATH_MAX];
+ char *p = strchr(rname, '@');
+ char *qname = G_fully_qualified_name(name, mapset);
+
+ if (p)
+ *p = '\0';
+
+ G__file_name_misc(path, "cell_misc", "reclassed_to", rname, rmapset);
+
+ if (nrmaps == 1 && !G_strcasecmp(rmaps[0], qname)) {
+
+ if (remove(path) < 0)
+ G_warning(_
+ ("Removing information about reclassed map from [%s@%s] failed"),
+ rname, rmapset);
+ }
+ else {
+ FILE *fp = fopen(path, "w");
+
+ if (fp) {
+ for (; *rmaps; rmaps++)
+ if (G_strcasecmp(*rmaps, qname))
+ fprintf(fp, "%s\n", *rmaps);
+ fclose(fp);
+ }
+ else
+ G_warning(_
+ ("Removing information about reclassed map from [%s@%s] failed"),
+ rname, rmapset);
+
+ }
+ }
+
+ return 0;
+}
Added: grass-addons/general/g.xremove/description.html
===================================================================
--- grass-addons/general/g.xremove/description.html (rev 0)
+++ grass-addons/general/g.xremove/description.html 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,26 @@
+<h2>DESCRIPTION</h2>
+
+<em>g.xremove</em> removes data files matching a pattern given by wildcards or POSIX Extended Regular Expressions.
+If the <b>-f</b> force flag is not given then nothing is removed, instead
+the list of selected file names is printed to <tt>stdout</tt>
+as a preview of the files to be deleted.
+
+<h2>EXAMPLE</h2>
+
+Delete all raster maps starting with "<tt>tmp_</tt>" in the current mapset:
+<div class="code"><pre>
+ g.xremove -f "tmp_*"
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em><a HREF="g.remove.html">g.remove</a></em>
+<p>
+<a href="http://en.wikipedia.org/wiki/Regular_expression">Regular expression</a> (from Wikipedia, the free encyclopedia)
+
+<h2>AUTHOR</h2>
+
+Huidae Cho<br>
+grass4u at gmail.com
+
+<p><i>Last changed: $Date: 2008-06-28 03:23:07 -0500 (Sat, 28 Jun 2008) $</i>
Added: grass-addons/general/g.xremove/do_remove.c
===================================================================
--- grass-addons/general/g.xremove/do_remove.c (rev 0)
+++ grass-addons/general/g.xremove/do_remove.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,106 @@
+#include <string.h>
+#include <grass/Vect.h>
+#include <grass/G3d.h>
+#include "global.h"
+
+/*
+ * returns 0 - success
+ * 1 - error
+ */
+int do_remove(int n, char *old)
+{
+ int i, ret;
+
+ /* int len; */
+ char *mapset;
+ int result = 0;
+ int removed = 0;
+ char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
+
+ G_message(_("Removing %s <%s>"), list[n].maindesc, old);
+
+ /* len = get_description_len(n); */
+
+ hold_signals(1);
+
+ if (G__name_is_fully_qualified(old, xname, xmapset)) {
+ if (strcmp(xmapset, G_mapset()) != 0)
+ G_fatal_error("%s is not in the current mapset (%s)", old,
+ G_mapset());
+ old = xname;
+ }
+
+ if (G_strcasecmp(list[n].alias, "vect") == 0) {
+ if ((mapset = G_find_vector2(old, "")) == NULL) {
+ G_warning(_("Vector map <%s> not found"), old);
+ }
+ else {
+ ret = Vect_delete(old);
+ if (ret != -1) {
+ removed = 1;
+ }
+ else {
+ G_warning(_("couldn't be removed"));
+ result = 1;
+ }
+ }
+ }
+ else {
+ if (G_strcasecmp(list[n].alias, "rast") == 0) {
+ if ((mapset = G_find_cell2(old, "")) == NULL)
+ G_warning(_("Raster map <%s> not found"), old);
+ }
+
+ if (G_strcasecmp(list[n].alias, "rast3d") == 0) {
+ if ((mapset = G_find_grid3(old, "")) == NULL)
+ G_warning(_("3D raster map <%s> not found"), old);
+ }
+
+ for (i = 0; i < list[n].nelem; i++) {
+
+ switch (G_remove(list[n].element[i], old)) {
+ case -1:
+ G_warning(_("%s: couldn't be removed"), list[n].desc[i]);
+ result = 1;
+ break;
+ case 0:
+ if (G_verbose() == G_verbose_max())
+ G_message(_("%s: missing"), list[n].desc[i]);
+ break;
+ case 1:
+ if (G_verbose() == G_verbose_max())
+ G_message(_("%s: removed"), list[n].desc[i]);
+ removed = 1;
+ break;
+ }
+ }
+ }
+
+ if (G_strcasecmp(list[n].element[0], "cell") == 0) {
+ char colr2[50];
+
+ sprintf(colr2, "colr2/%s", G_mapset());
+ switch (G_remove(colr2, old)) {
+ case -1:
+ G_warning("%s: %s", colr2, _("couldn't be removed"));
+ result = 1;
+ break;
+ case 0:
+ if (G_verbose() == G_verbose_max())
+ G_message(_("%s: missing"), colr2);
+ break;
+ case 1:
+ if (G_verbose() == G_verbose_max())
+ G_message(_("%s: removed"), colr2);
+ removed = 1;
+ break;
+ }
+ }
+
+ hold_signals(0);
+
+ if (!removed)
+ G_warning(_("<%s> nothing removed"), old);
+
+ return result;
+}
Added: grass-addons/general/g.xremove/gisdefs.h
===================================================================
--- grass-addons/general/g.xremove/gisdefs.h (rev 0)
+++ grass-addons/general/g.xremove/gisdefs.h 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,16 @@
+#ifndef GISDEFS_H
+#define GISDEFS_H
+
+#define G_JOIN_ELEMENT_TYPE 0x1
+#define G_JOIN_ELEMENT_MAPSET 0x2
+
+/* join.c */
+const char *G_join_element(const char *, const char *, const char *,
+ const char *, int, int *);
+
+/* ls.c */
+void G_set_ls_filter(const char *);
+const char *G_get_ls_filter(void);
+const char **G__ls(const char *, int *);
+
+#endif
Added: grass-addons/general/g.xremove/global.h
===================================================================
--- grass-addons/general/g.xremove/global.h (rev 0)
+++ grass-addons/general/g.xremove/global.h 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,38 @@
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+struct list
+{
+ char **element; /* list of related elements */
+ char *alias; /* element alias */
+ char **desc; /* description of elements */
+ char *text; /* menu text */
+ int nelem; /* number of elements */
+ char status;
+ char *mainelem; /* main element */
+ char *maindesc; /* main element description */
+};
+
+/* read_list.c */
+int read_list(int);
+
+/* wc2regex.c */
+char *wc2regex(const char *);
+
+/* check_reclass.c */
+int check_reclass(const char *, const char *, int);
+
+/* sighold.c */
+int hold_signals(int);
+
+/* do_remove.c */
+int do_remove(int, char *);
+
+#ifdef MAIN
+# define GLOBAL
+#else
+# define GLOBAL extern
+#endif
+
+GLOBAL int nlist;
+GLOBAL struct list *list;
Added: grass-addons/general/g.xremove/join.c
===================================================================
--- grass-addons/general/g.xremove/join.c (rev 0)
+++ grass-addons/general/g.xremove/join.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,158 @@
+
+/**
+ \file join.c
+
+ \brief Return a string that contains elements
+
+ \author Huidae Cho
+
+ (C) 2008 by the GRASS Development Team
+
+ This program is free software under the GNU General Public
+ License (>=v2). Read the file COPYING that comes with GRASS
+ for details.
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "gisdefs.h"
+
+static int join_element(const char *, const char *, const char *,
+ const char *, int, const char **);
+
+/**
+ \brief General purpose join function.
+
+ Will collect file names from all mapsets
+ in the mapset list for a specified database element
+ and join them into a string.
+
+ Note: Use G_(set|get)_ls_filter functions to filter out unwanted file names.
+
+ \param element Database element (eg, "cell", "cellhd", etc)
+ \param alias Alias for element (if NULL, element is used)
+ \param mapset Mapset to be listed "" to list all mapsets in mapset search list
+ "." will list current mapset
+ \param separator Map name separator
+ \param flags G_JOIN_ELEMENT_TYPE Include alias
+ G_JOIN_ELEMENT_MAPSET Include mapset name
+ \param count Return the number of elements (if NULL, ignored)
+
+ \return String pointer
+*/
+const char *G_join_element(const char *element,
+ const char *alias,
+ const char *mapset,
+ const char *separator, int flags, int *count)
+{
+ int c, n;
+ const char *buf;
+
+ c = 0;
+ if (alias == 0 || *alias == 0)
+ alias = element;
+
+ /*
+ * if no specific mapset is requested, list the mapsets
+ * from the mapset search list
+ * otherwise just list the specified mapset
+ */
+ buf = G_strdup("");
+ if (mapset == 0 || *mapset == 0)
+ for (n = 0; (mapset = G__mapset_name(n)); n++)
+ c += join_element(element, alias, mapset, separator, flags, &buf);
+ else
+ c = join_element(element, alias, mapset, separator, flags, &buf);
+
+ if (count)
+ *count = c;
+ return buf;
+}
+
+static int join_element(const char *element,
+ const char *alias,
+ const char *mapset,
+ const char *separator, int flags, const char **buf)
+{
+ char path[GPATH_MAX], *p;
+ int i, count = 0;
+ int buf_len, alias_len, list_len, sep_len = strlen(separator), mapset_len;
+ const char **list;
+
+ /*
+ * convert . to current mapset
+ */
+ if (strcmp(mapset, ".") == 0)
+ mapset = G_mapset();
+
+ mapset_len = strlen(mapset);
+
+ /*
+ * get the full name of the GIS directory within the mapset
+ * and list its contents (if it exists)
+ */
+ G__file_name(path, element, "", mapset);
+ if (access(path, 0) != 0)
+ return count;
+
+ list = G__ls(path, &count);
+
+ alias_len = strlen(alias);
+ for (i = 0; i < count; i++) {
+ buf_len = strlen(*buf);
+ list_len = strlen(list[i]);
+ *buf = (char *)G_realloc((char *)*buf,
+ (buf_len ? buf_len + sep_len : 0) +
+ (flags & G_JOIN_ELEMENT_TYPE ? alias_len +
+ 1 : 0) + list_len +
+ (flags & G_JOIN_ELEMENT_MAPSET ? mapset_len +
+ 1 : 0) + 1);
+ p = (char *)*buf + buf_len;
+
+ /* looks dirty but fast! */
+ if (buf_len) {
+ if (flags & G_JOIN_ELEMENT_TYPE) {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s%s/%s@%s", separator, alias, list[i],
+ mapset);
+ else
+ sprintf(p, "%s%s/%s", separator, alias, list[i]);
+ }
+ else {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s%s@%s", separator, list[i], mapset);
+ else
+ sprintf(p, "%s%s", separator, list[i]);
+ }
+ }
+ else {
+ if (flags & G_JOIN_ELEMENT_TYPE) {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s/%s@%s", alias, list[i], mapset);
+ else
+ sprintf(p, "%s/%s", alias, list[i]);
+ }
+ else {
+ if (flags & G_JOIN_ELEMENT_MAPSET)
+ sprintf(p, "%s@%s", list[i], mapset);
+ else
+ sprintf(p, "%s", list[i]);
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++)
+ G_free((char *)list[i]);
+ if (list)
+ G_free(list);
+
+ return count;
+}
Added: grass-addons/general/g.xremove/ls.c
===================================================================
--- grass-addons/general/g.xremove/ls.c (rev 0)
+++ grass-addons/general/g.xremove/ls.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,133 @@
+
+/**
+ \file ls.c
+
+ \brief Functions to list the files in a directory.
+
+ \author Paul Kelly, Huidae Cho
+
+ (C) 2007, 2008 by the GRASS Development Team
+
+ This program is free software under the GNU General Public
+ License (>=v2). Read the file COPYING that comes with GRASS
+ for details.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <regex.h>
+
+#include <grass/gis.h>
+#include <grass/config.h>
+#include <grass/glocale.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+
+#define LS_FILTER_FLAGS REG_EXTENDED|REG_NOSUB
+static char *ls_filter = NULL;
+
+static int cmp_names(const void *aa, const void *bb)
+{
+ char *const *a = (char *const *)aa;
+ char *const *b = (char *const *)bb;
+
+ return strcmp(*a, *b);
+}
+
+/**
+ * \brief Sets a filter for G__ls using POSIX Extended Regular Expressions.
+ *
+ * Defines the pattern that allows G__ls to filter out unwanted file names.
+ * Call this function before G__ls.
+ *
+ * \param pattern POSIX Extended Regular Expressions
+ * (if NULL, no filter will be used)
+ **/
+void G_set_ls_filter(const char *pattern)
+{
+ regex_t reg;
+
+ if (ls_filter)
+ G_free(ls_filter);
+ if (pattern) {
+ ls_filter = G_strdup(pattern);
+ if (regcomp(®, ls_filter, LS_FILTER_FLAGS) != 0)
+ G_fatal_error(_("Unable to compile regular expression %s"),
+ ls_filter);
+ regfree(®);
+ }
+ else
+ ls_filter = NULL;
+
+ return;
+}
+
+/**
+ * \brief Gets a filter string for G__ls.
+ *
+ * Returns the filter pattern defined by G_set_ls_filter.
+ *
+ * \return Filter pattern
+ **/
+const char *G_get_ls_filter(void)
+{
+ return ls_filter;
+}
+
+/**
+ * \brief Stores a sorted directory listing in an array
+ *
+ * The filenames in the specified directory are stored in an array of
+ * strings, then sorted alphabetically. Each filename has space allocated
+ * using G_store(), which can be freed using G_free() if necessary. The
+ * same goes for the array itself.
+ *
+ *
+ * \param dir Directory to list
+ * \param num_files Pointer to an integer in which the total number of
+ * files listed will be stored
+ *
+ * \return Pointer to array of strings containing the listing
+ **/
+
+const char **G__ls(const char *dir, int *num_files)
+{
+ struct dirent *dp;
+ DIR *dfd;
+ const char **dir_listing = NULL;
+ int n = 0;
+ regex_t reg;
+
+ if ((dfd = opendir(dir)) == NULL)
+ G_fatal_error(_("Unable to open directory %s"), dir);
+
+ if (ls_filter && regcomp(®, ls_filter, LS_FILTER_FLAGS) != 0)
+ G_fatal_error(_("Unable to compile regular expression %s"),
+ ls_filter);
+
+ while ((dp = readdir(dfd)) != NULL) {
+ if (dp->d_name[0] != '.' && /* Don't list hidden files */
+ (ls_filter == NULL || regexec(®, dp->d_name, 0, NULL, 0) == 0)) {
+ dir_listing = (const char **)G_realloc(dir_listing,
+ (1 + n) * sizeof(char *));
+ dir_listing[n] = G_store(dp->d_name);
+ n++;
+ }
+ }
+
+ if (ls_filter)
+ regfree(®);
+
+ /* Sort list of filenames alphabetically */
+ qsort(dir_listing, n, sizeof(char *), cmp_names);
+
+ *num_files = n;
+ return dir_listing;
+}
Added: grass-addons/general/g.xremove/main.c
===================================================================
--- grass-addons/general/g.xremove/main.c (rev 0)
+++ grass-addons/general/g.xremove/main.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,128 @@
+
+/****************************************************************************
+ *
+ * MODULE: g.xremove
+ *
+ * AUTHOR(S): Huidae Cho <grass4u gmail.com>
+ *
+ * Based on general/manage/cmd/remove.c by
+ * CERL (original contributor)
+ * Radim Blazek <radim.blazek gmail.com>,
+ * Cedric Shock <cedricgrass shockfamily.net>,
+ * Huidae Cho <grass4u gmail.com>,
+ * Glynn Clements <glynn gclements.plus.com>,
+ * Jachym Cepicky <jachym les-ejk.cz>,
+ * Markus Neteler <neteler itc.it>,
+ * Martin Landa <landa.martin gmail.com>
+ *
+ * PURPOSE: lets users remove GRASS database files
+ *
+ * COPYRIGHT: (C) 1999-2008 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ *****************************************************************************/
+
+#define MAIN
+#include <stdlib.h>
+#include "global.h"
+
+int main(int argc, char *argv[])
+{
+ struct GModule *module;
+ struct Option **opt, *o;
+ struct
+ {
+ struct Flag *regex;
+ struct Flag *force;
+ struct Flag *basemap;
+ } flag;
+ char *name, *mapset, *location_path, path[GPATH_MAX];
+ const char **files;
+ int num_files, rast, result = EXIT_SUCCESS;
+ int i, j, n;
+
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+ module->keywords = _("general, map management");
+ module->description =
+ _("Removes data base element files from "
+ "the user's current mapset.");
+
+ flag.regex = G_define_flag();
+ flag.regex->key = 'r';
+ flag.regex->description =
+ _("Use extended regular expressions instead of wildcards");
+#define FREGEX flag.regex->answer
+
+ flag.force = G_define_flag();
+ flag.force->key = 'f';
+ flag.force->description =
+ _("Force removal (required for actual deletion of files)");
+#define FFORCE flag.force->answer
+
+ flag.basemap = G_define_flag();
+ flag.basemap->key = 'b';
+ flag.basemap->description = _("Remove base maps");
+#define FBASEMAP flag.basemap->answer
+
+ read_list(0);
+
+ opt = (struct Option **)G_calloc(nlist, sizeof(struct Option *));
+
+ for (n = 0; n < nlist; n++) {
+ o = opt[n] = G_define_option();
+ o->key = list[n].alias;
+ o->type = TYPE_STRING;
+ o->required = NO;
+ o->multiple = YES;
+ o->gisprompt = G_malloc(64);
+ sprintf(o->gisprompt, "old,%s,%s", list[n].mainelem,
+ list[n].maindesc);
+ o->description = G_malloc(64);
+ sprintf(o->description, _("%s file(s) to be removed"), list[n].alias);
+ }
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ location_path = G_location_path();
+ mapset = G_mapset();
+
+ for (n = 0; n < nlist; n++) {
+ if (opt[n]->answers) {
+ G__file_name(path, list[n].element[0], "", mapset);
+ if (access(path, 0) != 0)
+ continue;
+ rast = !G_strcasecmp(list[n].alias, "rast");
+ for (i = 0; (name = opt[n]->answers[i]); i++) {
+ if (!FREGEX)
+ name = wc2regex(name);
+ G_set_ls_filter(name);
+
+ files = G__ls(path, &num_files);
+
+ if (!FREGEX)
+ G_free(name);
+
+ for (j = 0; j < num_files; j++) {
+ if (!FFORCE) {
+ fprintf(stdout, "%s/%s@%s\n", list[n].alias, files[j],
+ mapset);
+ continue;
+ }
+ if (rast && check_reclass(files[j], mapset, FBASEMAP))
+ continue;
+
+ if (do_remove(n, (char *)files[j]) == 1)
+ result = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+
+ exit(result);
+}
Added: grass-addons/general/g.xremove/read_list.c
===================================================================
--- grass-addons/general/g.xremove/read_list.c (rev 0)
+++ grass-addons/general/g.xremove/read_list.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,148 @@
+/* Copied from general/manage */
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include "global.h"
+
+/*******************************************************************
+read the element list file
+
+ format is:
+
+ # ... comments
+ main element:alias:description:menu text
+ sub element:description
+ sub element:description
+ .
+ .
+ .
+******************************************************************/
+
+static int add_element(const char *, const char *);
+static int empty(const char *);
+static int format_error(const char *, int, const char *);
+
+int read_list(int check_if_empty)
+{
+ FILE *fd;
+ char element_list[600], buf[1024], elem[100], alias[100], desc[100],
+ text[100], *env;
+ int any, line;
+
+ nlist = 0;
+ list = 0;
+ any = 0;
+
+ if ((env = G__getenv("ELEMENT_LIST")))
+ G_strcpy(element_list, env);
+ else
+ sprintf(element_list, "%s/etc/element_list", G_gisbase());
+ fd = fopen(element_list, "r");
+
+ if (!fd)
+ G_fatal_error("can't open database element list <%s>", element_list);
+
+ line = 0;
+ while (G_getl(buf, sizeof(buf), fd)) {
+ line++;
+ if (*buf == '#')
+ continue;
+ if (*buf == ' ' || *buf == '\t') { /* support element */
+ *desc = 0;
+ if (sscanf(buf, "%[^:]:%[^\n]", elem, desc) < 1)
+ continue;
+ if (*elem == '#')
+ continue;
+ if (nlist == 0)
+ format_error(element_list, line, buf);
+
+ G_strip(elem);
+ G_strip(desc);
+ add_element(elem, desc);
+ }
+ else { /* main element */
+
+ if (sscanf
+ (buf, "%[^:]:%[^:]:%[^:]:%[^\n]", elem, alias, desc,
+ text) != 4)
+ format_error(element_list, line, buf);
+
+ G_strip(elem);
+ G_strip(alias);
+ G_strip(desc);
+ G_strip(text);
+
+ list =
+ (struct list *)G_realloc(list, (nlist + 1) * sizeof(*list));
+ list[nlist].mainelem = G_store(elem);
+ list[nlist].alias = G_store(alias);
+ list[nlist].maindesc = G_store(desc);
+ list[nlist].text = G_store(text);
+ list[nlist].nelem = 0;
+ list[nlist].element = 0;
+ list[nlist].desc = 0;
+ list[nlist].status = 0;
+ if (!check_if_empty || !empty(elem)) {
+ list[nlist].status = 1;
+ any = 1;
+ }
+ nlist++;
+ add_element(elem, desc);
+ }
+ }
+
+ fclose(fd);
+
+ return any;
+}
+
+static int add_element(const char *elem, const char *desc)
+{
+ int n;
+ int nelem;
+
+ if (*desc == 0)
+ desc = elem;
+
+ n = nlist - 1;
+ nelem = list[n].nelem++;
+ list[n].element =
+ (char **)G_realloc(list[n].element, (nelem + 1) * sizeof(char *));
+ list[n].element[nelem] = G_store(elem);
+ list[n].desc =
+ (char **)G_realloc(list[n].desc, (nelem + 1) * sizeof(char *));
+ list[n].desc[nelem] = G_store(desc);
+
+ return 0;
+}
+
+static int empty(const char *elem)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ char dir[1024];
+ int any;
+
+ G__file_name(dir, elem, "", G_mapset());
+
+ any = 0;
+ if ((dirp = opendir(dir)) != NULL) {
+ while (!any && (dp = readdir(dirp)) != NULL) {
+ if (dp->d_name[0] != '.')
+ any = 1;
+ }
+ closedir(dirp);
+ }
+
+ return any == 0;
+}
+
+static int format_error(const char *element_list, int line, const char *buf)
+{
+ G_fatal_error(_("Format error: <%s>\nLine: %d\n%s"), element_list, line,
+ buf);
+
+ return 1;
+}
Added: grass-addons/general/g.xremove/sighold.c
===================================================================
--- grass-addons/general/g.xremove/sighold.c (rev 0)
+++ grass-addons/general/g.xremove/sighold.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,21 @@
+#include <signal.h>
+
+void (*sig) ();
+
+int hold_signals(int hold)
+{
+
+ sig = hold ? SIG_IGN : SIG_DFL;
+
+ signal(SIGINT, sig);
+
+#ifndef __MINGW32__
+ signal(SIGQUIT, sig);
+#endif
+
+#ifdef SIGTSTP
+ signal(SIGTSTP, sig);
+#endif
+
+ return 0;
+}
Added: grass-addons/general/g.xremove/wc2regex.c
===================================================================
--- grass-addons/general/g.xremove/wc2regex.c (rev 0)
+++ grass-addons/general/g.xremove/wc2regex.c 2008-06-29 11:44:57 UTC (rev 31881)
@@ -0,0 +1,46 @@
+#include <grass/gis.h>
+
+char *wc2regex(const char *wc)
+{
+ int i, j;
+ char *regex;
+
+ for (i = 0, j = 2; wc[i]; i++, j++) {
+ switch (wc[i]) {
+ case '.':
+ case '*':
+ j++;
+ break;
+ }
+ }
+ regex = (char *)G_malloc(j + 1);
+ j = 0;
+ regex[j++] = '^';
+ for (i = 0; wc[i]; i++) {
+ switch (wc[i]) {
+ case '.':
+ regex[j++] = '\\';
+ break;
+ case '*':
+ regex[j++] = '.';
+ break;
+ case '?':
+ regex[j++] = '.';
+ continue;
+ case '{':
+ regex[j++] = '(';
+ continue;
+ case '}':
+ regex[j++] = ')';
+ continue;
+ case ',':
+ regex[j++] = '|';
+ continue;
+ }
+ regex[j++] = wc[i];
+ }
+ regex[j++] = '$';
+ regex[j] = 0;
+
+ return regex;
+}
More information about the grass-commit
mailing list