list.c

Go to the documentation of this file.
00001 /*
00002  * $Id: list.c,v 2.15.4.2 2006/10/19 15:23:28 markus Exp $
00003  *
00004  ****************************************************************************
00005  *
00006  * MODULE:       GRASS 5 gis library, list.c
00007  * AUTHOR(S):    unknown
00008  * PURPOSE:      list elements
00009  * COPYRIGHT:    (C) 2000 by the GRASS Development Team
00010  *
00011  *               This program is free software under the GNU General Public
00012  *               License (>=v2). Read the file COPYING that comes with GRASS
00013  *               for details.
00014  *
00015  *****************************************************************************/
00016 
00017 /**********************************************************************
00018  *  G_list_element (element, desc, mapset, lister)
00019  *
00020  *      char *element    database element (eg, "cell", "cellhd", etc)
00021  *      char *desc       desc for element (if NULL, element is used)
00022  *      char *mapset     mapset to be listed.
00023  *                       "" to list all mapsets in mapset search list
00024  *                       "." will list current mapset
00025  *
00026  *      int (*lister)()  if given will call this routine to get a list
00027  *                       title. NULL if no titles desired.
00028  *
00029  *                       lister (name, mapset, buf)
00030  *                       char *name, *mapset, *buf
00031  *
00032  *                       given file 'name', and 'mapset',
00033  *                       lister() should copy a string into 'buf'
00034  *
00035  *                       when called with name == "", should set buf
00036  *                       to general title for mapset list.
00037  *
00038  *   General purpose list function. Will list files from all mapsets
00039  *   in the mapset list for a specified database element.
00040  *
00041  *   note:
00042  *      output is to stdout piped thru the more utility
00043  *********************************************************************/
00044 
00045 #include <stdlib.h>
00046 #include <unistd.h>
00047 #include <signal.h>
00048 #include <string.h>
00049 #include <sys/types.h>
00050 #include <dirent.h>
00051 #include <grass/gis.h>
00052 #include <grass/glocale.h>
00053 
00054 static int broken_pipe;
00055 static int hit_return = 0;
00056 static int list_element(FILE *,char *,char *,char *,int (*)());
00057 static void sigpipe_catch(int);
00058 static int pstrcmp(const void *, const void *);
00059 
00060 int G_set_list_hit_return(int flag)
00061 {
00062     hit_return = flag;
00063     return 0;
00064 }
00065 
00066 int G_list_element (
00067     char *element,
00068     char *desc,
00069     char *mapset,
00070     int (*lister)())
00071 {
00072     int n;
00073     FILE *more;
00074     int count;
00075 #ifdef SIGPIPE
00076     void (*sigpipe)();
00077 #endif
00078 
00079 /* must catch broken pipe in case "more" quits */
00080     broken_pipe = 0;
00081 #ifdef SIGPIPE
00082     sigpipe = signal (SIGPIPE, sigpipe_catch);
00083 #endif
00084 
00085     count = 0;
00086     if (desc == 0 || *desc == 0)
00087         desc = element;
00088 /*
00089  * G_popen() the more command to page the output
00090  */
00091     if (isatty(1))
00092     {
00093         more = G_popen ("$GRASS_PAGER","w");
00094         if (!more) more = stdout;
00095     }
00096     else
00097         more = stdout;
00098     fprintf (more,"----------------------------------------------\n");
00099 
00100 /*
00101  * if no specific mapset is requested, list the mapsets
00102  * from the mapset search list
00103  * otherwise just list the specified mapset
00104  */
00105     if (mapset == 0 || *mapset == 0)
00106         for (n = 0; !broken_pipe && (mapset = G__mapset_name (n)); n++)
00107             count += list_element (more, element, desc, mapset, lister);
00108     else
00109         count += list_element (more, element, desc, mapset, lister);
00110 
00111     if (!broken_pipe)
00112     {
00113         if (count == 0){
00114            if (mapset == 0 || *mapset == 0)
00115             fprintf (more,_("no %s files available in current mapset\n"), desc);
00116            else
00117             fprintf (more,_("no %s files available in mapset %s\n"), desc, mapset);
00118         }
00119 
00120         fprintf (more,"----------------------------------------------\n");
00121     }
00122 /*
00123  * close the more
00124  */
00125     if (more != stdout) G_pclose (more);
00126 #ifdef SIGPIPE
00127     signal (SIGPIPE, sigpipe);
00128 #endif
00129 if (hit_return && isatty(1))
00130     {
00131         fprintf (stderr, _("hit RETURN to continue -->"));
00132         while (getchar() != '\n')
00133             ;
00134     }
00135 
00136     return 0;
00137 }
00138 
00139 static void sigpipe_catch(int n)
00140 {
00141     broken_pipe = 1;
00142     signal (n,sigpipe_catch);
00143 }
00144 
00145 static int list_element( FILE *out, char *element,
00146     char *desc, char *mapset, int (*lister)())
00147 {
00148     char path[1000];
00149     DIR *dirp;
00150     struct dirent *dp;
00151     int count = 0, maxlen = 0, num_cols = 1;
00152     char **list;
00153     int i;
00154 
00155 /*
00156  * convert . to current mapset
00157  */
00158     if (strcmp (mapset,".") == 0)
00159         mapset = G_mapset();
00160 
00161 
00162 /*
00163  * get the full name of the GIS directory within the mapset
00164  * and list its contents (if it exists)
00165  *
00166  * if lister() routine is given, the ls command must give 1 name
00167  */
00168     G__file_name (path, element, "", mapset);
00169     if (access(path, 0) != 0)
00170     {
00171         fprintf(out,"\n");
00172         return count;
00173     }
00174 
00175 /*
00176  * if a title so that we can call lister() with the names
00177  * otherwise the ls must be forced into columnar form.
00178  */
00179 
00180     if ((dirp = opendir(path)) == NULL)
00181         G_fatal_error("ERROR: %s: open failed.", path);
00182 
00183     if (!lister)
00184     {
00185         while((dp = readdir(dirp)) != NULL)
00186         {
00187                 if (dp->d_name[0] == '.')
00188                         continue;
00189                 if (maxlen < (i = strlen(dp->d_name)))
00190                         maxlen = i;
00191         }
00192         rewinddir(dirp);
00193 
00194         num_cols = 80 / (maxlen + 1); /* + 1: column separator */
00195     }
00196 
00197     if (num_cols < 1)
00198         num_cols = 1;
00199 
00200     list = NULL;
00201     while ((dp = readdir(dirp)) != NULL)
00202     {
00203         if (dp->d_name[0] == '.')
00204             continue;
00205 
00206         if ((list=(char **)G_realloc(list, (count+1)*sizeof(char *))) == NULL ||
00207            (list[count] = (char *)G_malloc(strlen(dp->d_name)+1)) == NULL)
00208             G_fatal_error("ERROR: memory allocation error!");
00209         strcpy(list[count++], dp->d_name);
00210     }
00211     closedir(dirp);
00212 
00213     if (count > 0)
00214     {
00215         fprintf(out, _("%s files available in mapset %s:\n"), desc, mapset);
00216         if (lister)
00217         {
00218             char title[400];
00219             char name[GNAME_MAX];
00220 
00221             *name = *title = 0;
00222             lister (name, mapset, title);
00223             if (*title)
00224                 fprintf(out,"\n%-18s %-.60s\n",name,title);
00225         }
00226     }
00227 
00228     qsort(list, (size_t)count, sizeof(char *), pstrcmp);
00229 
00230     for(i = 0; i < count; i++)
00231     {
00232         if (lister)
00233         {
00234             char title[400];
00235             char *b;
00236     
00237             /* remove the trailing newline */
00238             for (b = list[i]; *b; b++)
00239                 if (*b == '\n')
00240                     *b = 0;
00241     
00242             lister (list[i], mapset, title);
00243             fprintf(out,"%-18s %-.60s\n",list[i],title);
00244         }
00245         else
00246         {
00247             if ((i+1) % num_cols)
00248                 fprintf(out,"%-*s", maxlen+1, list[i]);
00249             else
00250                 fprintf(out,"%s", list[i]);
00251         }
00252 
00253         if (!lister && !((i+1) % num_cols))
00254             fprintf(out, "\n");
00255 
00256         G_free(list[i]);
00257     }
00258 
00259     if (!lister && (count % num_cols))
00260         fprintf(out,"\n");
00261 
00262     fprintf(out, "\n");
00263 
00264     if (list)
00265         G_free(list);
00266 
00267     return count;
00268 }
00269 
00270 static int pstrcmp(const void *s1, const void *s2)
00271 {
00272     return strcmp(*(char **)s1, *(char **)s2);
00273 }
00274 
00285 char **G_list(int element, const char *gisbase, const char *location, const char* mapset)
00286 {
00287     char *el;
00288     char *buf;
00289     DIR *dirp;
00290     struct dirent *dp;
00291     int count;
00292     char **list;
00293     
00294     switch ( element )
00295     {
00296         case G_ELEMENT_RASTER:
00297             el = "cell";
00298             break;
00299 
00300         case G_ELEMENT_GROUP:
00301             el = "group";
00302             break;
00303 
00304         case G_ELEMENT_VECTOR:
00305             el = "vector";
00306             break;
00307 
00308         case G_ELEMENT_REGION:
00309             el = "window";
00310             break;
00311 
00312         default:
00313             G_fatal_error ("G_list: Unknown element type." );
00314     }                   
00315         
00316     buf = (char *) G_malloc ( strlen(gisbase) + strlen(location)
00317                               + strlen(mapset) + strlen(el) + 4 );
00318 
00319     sprintf ( buf, "%s/%s/%s/%s", gisbase, location, mapset, el );
00320 
00321     dirp = opendir(buf);
00322     G_free ( buf );             
00323 
00324     if ( dirp == NULL ) /* this can happen if element does not exist */
00325     {
00326         list = (char **) G_calloc ( 1, sizeof(char *) );
00327         return list;
00328     }
00329 
00330     count = 0;
00331     while((dp = readdir(dirp)) != NULL)
00332     {
00333         if (dp->d_name[0] == '.') continue;
00334         count++;
00335     }
00336     rewinddir(dirp);
00337 
00338     list = (char **) G_calloc ( count+1, sizeof(char *) );
00339     
00340     count = 0;
00341     while ((dp = readdir(dirp)) != NULL)
00342     {
00343         if (dp->d_name[0] == '.') continue;
00344 
00345         list[count] = (char *) G_malloc( strlen(dp->d_name)+1 );
00346         strcpy ( list[count], dp->d_name );
00347         count++;
00348     }
00349     closedir(dirp);
00350 
00351     return list;
00352 }
00353 
00354 void G_free_list(char **list)
00355 {
00356     int i = 0;
00357 
00358     if ( !list ) return;
00359    
00360     while ( list[i] )
00361     {
00362         G_free (list[i]);
00363         i++;
00364     }
00365     G_free (list);
00366 }

Generated on Fri Nov 21 11:02:18 2008 for GRASS by  doxygen 1.5.1