1#!/bin/sh
2#fix-info-dir (GNU texinfo)
3VERSION=1.1
4#Copyright (C) 1998, 2003 Free Software Foundation, Inc.
5#fix-info-dir comes with NO WARRANTY, to the extent permitted by law.
6#You may redistribute copies of fix-info-dir
7#under the terms of the GNU General Public License.
8#For more information about these matters, see the files named COPYING."
9#fix-info-dir was derived from update-info and gen-dir-node
10# The skeleton file contains info topic names in the
11# order they should appear in the output.  There are three special
12# lines that alter the behavior: a line consisting of just "--" causes
13# the next line to be echoed verbatim to the output.  A line
14# containing just "%%" causes all the remaining filenames (wildcards
15# allowed) in the rest of the file to be ignored.  A line containing
16# just "!!" exits the script when reached (unless preceded by a line
17# containing just "--").
18#Author: Richard L. Hawes, rhawes@dmapub.dma.org.
19
20# ###SECTION 1### Constants
21set -h 2>/dev/null
22# ENVIRONMENT
23if test -z "$TMPDIR"; then
24	TMPDIR="/usr/tmp"
25fi
26if test -z "$LINENO"; then
27	LINENO="0"
28fi
29
30MENU_BEGIN='^\*\([ 	]\)\{1,\}Menu:'
31MENU_ITEM='^\* ([^ 	]).*:([ 	])+\('
32MENU_FILTER1='s/^\*\([ 	]\)\{1,\}/* /'
33MENU_FILTER2='s/\([ 	]\)\{1,\}$//g'
34
35TMP_FILE1="${TMPDIR}/fx${$}.info"
36TMP_FILE2="${TMPDIR}/fy${$}.info"
37TMP_FILE_LIST="$TMP_FILE1 $TMP_FILE2"
38
39TRY_HELP_MSG="Try --help for more information"
40
41# ###SECTION 100### main program
42#variables set by options
43CREATE_NODE=""
44DEBUG=":"
45MODE=""
46#
47Total="0"
48Changed=""
49
50while test "$*"; do
51	case "$1" in
52		-c|--create)    CREATE_NODE="y";;
53		--debug)	set -eux; DEBUG="set>&2";;
54		-d|--delete)	MODE="Detect_Invalid";;
55		+d);;
56		--version)
57cat<<VersionEOF
58fix-info-dir (GNU Texinfo) $VERSION
59Copyright (C) 1998 Free Software Foundation, Inc.
60fix-info-dir comes with NO WARRANTY, to the extent permitted by law.
61You may redistribute copies of fix-info-dir
62under the terms of the GNU General Public License.
63For more information about these matters, see the files named COPYING.
64Author: Richard L. Hawes
65VersionEOF
66		exit;;
67
68		--help)
69cat<<HelpEndOfFile
70Usage:	fix-info-dir  [OPTION]... [INFO_DIR/[DIR_FILE]] [SKELETON]
71
72It detects and inserts missing menu items into the info dir file.
73The info dir must be the current directory.
74
75Options:
76-c,	--create	create a new info node
77-d,	--delete	delete invalid menu items (ignore missing menu items)
78	--debug		print debug information to standard error path
79	--help		print this help message and exit
80	--version	print current version and exit
81Backup of the info node has a '.old' suffix added.  This is a shell script.
82Environment Variables: TMPDIR
83Email bug reports to bug-texinfo@gnu.org.
84HelpEndOfFile
85		exit;;
86
87		[-+]*)	echo "$0:$LINENO: \"$1\" is not a valid option">&2
88			echo "$TRY_HELP_MSG">&2
89			exit 2;;
90		*) break;;
91	esac
92	shift
93done
94
95ORIGINAL_DIR=`pwd`
96
97if test "$#" -gt "0"; then
98	INFO_DIR="$1"
99	shift
100else
101	INFO_DIR=$DEFAULT_INFO_DIR
102fi
103
104if test ! -d "${INFO_DIR}"; then
105	DIR_FILE=`basename ${INFO_DIR}`;
106	INFO_DIR=`dirname ${INFO_DIR}`;
107else
108	DIR_FILE="dir"
109fi
110
111cd "$INFO_DIR"||exit
112
113
114if test "$CREATE_NODE"; then
115	if test "$#" -gt "0"; then
116		if test `expr $1 : /` = '1'; then
117			SKELETON="$1"
118		else
119			SKELETON="$ORIGINAL_DIR/$1"
120		fi
121		if test ! -r "$SKELETON" && test -f "$SKELETON"; then
122			echo "$0:$LINENO: $SKELETON is not readable">&2
123			exit 2
124		fi
125		shift
126	else
127		SKELETON=/dev/null
128
129	fi
130else
131	if test ! -f "$DIR_FILE"; then
132		echo "$0:$LINENO: $DIR_FILE is irregular or nonexistant">&2
133		exit 2
134	elif test ! -r "$DIR_FILE"; then
135		echo "$0:$LINENO: $DIR_FILE is not readable">&2
136		exit 2
137	elif test ! -w "$DIR_FILE"; then
138		echo "$0:$LINENO: $DIR_FILE is not writeable">&2
139		exit 2
140	fi
141fi
142
143if test "$#" -gt "0"; then
144	echo "$0:$LINENO: Too many parameters">&2
145	echo "$TRY_HELP_MSG">&2
146	exit 2
147fi
148
149if test -f "$DIR_FILE"; then
150	cp "$DIR_FILE" "$DIR_FILE.old"
151	echo "Backed up $DIR_FILE to $DIR_FILE.old."
152fi
153
154if test "$CREATE_NODE"; then
155	if test "$MODE"; then
156		echo "$0:$LINENO: ERROR: Illogical option combination: -d -c">&2
157		echo "$TRY_HELP_MSG">&2
158		exit 2
159	fi
160	echo "Creating new Info Node: `pwd`/$DIR_FILE"
161	Changed="y"
162
163{
164
165	### output the dir header
166	echo "-*- Text -*-"
167	echo "This file was generated automatically by $0."
168	echo "This version was generated on `date`"
169	echo "by `whoami`@`hostname` for `pwd`"
170
171	cat<<DIR_FILE_END_OF_FILE
172This is the file .../info/$DIR_FILE, which contains the topmost node of the
173Info hierarchy.  The first time you invoke Info you start off
174looking at that node, which is ($DIR_FILE)Top.
175
176
177File: $DIR_FILE       Node: Top       This is the top of the INFO tree
178
179  This (the Directory node) gives a menu of major topics.
180  Typing "q" exits, "?" lists all Info commands, "d" returns here,
181  "h" gives a primer for first-timers,
182  "mEmacs<Return>" visits the Emacs topic, etc.
183
184  In Emacs, you can click mouse button 2 on a menu item or cross reference
185  to select it.
186
187* Menu: The list of major topics begins on the next line.
188
189DIR_FILE_END_OF_FILE
190
191### go through the list of files in the skeleton.  If an info file
192### exists, grab the ENTRY information from it.  If an entry exists
193### use it, otherwise create a minimal $DIR_FILE entry.
194
195	# Read one line from the file.  This is so that we can echo lines with
196	# whitespace and quoted characters in them.
197	while read fileline; do
198		# flag fancy features
199		if test ! -z "$echoline"; then        # echo line
200			echo "$fileline"
201			echoline=""
202			continue
203		elif test "${fileline}" = "--"; then
204			# echo the next line
205			echoline="1"
206			continue
207		elif test "${fileline}" = "%%"; then
208			# skip remaining files listed in skeleton file
209			skip="1"
210			continue
211		elif test "${fileline}" = "!!"; then
212			# quit now
213			break
214		fi
215
216		# handle files if they exist
217		for file in $fileline""; do
218			fname=
219			if test -z "$file"; then
220				break
221			fi
222			# Find the file to operate upon.
223			if test -r "$file"; then
224				fname="$file"
225			elif test -r "${file}.info"; then
226				fname="${file}.info"
227			elif test -r "${file}.gz"; then
228				fname="${file}.gz"
229			elif test -r "${file}.info.gz"; then
230				fname="${file}.info.gz"
231			else
232				echo "$0:$LINENO: can't find info file for ${file}?">&2
233				continue
234			fi
235
236			# if we found something and aren't skipping, do the entry
237			if test "$skip"; then
238				continue
239			fi
240
241			infoname=`echo $file|sed -e 's/.info$//'`
242			entry=`zcat -f $fname|\
243			sed -e '1,/START-INFO-DIR-ENTRY/d'\
244			-e '/END-INFO-DIR-ENTRY/,$d'`
245			if [ ! -z "${entry}" ]; then
246				echo "${entry}"
247			else
248				echo "* ${infoname}: (${infoname})."
249			fi
250			Total=`expr "$Total" + "1"`
251		done
252	done
253}>$DIR_FILE<$SKELETON
254fi
255
256trap ' eval "$DEBUG"; rm -f $TMP_FILE_LIST; exit ' 0
257trap ' rm -f $TMP_FILE_LIST
258	exit ' 1
259trap ' rm -f $TMP_FILE_LIST
260	echo "$0:$LINENO: received INT signal.">&2
261	exit ' 2
262trap ' rm -f $TMP_FILE_LIST
263	echo "$0:$LINENO: received QUIT signal.">&2
264	exit ' 3
265
266sed -e "1,/$MENU_BEGIN/d" -e "$MENU_FILTER1" -e "$MENU_FILTER2"<$DIR_FILE\
267|sed -n -e '/\* /{
268s/).*$//g
269s/\.gz$//
270s/\.info$//
271s/^.*(//p
272}'|sort -u>$TMP_FILE1
273ls -F|sed -e '/\/$/d' -e '/[-.][0-9]/d'\
274	-e "/^$DIR_FILE\$/d" -e "/^$DIR_FILE.old\$/d"\
275	-e 's/[*@]$//' -e 's/\.gz$//' -e 's/\.info$//'|sort>$TMP_FILE2
276
277if test -z "$MODE"; then
278	#Detect Missing
279	DONE_MSG="total menu item(s) were inserted into `pwd`/$DIR_FILE"
280	for Info_Name in `comm -13 $TMP_FILE1 $TMP_FILE2`; do
281		if test -r "$Info_Name"; then
282			Info_File="$Info_Name"
283		elif test -r "${Info_Name}.info"; then
284			Info_File="${Info_Name}.info"
285		elif test -r "${Info_Name}.gz"; then
286			Info_File="${Info_Name}.gz"
287		elif test -r "${Info_Name}.info.gz"; then
288			Info_File="${Info_Name}.info.gz"
289		else
290			echo "$0:$LINENO: can't find info file for ${Info_Name}?">&2
291			continue
292		fi
293		Changed="y"
294		if install-info $Info_File $DIR_FILE; then
295			Total=`expr "$Total" + "1"`
296		fi
297	done
298else
299	# Detect Invalid
300	DONE_MSG="total invalid menu item(s) were removed from `pwd`/$DIR_FILE"
301	for Info_Name in `comm -23 $TMP_FILE1 $TMP_FILE2`; do
302		Changed="y"
303		if install-info --remove $Info_Name $DIR_FILE; then
304			Total=`expr "$Total" + "1"`
305		fi
306	done
307fi
308
309# print summary
310if test "$Changed"; then
311	echo "$Total $DONE_MSG"
312else
313	echo "Nothing to do"
314fi
315rm -f $TMP_FILE_LIST
316eval "$DEBUG"
317exit 0
318