diff options
Diffstat (limited to 'contrib/texinfo/info/dir.c')
-rw-r--r-- | contrib/texinfo/info/dir.c | 190 |
1 files changed, 85 insertions, 105 deletions
diff --git a/contrib/texinfo/info/dir.c b/contrib/texinfo/info/dir.c index 651e48a6e3685..4ccf85613101c 100644 --- a/contrib/texinfo/info/dir.c +++ b/contrib/texinfo/info/dir.c @@ -1,7 +1,9 @@ -/* dir.c -- How to build a special "dir" node from "localdir" files. - $Id: dir.c,v 1.6 1997/07/27 21:09:20 karl Exp $ +/* dir.c -- How to build a special "dir" node from "localdir" files. */ - Copyright (C) 1993, 97 Free Software Foundation, Inc. +/* This file is part of GNU Info, a program for reading online documentation + stored in Info format. + + Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,7 +21,13 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#include "info.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#if defined (HAVE_SYS_FILE_H) +#include <sys/file.h> +#endif /* HAVE_SYS_FILE_H */ +#include <sys/errno.h> #include "info-utils.h" #include "filesys.h" #include "tilde.h" @@ -29,53 +37,23 @@ dirs_to_add which are found in INFOPATH. */ static void add_menu_to_file_buffer (), insert_text_into_fb_at_binding (); +static void build_dir_node_internal (); static char *dirs_to_add[] = { "dir", "localdir", (char *)NULL }; - -/* Return zero if the file represented in the stat structure TEST has - already been seen, nonzero else. */ - -typedef struct -{ - unsigned long device; - unsigned long inode; -} dir_file_list_entry_type; - -static int -new_dir_file_p (test) - struct stat *test; -{ - static unsigned dir_file_list_len = 0; - static dir_file_list_entry_type *dir_file_list = NULL; - unsigned i; - - for (i = 0; i < dir_file_list_len; i++) - { - dir_file_list_entry_type entry; - entry = dir_file_list[i]; - if (entry.device == test->st_dev && entry.inode == test->st_ino) - return 0; - } - - dir_file_list_len++; - dir_file_list = xrealloc (dir_file_list, - dir_file_list_len * sizeof (dir_file_list_entry_type)); - dir_file_list[dir_file_list_len - 1].device = test->st_dev; - dir_file_list[dir_file_list_len - 1].inode = test->st_ino; - return 1; -} - - void maybe_build_dir_node (dirname) char *dirname; { + FILE_BUFFER *dir_buffer; int path_index, update_tags; char *this_dir; - FILE_BUFFER *dir_buffer = info_find_file (dirname); + + /* Check to see if the file has already been built. If so, then + do not build it again. */ + dir_buffer = info_find_file (dirname); /* If there is no "dir" in the current info path, we cannot build one from nothing. */ @@ -86,10 +64,6 @@ maybe_build_dir_node (dirname) if (dir_buffer->flags & N_CannotGC) return; - /* Initialize the list we use to avoid reading the same dir file twice - with the dir file just found. */ - new_dir_file_p (&dir_buffer->finfo); - path_index = update_tags = 0; /* Using each element of the path, check for one of the files in @@ -97,56 +71,62 @@ maybe_build_dir_node (dirname) Only files explictly named are eligible. This is a design decision. There can be an info file name "localdir.info" which contains information on the setting up of "localdir" files. */ - while ((this_dir = extract_colon_unit (infopath, &path_index))) + while (this_dir = extract_colon_unit (infopath, &path_index)) { register int da_index; char *from_file; /* Expand a leading tilde if one is present. */ if (*this_dir == '~') - { - char *tilde_expanded_dirname; - - tilde_expanded_dirname = tilde_expand_word (this_dir); - if (tilde_expanded_dirname != this_dir) - { - free (this_dir); - this_dir = tilde_expanded_dirname; - } - } - - /* For every different file named in DIRS_TO_ADD found in the - search path, add that file's menu to our "dir" node. */ - for (da_index = 0; (from_file = dirs_to_add[da_index]); da_index++) - { - struct stat finfo; - int statable; - int namelen = strlen (from_file); - char *fullpath = xmalloc (3 + strlen (this_dir) + namelen); - - strcpy (fullpath, this_dir); - if (fullpath[strlen (fullpath) - 1] != '/') - strcat (fullpath, "/"); - strcat (fullpath, from_file); - - statable = (stat (fullpath, &finfo) == 0); - - /* Only add this file if we have not seen it before. */ - if (statable && S_ISREG (finfo.st_mode) && new_dir_file_p (&finfo)) - { - long filesize; - char *contents = filesys_read_info_file (fullpath, &filesize, - &finfo); - if (contents) - { - update_tags++; - add_menu_to_file_buffer (contents, filesize, dir_buffer); - free (contents); - } - } - - free (fullpath); - } + { + char *tilde_expanded_dirname; + + tilde_expanded_dirname = tilde_expand_word (this_dir); + if (tilde_expanded_dirname != this_dir) + { + free (this_dir); + this_dir = tilde_expanded_dirname; + } + } + + /* For every file named in DIRS_TO_ADD found in the search path, + add the contents of that file's menu to our "dir" node. */ + for (da_index = 0; from_file = dirs_to_add[da_index]; da_index++) + { + struct stat finfo; + char *fullpath; + int namelen, statable; + + namelen = strlen (from_file); + + fullpath = (char *)xmalloc (3 + strlen (this_dir) + namelen); + strcpy (fullpath, this_dir); + if (fullpath[strlen (fullpath) - 1] != '/') + strcat (fullpath, "/"); + strcat (fullpath, from_file); + + statable = (stat (fullpath, &finfo) == 0); + + /* Only add the contents of this file if it is not identical to the + file of the DIR buffer. */ + if ((statable && S_ISREG (finfo.st_mode)) && + (strcmp (dir_buffer->fullpath, fullpath) != 0)) + { + long filesize; + char *contents; + + contents = filesys_read_info_file (fullpath, &filesize, &finfo); + + if (contents) + { + update_tags++; + add_menu_to_file_buffer (contents, filesize, dir_buffer); + free (contents); + } + } + + free (fullpath); + } free (this_dir); } @@ -196,37 +176,37 @@ add_menu_to_file_buffer (contents, size, fb) if (fb_offset == -1) { /* Find the start of the second node in this file buffer. If there - is only one node, we will be adding the contents to the end of - this node. */ + is only one node, we will be adding the contents to the end of + this node. */ fb_offset = find_node_separator (&fb_binding); /* If not even a single node separator, give up. */ if (fb_offset == -1) - return; + return; fb_binding.start = fb_offset; fb_binding.start += - skip_node_separator (fb_binding.buffer + fb_binding.start); + skip_node_separator (fb_binding.buffer + fb_binding.start); /* Try to find the next node separator. */ fb_offset = find_node_separator (&fb_binding); /* If found one, consider that the start of the menu. Otherwise, the - start of this menu is the end of the file buffer (i.e., fb->size). */ + start of this menu is the end of the file buffer (i.e., fb->size). */ if (fb_offset != -1) - fb_binding.start = fb_offset; + fb_binding.start = fb_offset; else - fb_binding.start = fb_binding.end; + fb_binding.start = fb_binding.end; insert_text_into_fb_at_binding - (fb, &fb_binding, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)); + (fb, &fb_binding, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)); fb_binding.buffer = fb->contents; fb_binding.start = 0; fb_binding.end = fb->filesize; fb_offset = search_forward (INFO_MENU_LABEL, &fb_binding); if (fb_offset == -1) - abort (); + abort (); } /* CONTENTS_OFFSET and FB_OFFSET point to the starts of the menus that @@ -244,23 +224,23 @@ add_menu_to_file_buffer (contents, size, fb) int num_found = 0; while ((fb_binding.start > 0) && - (whitespace_or_newline (fb_binding.buffer[fb_binding.start - 1]))) + (whitespace_or_newline (fb_binding.buffer[fb_binding.start - 1]))) { - num_found++; - fb_binding.start--; + num_found++; + fb_binding.start--; } /* Optimize if possible. */ if (num_found >= 2) { - fb_binding.buffer[fb_binding.start++] = '\n'; - fb_binding.buffer[fb_binding.start++] = '\n'; + fb_binding.buffer[fb_binding.start++] = '\n'; + fb_binding.buffer[fb_binding.start++] = '\n'; } else { - /* Do it the hard way. */ - insert_text_into_fb_at_binding (fb, &fb_binding, "\n\n", 2); - fb_binding.start += 2; + /* Do it the hard way. */ + insert_text_into_fb_at_binding (fb, &fb_binding, "\n\n", 2); + fb_binding.start += 2; } } |