static GList *list_add_file(GList *list, const char *name, const char *default_path) { struct stat statbuf; char *fname; g_return_val_if_fail(name != NULL, NULL); fname = convert_home(name); if (USE_DEFAULT_PATH(fname, default_path)) { g_free(fname); fname = g_strconcat(default_path, G_DIR_SEPARATOR_S, name, NULL); } if (stat(fname, &statbuf) == 0) { list = g_list_append(list, !S_ISDIR(statbuf.st_mode) ? g_strdup(name) : g_strconcat(name, G_DIR_SEPARATOR_S, NULL)); } g_free(fname); return list; }
GList *filename_complete(const char *path, const char *default_path) { GList *list; DIR *dirp; struct dirent *dp; char *basename; char *realpath, *dir, *name; size_t len; g_return_val_if_fail(path != NULL, NULL); if (path[0] == '\0') { return NULL; } list = NULL; /* get directory part of the path - expand ~/ */ realpath = convert_home(path); if (USE_DEFAULT_PATH(realpath, default_path)) { g_free(realpath); realpath = g_strconcat(default_path, G_DIR_SEPARATOR_S, path, NULL); } /* open directory for reading */ dir = g_path_get_dirname(realpath); dirp = opendir(dir); g_free(dir); g_free(realpath); if (dirp == NULL) return NULL; dir = g_path_get_dirname(path); if (*dir == G_DIR_SEPARATOR && dir[1] == '\0') { /* completing file in root directory */ *dir = '\0'; } else if (IS_CURRENT_DIR(dir) && !IS_CURRENT_DIR(path)) { /* completing file in default_path (path not set, and leave it that way) */ g_free_and_null(dir); } len = strlen(path); /* g_path_get_basename() returns the component before the last slash if * the path ends with a directory separator, that's not what we want */ if (len > 0 && path[len - 1] == G_DIR_SEPARATOR) { basename = g_strdup(""); } else { basename = g_path_get_basename(path); } len = strlen(basename); /* add all files in directory to completion list */ while ((dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.') { if (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0')) continue; /* skip . and .. */ /* Skip the dotfiles unless the user explicitly asked us * to do so. Basename might be './', beware of that */ if (basename[0] != '.' || basename[1] == '\0') continue; } if (len == 0 || strncmp(dp->d_name, basename, len) == 0) { name = dir == NULL ? g_strdup(dp->d_name) : g_strdup_printf("%s"G_DIR_SEPARATOR_S"%s", dir, dp->d_name); list = list_add_file(list, name, default_path); g_free(name); } } closedir(dirp); g_free(basename); g_free_not_null(dir); return list; }
GList *filename_complete(const char *path, const char *default_path) { GList *list; DIR *dirp; struct dirent *dp; const char *basename; char *realpath, *dir, *name; int len; g_return_val_if_fail(path != NULL, NULL); list = NULL; /* get directory part of the path - expand ~/ */ realpath = convert_home(path); if (USE_DEFAULT_PATH(realpath, default_path)) { g_free(realpath); realpath = g_strconcat(default_path, G_DIR_SEPARATOR_S, path, NULL); } /* open directory for reading */ dir = g_dirname(realpath); dirp = opendir(dir); g_free(dir); g_free(realpath); if (dirp == NULL) return NULL; dir = g_dirname(path); if (*dir == G_DIR_SEPARATOR && dir[1] == '\0') { /* completing file in root directory */ *dir = '\0'; } else if (IS_CURRENT_DIR(dir) && !IS_CURRENT_DIR(path)) { /* completing file in default_path (path not set, and leave it that way) */ g_free_and_null(dir); } basename = g_basename(path); len = strlen(basename); /* add all files in directory to completion list */ while ((dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.') { if (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' && dp->d_name[2] == '\0')) continue; /* skip . and .. */ if (basename[0] != '.') continue; } if (len == 0 || strncmp(dp->d_name, basename, len) == 0) { name = dir == NULL ? g_strdup(dp->d_name) : g_strdup_printf("%s"G_DIR_SEPARATOR_S"%s", dir, dp->d_name); list = list_add_file(list, name, default_path); g_free(name); } } closedir(dirp); g_free_not_null(dir); return list; }