* return first found file name starting by the ``text'' or NULL if no * such file can be found * value of ``state'' is ignored * * it's the caller's responsibility to free the returned string */
| 142 | * it's the caller's responsibility to free the returned string |
| 143 | */ |
| 144 | char * |
| 145 | fn_filename_completion_function(const char *text, int state) |
| 146 | { |
| 147 | static DIR *dir = NULL; |
| 148 | static char *filename = NULL, *dirname = NULL, *dirpath = NULL; |
| 149 | static size_t filename_len = 0; |
| 150 | struct dirent *entry; |
| 151 | char *temp; |
| 152 | size_t len; |
| 153 | |
| 154 | if (state == 0 || dir == NULL) { |
| 155 | temp = strrchr(text, '/'); |
| 156 | if (temp) { |
| 157 | char *nptr; |
| 158 | temp++; |
| 159 | nptr = el_realloc(filename, (strlen(temp) + 1) * |
| 160 | sizeof(*nptr)); |
| 161 | if (nptr == NULL) { |
| 162 | el_free(filename); |
| 163 | filename = NULL; |
| 164 | return NULL; |
| 165 | } |
| 166 | filename = nptr; |
| 167 | (void)strcpy(filename, temp); |
| 168 | len = (size_t)(temp - text); /* including last slash */ |
| 169 | |
| 170 | nptr = el_realloc(dirname, (len + 1) * |
| 171 | sizeof(*nptr)); |
| 172 | if (nptr == NULL) { |
| 173 | el_free(dirname); |
| 174 | dirname = NULL; |
| 175 | return NULL; |
| 176 | } |
| 177 | dirname = nptr; |
| 178 | (void)strncpy(dirname, text, len); |
| 179 | dirname[len] = '\0'; |
| 180 | } else { |
| 181 | el_free(filename); |
| 182 | if (*text == 0) |
| 183 | filename = NULL; |
| 184 | else { |
| 185 | filename = strdup(text); |
| 186 | if (filename == NULL) |
| 187 | return NULL; |
| 188 | } |
| 189 | el_free(dirname); |
| 190 | dirname = NULL; |
| 191 | } |
| 192 | |
| 193 | if (dir != NULL) { |
| 194 | (void)closedir(dir); |
| 195 | dir = NULL; |
| 196 | } |
| 197 | |
| 198 | /* support for ``~user'' syntax */ |
| 199 | |
| 200 | el_free(dirpath); |
| 201 | dirpath = NULL; |
no test coverage detected