/* Assume FNAME is an absolute file name, and check whether it is a regular file. If it is, return it as a new string; otherwise return a NULL pointer. We do it by taking the file name apart into its directory and basename parts, and calling info_file_in_path.*/ static char * info_absolute_file (char *fname) { char *containing_dir = xstrdup (fname); char *base = filename_non_directory (containing_dir); if (base > containing_dir) base[-1] = '\0'; return info_file_in_path (filename_non_directory (fname), containing_dir); }
/* Return the expansion of FILENAME. */ char * expand_filename (char *filename, char *input_name) { int i; if (filename) { filename = full_pathname (filename); if (IS_ABSOLUTE (filename) || (*filename == '.' && (IS_SLASH (filename[1]) || (filename[1] == '.' && IS_SLASH (filename[2]))))) return filename; } else { filename = filename_non_directory (input_name); if (!*filename) { free (filename); filename = xstrdup ("noname.texi"); } for (i = strlen (filename) - 1; i; i--) if (filename[i] == '.') break; if (!i) i = strlen (filename); if (i + 6 > (strlen (filename))) filename = xrealloc (filename, i + 6); strcpy (filename + i, html ? ".html" : ".info"); return filename; } if (IS_ABSOLUTE (input_name)) { /* Make it so that relative names work. */ char *result; i = strlen (input_name) - 1; result = xmalloc (1 + strlen (input_name) + strlen (filename)); strcpy (result, input_name); while (!IS_SLASH (result[i]) && i) i--; if (IS_SLASH (result[i])) i++; strcpy (&result[i], filename); free (filename); return result; } return filename; }
/* Return just the simple part of the filename; i.e. the filename without the path information, or extensions. This conses up a new string. */ char * filename_part (char *filename) { char *basename = filename_non_directory (filename); #ifdef REMOVE_OUTPUT_EXTENSIONS /* See if there is an extension to remove. If so, remove it. */ { char *temp = strrchr (basename, '.'); if (temp) *temp = 0; } #endif /* REMOVE_OUTPUT_EXTENSIONS */ return basename; }
/* Scan the list of directories in PATH looking for FILENAME. If we find one that is a regular file, return it as a new string. Otherwise, return a NULL pointer. */ static char * info_file_in_path (char *filename, char *path) { struct stat finfo; char *temp_dirname; int statable, dirname_index; /* Reject ridiculous cases up front, to prevent infinite recursion later on. E.g., someone might say "info '(.)foo'"... */ if (!*filename || STREQ (filename, ".") || STREQ (filename, "..")) return NULL; dirname_index = 0; while ((temp_dirname = extract_colon_unit (path, &dirname_index))) { register int i, pre_suffix_length; char *temp; /* Expand a leading tilde if one is present. */ if (*temp_dirname == '~') { char *expanded_dirname; expanded_dirname = tilde_expand_word (temp_dirname); free (temp_dirname); temp_dirname = expanded_dirname; } temp = xmalloc (30 + strlen (temp_dirname) + strlen (filename)); strcpy (temp, temp_dirname); if (!IS_SLASH (temp[(strlen (temp)) - 1])) strcat (temp, "/"); strcat (temp, filename); pre_suffix_length = strlen (temp); free (temp_dirname); for (i = 0; info_suffixes[i]; i++) { strcpy (temp + pre_suffix_length, info_suffixes[i]); statable = (stat (temp, &finfo) == 0); /* If we have found a regular file, then use that. Else, if we have found a directory, look in that directory for this file. */ if (statable) { if (S_ISREG (finfo.st_mode)) { return temp; } else if (S_ISDIR (finfo.st_mode)) { char *newpath, *filename_only, *newtemp; newpath = xstrdup (temp); filename_only = filename_non_directory (filename); newtemp = info_file_in_path (filename_only, newpath); free (newpath); if (newtemp) { free (temp); return newtemp; } } } else { /* Add various compression suffixes to the name to see if the file is present in compressed format. */ register int j, pre_compress_suffix_length; pre_compress_suffix_length = strlen (temp); for (j = 0; compress_suffixes[j].suffix; j++) { strcpy (temp + pre_compress_suffix_length, compress_suffixes[j].suffix); statable = (stat (temp, &finfo) == 0); if (statable && (S_ISREG (finfo.st_mode))) return temp; } } } free (temp); } return NULL; }