Browse Source

Use dirent.h instead of fts.h for launcher completion because of compatibility

Martin Duquesnoy 12 years ago
parent
commit
235935f36f
1 changed files with 48 additions and 55 deletions
  1. 48 55
      src/launcher.c

+ 48 - 55
src/launcher.c

@@ -4,7 +4,7 @@
  */
 
 #include <string.h>
-#include <fts.h>
+#include <dirent.h>
 #include <sys/stat.h>
 #include <X11/Xutil.h>
 
@@ -15,18 +15,18 @@
 #include "config.h"
 
 static int
-fts_alphasort(const FTSENT **a, const FTSENT **b)
+qsort_string_compare(const void * a, const void * b)
 {
-     return (strcmp((*a)->fts_name, (*b)->fts_name));
+     return (strcmp(*(char **)a, *(char **)b));
 }
 
 static char **
 complete_on_command(char *start)
 {
+     struct dirent *content;
+     DIR *dir;
      char **paths, *path, *p, **namelist = NULL;
-     int count;
-     FTS *tree;
-     FTSENT *node;
+     int i, count;
 
      if(!(path = getenv("PATH")) || !start)
           return NULL;
@@ -46,40 +46,31 @@ complete_on_command(char *start)
 
      paths[count] = NULL;
 
-     if(!(tree = fts_open(paths, FTS_NOCHDIR, fts_alphasort)))
+     /* recursively open PATH */
+     for(i = count = 0; paths[i]; ++i)
      {
-          warnl("fts_open");
-          free(paths);
-          free(path);
-          return NULL;
-     }
+          if(!(dir = opendir(paths[i])))
+               continue;
 
-     count = 0;
-     while((node = fts_read(tree)))
-     {
-          if(node->fts_level > 0)
-               fts_set(tree, node, FTS_SKIP);
-
-          if(node->fts_level
-             && (node->fts_info & FTS_F)
-             && (node->fts_info & FTS_NS)
-             && (node->fts_statp->st_mode & S_IXOTH)
-             && !strncmp(node->fts_name, start, strlen(start)))
+          while((content = readdir(dir)))
           {
-               namelist = xrealloc(namelist, ++count, sizeof(*namelist));
-               namelist[count - 1] = xstrdup(node->fts_name + strlen(start));
+               if(strncmp(content->d_name, ".", 1)
+                  && !strncmp(content->d_name, start, strlen(start)))
+               {
+                    namelist = xrealloc(namelist, ++count, sizeof(*namelist));
+                    namelist[count - 1] = xstrdup(content->d_name + strlen(start));
+               }
           }
+          closedir(dir);
      }
 
      if(count)
      {
+          qsort(namelist, count, sizeof(char *), qsort_string_compare);
           namelist = xrealloc(namelist, ++count, sizeof(*namelist));
           namelist[count - 1] = NULL;
      }
 
-     if(fts_close(tree))
-          warnl("fts_close");
-
      free(paths);
      free(path);
 
@@ -93,12 +84,12 @@ complete_on_command(char *start)
 static char **
 complete_on_files(char *start)
 {
-     char *p, *home, *path, *dirname = NULL, *paths[2], **namelist = NULL;
-     int count;
-     FTS *tree;
-     FTSENT *node;
-
-     p = start;
+     struct dirent *content = NULL;
+     struct stat st;
+     DIR *dir;
+     char *home, *path, *dirname = NULL;
+     char **namelist = NULL, *filepath, *p = start;
+     int count = 0;
 
      /*
       * Search the directory to open and set
@@ -135,28 +126,33 @@ complete_on_files(char *start)
           }
      }
 
-     paths[0] = path;
-     paths[1] = NULL;
-
-     if(!(tree = fts_open(paths, FTS_NOCHDIR, fts_alphasort)))
+     if((dir = opendir(path)))
      {
-          warnl("fts_open");
-          free(dirname);
-          free(path);
-          return NULL;
-     }
+          while((content = readdir(dir)))
+          {
+               if(!strcmp(content->d_name, ".")
+                  || !strcmp(content->d_name, "..")
+                  || strncmp(content->d_name, p, strlen(p)))
+                    continue;
 
-     count = 0;
-     while((node = fts_read(tree)))
-     {
-          if(node->fts_level > 0)
-               fts_set(tree, node, FTS_SKIP);
+               /* If it's a directory append '/' to the completion */
+               xasprintf(&filepath, "%s/%s", path, content->d_name);
 
-          if(node->fts_level && !strncmp(node->fts_name, p, strlen(p)))
-          {
-               namelist = xrealloc(namelist, ++count, sizeof(*namelist));
-               namelist[count - 1] = xstrdup(node->fts_name + strlen(p));
+               if(filepath && stat(filepath, &st) != -1)
+               {
+                    namelist = xrealloc(namelist, ++count, sizeof(*namelist));
+
+                    if(S_ISDIR(st.st_mode))
+                         xasprintf(&namelist[count - 1], "%s/", content->d_name + strlen(p));
+                    else
+                         namelist[count - 1] = xstrdup(content->d_name + strlen(p));
+               }
+               else
+                    warnl("%s", filepath);
+
+               free(filepath);
           }
+          closedir(dir);
      }
 
      if(count)
@@ -165,9 +161,6 @@ complete_on_files(char *start)
           namelist[count - 1] = NULL;
      }
 
-     if(fts_close(tree))
-          warnl("fts_close");
-
      free(dirname);
      free(path);