[GRASS-SVN] r31886 - in grass-addons/general: g.xlist g.xremove

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jun 29 17:58:52 EDT 2008


Author: hcho
Date: 2008-06-29 17:58:52 -0400 (Sun, 29 Jun 2008)
New Revision: 31886

Modified:
   grass-addons/general/g.xlist/gisdefs.h
   grass-addons/general/g.xlist/ls.c
   grass-addons/general/g.xlist/main.c
   grass-addons/general/g.xremove/gisdefs.h
   grass-addons/general/g.xremove/ls.c
   grass-addons/general/g.xremove/main.c
Log:
G__ls filter changed to a callback function

Modified: grass-addons/general/g.xlist/gisdefs.h
===================================================================
--- grass-addons/general/g.xlist/gisdefs.h	2008-06-29 16:30:55 UTC (rev 31885)
+++ grass-addons/general/g.xlist/gisdefs.h	2008-06-29 21:58:52 UTC (rev 31886)
@@ -9,8 +9,7 @@
 			   const char *, int, int *);
 
 /* ls.c */
-void G_set_ls_filter(const char *);
-const char *G_get_ls_filter(void);
+void G_set_ls_filter(int (*)(const char *, void *), void *);
 const char **G__ls(const char *, int *);
 
 #endif

Modified: grass-addons/general/g.xlist/ls.c
===================================================================
--- grass-addons/general/g.xlist/ls.c	2008-06-29 16:30:55 UTC (rev 31885)
+++ grass-addons/general/g.xlist/ls.c	2008-06-29 21:58:52 UTC (rev 31886)
@@ -19,7 +19,6 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <unistd.h>
-#include <regex.h>
 
 #include <grass/gis.h>
 #include <grass/config.h>
@@ -29,10 +28,10 @@
 #  include <sys/ioctl.h>
 #endif
 
+typedef int ls_filter_func(const char * /*filename */ , void * /*closure */ );
+static ls_filter_func *ls_filter = NULL;
+static void *ls_closure = NULL;
 
-#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;
@@ -42,46 +41,26 @@
 }
 
 /**
- * \brief Sets a filter for G__ls using POSIX Extended Regular Expressions.
+ * \brief Sets a function and its complementary data for G__ls filtering.
  * 
- * Defines the pattern that allows G__ls to filter out unwanted file names.
- * Call this function before G__ls.
+ * Defines a filter function and its rule data that allow 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)
+ * \param func      Filter callback function to compare a file name and closure
+ * 		    pattern (if NULL, no filter will be used).
+ * 		    func(filename, closure) should return 1 on success, 0 on
+ * 		    failure.
+ * \param closure   Data used to determine if a file name matches the rule.
  **/
-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(&reg, ls_filter, LS_FILTER_FLAGS) != 0)
-	    G_fatal_error(_("Unable to compile regular expression %s"),
-			  ls_filter);
-	regfree(&reg);
-    }
-    else
-	ls_filter = NULL;
-
+void G_set_ls_filter(ls_filter_func * func, void *closure)
+{
+    ls_filter = func;
+    ls_closure = closure;
     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
@@ -103,28 +82,22 @@
     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(&reg, 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(&reg, 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 ((dp->d_name[0] == '.' && dp->d_name[1] == 0) ||
+	    (dp->d_name[0] == '.' && dp->d_name[1] == '.' &&
+	     dp->d_name[2] == 0) || (ls_filter &&
+				     !(*ls_filter) (dp->d_name, ls_closure)))
+	    continue;
+	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(&reg);
-
     /* Sort list of filenames alphabetically */
     qsort(dir_listing, n, sizeof(char *), cmp_names);
 

Modified: grass-addons/general/g.xlist/main.c
===================================================================
--- grass-addons/general/g.xlist/main.c	2008-06-29 16:30:55 UTC (rev 31885)
+++ grass-addons/general/g.xlist/main.c	2008-06-29 21:58:52 UTC (rev 31886)
@@ -20,12 +20,14 @@
 #define MAIN
 #include <stdlib.h>
 #include <string.h>
+#include <regex.h>
 #include <grass/spawn.h>
 #include "gisdefs.h"
 #include "global.h"
 
+static int do_list(int, const char *, const char *, int, const char *, int);
 static int parse(const char *);
-static int do_list(int, const char *, const char *, int, const char *, int);
+static int ls_filter(const char *, void *);
 
 int main(int argc, char *argv[])
 {
@@ -47,6 +49,7 @@
     } flag;
     int i, n, all, num_types, any, flags = 0;
     char **types, *pattern = NULL, separator[2];
+    regex_t regex;
 
     G_gisinit(argv[0]);
 
@@ -76,7 +79,6 @@
 	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";
@@ -85,7 +87,6 @@
     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";
@@ -95,7 +96,6 @@
     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";
@@ -104,69 +104,61 @@
     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;
-    }
+    if (flag.regex->answer)
+	pattern = opt.pattern->answer;
+    else
+	pattern = wc2regex(opt.pattern->answer);
 
-    G_set_ls_filter(PATTERN);
-#if 0
-    fprintf(stderr, "%s\n", G_get_ls_filter());
-#endif
+    if (regcomp(&regex, pattern, REG_EXTENDED | REG_NOSUB))
+	G_fatal_error(_("Unable to compile regular expression %s"), pattern);
+    G_set_ls_filter(ls_filter, &regex);
 
-    if (strcmp(SEPARATOR, "newline") == 0)
+    if (strcmp(opt.separator->answer, "newline") == 0)
 	separator[0] = '\n';
-    else if (strcmp(SEPARATOR, "space") == 0)
+    else if (strcmp(opt.separator->answer, "space") == 0)
 	separator[0] = ' ';
-    else if (strcmp(SEPARATOR, "tab") == 0)
+    else if (strcmp(opt.separator->answer, "tab") == 0)
 	separator[0] = '\t';
     else
-	separator[0] = SEPARATOR[0];
+	separator[0] = opt.separator->answer[0];
     separator[1] = 0;
 
-    if (MAPSET == NULL)
-	MAPSET = "";
+    if (opt.mapset->answer == NULL)
+	opt.mapset->answer = "";
 
-    if (G_strcasecmp(MAPSET, ".") == 0)
-	MAPSET = G_mapset();
+    if (G_strcasecmp(opt.mapset->answer, ".") == 0)
+	opt.mapset->answer = G_mapset();
 
-    for (i = 0; TYPES[i]; i++) {
-	if (strcmp(TYPES[i], "all") == 0)
+    for (i = 0; opt.type->answers[i]; i++) {
+	if (strcmp(opt.type->answers[i], "all") == 0)
 	    break;
     }
-    if (TYPES[i]) {
+    if (opt.type->answers[i]) {
 	all = 1;
 	num_types = nlist;
     }
@@ -175,49 +167,43 @@
 	num_types = i;
     }
 
-    if (FTYPE)
+    if (flag.type->answer)
 	flags |= G_JOIN_ELEMENT_TYPE;
-    if (FMAPSET)
+    if (flag.mapset->answer)
 	flags |= G_JOIN_ELEMENT_MAPSET;
 
     for (i = 0; i < num_types; i++) {
-	n = all ? i : parse(TYPES[i]);
+	n = all ? i : parse(opt.type->answers[i]);
 
-	if (FFULL) {
+	if (flag.full->answer) {
 	    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);
+		G_spawn(lister, lister, opt.mapset->answer, NULL);
 	    else
-		any = do_list(n, PATTERN, MAPSET, FPRETTY, separator, flags);
+		any =
+		    do_list(n, pattern, opt.mapset->answer,
+			    flag.pretty->answer, separator, flags);
 	}
 	else
-	    any = do_list(n, PATTERN, MAPSET, FPRETTY, separator, flags);
+	    any =
+		do_list(n, pattern, opt.mapset->answer, flag.pretty->answer,
+			separator, flags);
     }
-    if (!FPRETTY && any)
+    if (!flag.pretty->answer && any)
 	fprintf(stdout, "\n");
 
-    if (pattern)
+    if (!flag.regex->answer)
 	G_free(pattern);
 
+    regfree(&regex);
+
     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)
 {
@@ -245,3 +231,21 @@
 
     return any;
 }
+
+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 ls_filter(const char *filename, void *closure)
+{
+    return filename[0] != '.' &&
+	regexec((regex_t *) closure, filename, 0, NULL, 0) == 0;
+}

Modified: grass-addons/general/g.xremove/gisdefs.h
===================================================================
--- grass-addons/general/g.xremove/gisdefs.h	2008-06-29 16:30:55 UTC (rev 31885)
+++ grass-addons/general/g.xremove/gisdefs.h	2008-06-29 21:58:52 UTC (rev 31886)
@@ -9,8 +9,7 @@
 			   const char *, int, int *);
 
 /* ls.c */
-void G_set_ls_filter(const char *);
-const char *G_get_ls_filter(void);
+void G_set_ls_filter(int (*)(const char *, void *), void *);
 const char **G__ls(const char *, int *);
 
 #endif

Modified: grass-addons/general/g.xremove/ls.c
===================================================================
--- grass-addons/general/g.xremove/ls.c	2008-06-29 16:30:55 UTC (rev 31885)
+++ grass-addons/general/g.xremove/ls.c	2008-06-29 21:58:52 UTC (rev 31886)
@@ -19,7 +19,6 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <unistd.h>
-#include <regex.h>
 
 #include <grass/gis.h>
 #include <grass/config.h>
@@ -29,10 +28,10 @@
 #  include <sys/ioctl.h>
 #endif
 
+typedef int ls_filter_func(const char * /*filename */ , void * /*closure */ );
+static ls_filter_func *ls_filter = NULL;
+static void *ls_closure = NULL;
 
-#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;
@@ -42,46 +41,26 @@
 }
 
 /**
- * \brief Sets a filter for G__ls using POSIX Extended Regular Expressions.
+ * \brief Sets a function and its complementary data for G__ls filtering.
  * 
- * Defines the pattern that allows G__ls to filter out unwanted file names.
- * Call this function before G__ls.
+ * Defines a filter function and its rule data that allow 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)
+ * \param func      Filter callback function to compare a file name and closure
+ * 		    pattern (if NULL, no filter will be used).
+ * 		    func(filename, closure) should return 1 on success, 0 on
+ * 		    failure.
+ * \param closure   Data used to determine if a file name matches the rule.
  **/
-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(&reg, ls_filter, LS_FILTER_FLAGS) != 0)
-	    G_fatal_error(_("Unable to compile regular expression %s"),
-			  ls_filter);
-	regfree(&reg);
-    }
-    else
-	ls_filter = NULL;
-
+void G_set_ls_filter(ls_filter_func * func, void *closure)
+{
+    ls_filter = func;
+    ls_closure = closure;
     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
@@ -103,28 +82,22 @@
     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(&reg, 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(&reg, 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 ((dp->d_name[0] == '.' && dp->d_name[1] == 0) ||
+	    (dp->d_name[0] == '.' && dp->d_name[1] == '.' &&
+	     dp->d_name[2] == 0) || (ls_filter &&
+				     !(*ls_filter) (dp->d_name, ls_closure)))
+	    continue;
+	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(&reg);
-
     /* Sort list of filenames alphabetically */
     qsort(dir_listing, n, sizeof(char *), cmp_names);
 

Modified: grass-addons/general/g.xremove/main.c
===================================================================
--- grass-addons/general/g.xremove/main.c	2008-06-29 16:30:55 UTC (rev 31885)
+++ grass-addons/general/g.xremove/main.c	2008-06-29 21:58:52 UTC (rev 31886)
@@ -27,8 +27,11 @@
 
 #define MAIN
 #include <stdlib.h>
+#include <regex.h>
 #include "global.h"
 
+static int ls_filter(const char *, void *);
+
 int main(int argc, char *argv[])
 {
     struct GModule *module;
@@ -43,6 +46,7 @@
     const char **files;
     int num_files, rast, result = EXIT_SUCCESS;
     int i, j, n;
+    regex_t regex;
 
     G_gisinit(argv[0]);
 
@@ -56,18 +60,15 @@
     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);
 
@@ -99,22 +100,27 @@
 		continue;
 	    rast = !G_strcasecmp(list[n].alias, "rast");
 	    for (i = 0; (name = opt[n]->answers[i]); i++) {
-		if (!FREGEX)
+		if (!flag.regex->answer)
 		    name = wc2regex(name);
-		G_set_ls_filter(name);
+		if (regcomp(&regex, name, REG_EXTENDED | REG_NOSUB))
+		    G_fatal_error(_
+				  ("Unable to compile regular expression %s"),
+				  name);
+		if (!flag.regex->answer)
+		    G_free(name);
 
+		G_set_ls_filter(ls_filter, &regex);
 		files = G__ls(path, &num_files);
+		regfree(&regex);
 
-		if (!FREGEX)
-		    G_free(name);
-
 		for (j = 0; j < num_files; j++) {
-		    if (!FFORCE) {
+		    if (!flag.force->answer) {
 			fprintf(stdout, "%s/%s@%s\n", list[n].alias, files[j],
 				mapset);
 			continue;
 		    }
-		    if (rast && check_reclass(files[j], mapset, FBASEMAP))
+		    if (rast &&
+			check_reclass(files[j], mapset, flag.basemap->answer))
 			continue;
 
 		    if (do_remove(n, (char *)files[j]) == 1)
@@ -126,3 +132,9 @@
 
     exit(result);
 }
+
+static int ls_filter(const char *filename, void *closure)
+{
+    return filename[0] != '.' &&
+	regexec((regex_t *) closure, filename, 0, NULL, 0) == 0;
+}



More information about the grass-commit mailing list