[Pinfo-devel] r220 - pinfo/trunk/src

Bas Zoetekouw bas at costa.debian.org
Sat Sep 10 15:06:56 UTC 2005


Author: bas
Date: 2005-09-10 15:06:55 +0000 (Sat, 10 Sep 2005)
New Revision: 220

Modified:
   pinfo/trunk/src/pinfo.c
   pinfo/trunk/src/utils.c
   pinfo/trunk/src/utils.h
Log:
Added a check to automatically fix broken tag tables.
If the node we find isn't the same node we were looking
for, we set ForceManualTagTable to 1 (simulating a -t 
command line option) and reload the current file.


Modified: pinfo/trunk/src/pinfo.c
===================================================================
--- pinfo/trunk/src/pinfo.c	2005-09-10 10:46:18 UTC (rev 219)
+++ pinfo/trunk/src/pinfo.c	2005-09-10 15:06:55 UTC (rev 220)
@@ -61,6 +61,7 @@
 	/* this will hold the node's header */
 	char *type = 0;
 	int tag_table_pos = 1;
+	char *file_name_force = NULL;
 #ifdef HAVE_GETOPT_LONG
 	static struct option long_options[] =
 	{
@@ -383,10 +384,71 @@
 
 			/* handle goto/link where no file was found -- see below */
 			if (!filenotfound)
-				addinfohistory(curfile, tag_table[tag_table_pos].nodename, -1, -1, -1);
+			{
+				addinfohistory(curfile, tag_table[tag_table_pos].nodename, 
+						-1, -1, -1);
+			}
 			else
 				filenotfound = 0;
-			work_return_value = work(&message, &type, &lines, id, tag_table_pos);
+
+			/* this might have been allocated in the previous iteration */
+			if (file_name_force!=NULL) 
+			{
+				xfree(file_name_force);
+				file_name_force = NULL;
+			}
+
+			/* check if we really found the node we were looking for
+			 * (don't do this for tag tables we manually created, as this 
+			 * might cause a loop if somethign goes wrong)
+			 *
+			 * the entire handling of file_name_force and work_return_value.file is a 
+			 * big hack, but it'll have to do for now, until the entire work 
+			 * loop thing is rewritten.
+			 */
+			if ( (ForceManualTagTable==0)
+				 && (check_node_name(work_return_value.node, type) == 0 ))
+			{
+				/* Oops, we found the wrong node! */
+
+				/* display error message to make the user aware of 
+				 * the broken info page 
+				 */
+				char msg[81];
+				snprintf(msg, 81, "%s (%s)", 
+						_("Tag table is corrupt, trying to fix..."),
+						_("press a key to continue") );
+				attrset(bottomline);
+				mvhline(maxy - 1, 0, ' ', maxx);
+				mvaddstr(maxy - 1, 0, msg);
+				move(0, 0);
+				attrset(normal);
+				getch();
+
+				/* We found another node than we were looking for, so the 
+				 * tag table must be corrupt. Try to fix it by manually
+				 * creating tag tables and... */
+				ForceManualTagTable = 1;
+				
+				/* forcing the current file to reload by seting 
+				 * work_return_value.file to the current file, and the current 
+				 * file to \0
+				 */
+				if (file_name_force) xfree(file_name_force);
+				file_name_force = xmalloc( strlen(curfile)+1 ); /* freed below */
+				strcpy(file_name_force, curfile);
+				curfile[0] = '\0';
+				work_return_value.file = file_name_force;
+
+				/* remove this try from the history stack */
+				dellastinfohistory();
+			}
+			else 
+			{
+				/* everything went fine, so display the node and wait for
+				 * key events and stuff */
+				work_return_value = work(&message, &type, &lines, id, tag_table_pos);
+			}
 			if (work_return_value.node)
 			{
 				/* no cross-file link selected */

Modified: pinfo/trunk/src/utils.c
===================================================================
--- pinfo/trunk/src/utils.c	2005-09-10 10:46:18 UTC (rev 219)
+++ pinfo/trunk/src/utils.c	2005-09-10 15:06:55 UTC (rev 220)
@@ -518,3 +518,62 @@
 	getmaxyx(stdscr, maxy, maxx);
 	ungetch(keys.refresh_1);
 }
+
+/*
+ * this functions checks whether the node header node_header 
+ * corresponds to node node_name
+ *
+ * e.g. the header is something like:
+ * File: bash.info,  Node: Introduction,  Next: Defs,  Prev: Top,  Up: Top
+ * and we check here if the Node: entry in this header is equal to node_name
+ *
+ * returns  0 if node_header does not belong to a node with name node_name
+ * returns -1 if no checking was done
+ * returns  1 if check turned out ok
+ */
+int
+check_node_name( const char * const node_name, const char * const node_header)
+{
+	/* if either one of node_name or node_header is NULL or a zero 
+	 * sized string, we have nothing to check, so return success */
+	if ( (node_name==NULL) || (node_header==NULL) 
+		|| (strlen(node_name)==0) || (strlen(node_header)==0) )
+	{
+		return 1;
+	}
+
+	size_t header_len = strlen(node_header);
+	
+	/* copy node_header to a local string which can be mutilated */
+	/* don't use strdup here, as xmalloc handles all errors */
+	char *header = xmalloc( header_len + 1 );
+	strcpy(header, node_header);
+
+	/* search for "Node: foobar," in node_header */
+	char *str_start = strstr(header, "Node: ");
+	if (str_start==NULL) /* no match */
+	{
+		return 0;
+	}
+	/* advance str_start to the start of the node name */
+	str_start += strlen("Node: ");
+	/* and search for the next comma, tab, or newline */
+	char *c = str_start;
+	while ( (*c!=',') && (*c!='\t') && (*c!='\n') && (*c!='\0') ) c++;
+	*c = '\0';
+	
+	/* so, now str_start point to a \0-terminated string containing the 
+	 * node name from the header.
+	 * Let's compare it with the node_name we're looking for */
+	if ( strcmp(str_start, node_name)==0 )
+	{
+		/* match found */
+		return 1;
+	}
+	else
+	{
+		/* no match */
+		return 0;
+	}
+}
+

Modified: pinfo/trunk/src/utils.h
===================================================================
--- pinfo/trunk/src/utils.h	2005-09-10 10:46:18 UTC (rev 219)
+++ pinfo/trunk/src/utils.h	2005-09-10 15:06:55 UTC (rev 220)
@@ -78,4 +78,16 @@
 /* is curses screen open? */
 extern int curses_open;
 
+/*
+ * this functions checks whether the node header node_header 
+ * corresponds to node node_name
+ *
+ * returns  0 if node_header does not belong to a node with name node_name
+ * returns -1 if no checking was done (e.g. because node_name was NULL)
+ * returns  1 if check turned out ok
+ */
+int
+check_node_name( const char * const node_name, const char * const node_header);
+
+
 #endif




More information about the Pinfo-devel mailing list