[comp.sources.bugs] ID cross-ref programs fix

jack@cadre.dsl.PITTSBURGH.EDU (Jack Nelson) (10/23/87)

Here is a fix for the absolute pathname misprinting without leading
backslash; the code is in skipJunk().

Cut:-----------
*** paths.c.org	Mon Oct 12 17:34:35 1987
--- paths.c	Fri Oct 23 16:01:03 1987
***************
*** 62,70
  		return NULL;
  	while (*path == '/')
  		path++;
! 	while (path[0] == '.' && path[1] == '/') {
! 		path += 2;
! 		while (*path == '/')
  			path++;
  	}
  	if (strequ(path, "."))

--- 62,74 -----
  		return NULL;
  	while (*path == '/')
  		path++;
! 	if ( *path == '.') {
! 		while (path[0] == '.' && path[1] == '/') {
! 			path += 2;
! 			while (*path == '/')
! 				path++;
! 		}
! 		if (strequ(path, "."))
  			path++;
  	}
  	else if ( *(path-1) == '/' ) --path; /* absolute directory */
***************
*** 67,74
  		while (*path == '/')
  			path++;
  	}
! 	if (strequ(path, "."))
! 		path++;
  	
  	return path;
  }

--- 71,77 -----
  		if (strequ(path, "."))
  			path++;
  	}
! 	else if ( *(path-1) == '/' ) --path; /* absolute directory */
  	
  	return path;
  }

-- 
John P. Nelson, M.D., 3811 O'Hara St, Pittsburgh, PA 15213, t:412-624-1769 Dept. of Psychiatry, U. of Pittsburgh
UUCP: { akgua | allegra | cmcl2 | idis | ihnp4 | mi-cec | pitt | psuvax1 | sun | sunrise | vax135 } ! cadre ! jack
ARPA: jack@cadre.dsl.pittsburgh.edu

guido@cwi.nl (Guido van Rossum) (10/28/87)

The patch posted to fix some problem with files with leading backslash
(backslash?!?  surely you mean slash!?!) breaks the mechanism to find
the ID file is a directory higher up in the hierarchy -- spanPath ends
up appending an infinite series of "../" to a buffer.

I can't offer a fix -- I must say I don't understand exactly what the
code is doing there, and maybe neither is the author, or the problem
which the patch was supposed to fix wouldn't have occurred.  Undoing the
patch was enough for me.
--
Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
guido@cwi.nl or mcvax!guido or (from ARPAnet) guido%cwi.nl@uunet.uu.net

tbm@anuck.UUCP (10/30/87)

The patch to paths.c was not succesfull here either.

Not only do we  have the problem  with paths.c, but  don't have the  BSD
dir-open/close/etc stuff.  We run pure  SYS 5.2 here and wonder how  all
of you are getting it to compile.

You ask "How do you know you have the problem?".  Well, we do have  some
internal software that includes an  ndir.h and a library that  satisfied
the linker, unfortunately it is not on all our machines (Amdahl).

Could the author please supply all  that is needed and perhaps  simplify
the fancy stuff that tries to handle relative (or whatever) path-names?

This program is ideal for a  complex project where we must maintain  and
add features with new people.  It almost works, please don't stop now.

Any help would be greatly appreciated,
Tom Merrick ATT BTL Andover, MA

stan@amc.UUCP (Stan Tazuma) (10/31/87)

In article <99@piring.cwi.nl> guido@cwi.nl (Guido van Rossum) writes:
>the ID file is a directory higher up in the hierarchy -- spanPath ends
>up appending an infinite series of "../" to a buffer.
>
>I can't offer a fix -- I must say I don't understand exactly what the
>code is doing there, and maybe neither is the author, or the problem
>which the patch was supposed to fix wouldn't have occurred.  Undoing the
>patch was enough for me.

I spent some time on it and I think I've got the proper
fix for the slash problem.  First, do not use the previous slash fix
posted by Jack Nelson (the mods to paths.c/skipJunk()).  Instead, put
the following lines at the beginning of paths.c/spanPath() (right after
the declarations).

	if (arg[0] == '/') {
		/* don't need to span full pathnames */
		strcpy(pathBuf, arg);
		return(pathBuf);
	}

The code is complicated because of an attempt to handle different
situations involving the location of the ID database, and of where the
files specified in the database are actually located.
There is code to search for the ID database.  Depending on
where it finds it, it prefixes one or more "../" strings in front of
file names.  The fix by Jack Nelson does cause an infinite loop, but
not normally in the loop which prefixes "../" (at least for my tests).
It looped in the "for (;;)" loop because a leading '/' causes argLength
to be 0, which makes the strnequ(...) (alias strncmp()) to act as though
the strings matched, when in fact they were different.

---------------------------------------------

For a usable version of the id package, install the above
change, plus the fixes posted by Tim Walters (opening files)
and Ian Donaldson (fix for eid to prevent ^C from killing it).
The package works quite well now and my thanks go to the author,
Greg Mcgary.

Following are some possibly interesting and/or useful enhancements that
I also use.  They probably depend on your having 4.[23]bsd or
equivalent (Ultrix), including Sun OS 3.4 (maybe any of 3.x).

=============================================
Greg apparently didn't see much need for full pathnames,
hence the fact the original code didn't support it.  However, consider
setting up a database for many local files, but also wanting identifiers
in system include files in the database.   Normally you might run mkid
with the following args:	mkid *.[ch]
But that doesn't account for the system include files.  Here's a script
which will pull those in also (it depends on your cc(1) supporting
the -M option, which generates makefile dependency lines).
---------------mkflist--------------cut here
#! /bin/sh
# script for listing all the include files for the specified source
# files.  Also lists the specified source files.
# This was written for use with the id system (mkid).
# Note:  "cc -M" might not work everywhere.
#	-- Stan Tazuma  10/30/87

if test $# = 0
then
    echo "Usage:  $0 [ cc args ] source-files ..."
    echo Examples:
    echo "	$0 *.c"
    echo "	$0 -I. *.c"
    echo "	mkid \`$0 *.c\`"
    exit 1
fi
cc -M $@ | sed -e 's/.*: //' -e 's;^\./;;' | sort | uniq

# The one below lists all the local .h files first, then all the full
# pathname'd include files, then all the .c files.  The one above
# inter-mingles the local .h and .c files.
# cc -M $@ | sed 's/.*: //' | sort | uniq | sed 's;^\./;;'
---------------end of mkflist--------------cut here

==================================================================
Another subject.  The ID database uses a (partly) binary format.  This
makes it byte-order dependent.  In a networked (NFS) environment
this is a problem.  Yes one could re-build the database when needed,
but when just browsing you wouldn't want to do that.  Here's a solution
which works in a Sun/VAX environment.  It depends on the assumption
that the only byte order dependent part of the database is in the
idhead struct which gets written at the beginning of the database.
A byte for byte comparison of Sun and VAX databases showed the differences
were confined here.

Here are the relevant changes.  (My files have a bunch of RCS stuff in
them, which I deleted from below.  The line numbers below will vary
from the original source.  Hopefully the context is sufficient.)
------id.h changes---------------
RCS file: id.h,v
retrieving revision 1.1
retrieving revision 1.3
diff -c -r1.1 -r1.3
*** /tmp/,RCSt1022558	Fri Oct 30 18:35:00 1987
--- /tmp/,RCSt2022558	Fri Oct 30 18:35:02 1987
***************
*** 1,13 ****
--- 1,35 ----
  #define	IDFILE	"ID"
  
+ #define COMMON_FILE_FORMAT	/* use an ID file which is the same on
+ 				 * a VAX or a SUN (and other similar
+ 				 * architectures) */
+ 
  struct idhead {
  	char	idh_magic[2];	/* magic number */
  #define	IDH_MAGIC "\311\304"	/* magic-number ("ID" with hi bits) */
  	short	idh_vers;	/* id-file version number */
+ #if ! defined(COMMON_FILE_FORMAT)
  #define	IDH_VERS	2	/* current version */
+ #else
+ #define	IDH_VERS	3	/* to prevent destruction of existing
+ 				 * databases */
+ #endif
  	int	idh_argc;	/* # of args for mkid update */
  	int	idh_pthc;	/* # of paths for mkid update */
  	int	idh_namc;	/* # of identifiers */
------init.c changes---------------
RCS file: init.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** /tmp/,RCSt1022489	Fri Oct 30 18:26:21 1987
--- /tmp/,RCSt2022489	Fri Oct 30 18:26:22 1987
***************
*** 22,27 ****
--- 29,37 ----
  
  	fseek(idFILE, 0L, 0);
  	fread(idhp, sizeof(struct idhead), 1, idFILE);
+ #ifdef COMMON_FILE_FORMAT
+ 	massage_in(idhp);
+ #endif
  	if (!strnequ(idhp->idh_magic, IDH_MAGIC, sizeof(idhp->idh_magic))) {
  		fprintf(stderr, "%s: Not an id file: `%s'\n", MyName, idFile);
  		exit(1);
------mkid.c changes---------------
RCS file: mkid.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** /tmp/,RCSt1022500	Fri Oct 30 18:28:01 1987
--- /tmp/,RCSt2022500	Fri Oct 30 18:28:02 1987
***************
*** 378,384 ****
--- 385,402 ----
  	strncpy(idh.idh_magic, IDH_MAGIC, sizeof(idh.idh_magic));
  	idh.idh_vers = IDH_VERS;
  	fseek(idFILE, 0L, 0);
+ #ifdef COMMON_FILE_FORMAT
+ 	{
+ 	    struct idhead midh;
+ 	    extern void massage_out();
+ 
+ 	    midh = idh;
+ 	    massage_out(&midh);
+ 	    fwrite(&midh, sizeof(struct idhead), 1, idFILE);
+ 	}
+ #else
  	fwrite(&idh, sizeof(struct idhead), 1, idFILE);
+ #endif
  
  	fclose(idFILE);
  }
***************
*** 413,418 ****
--- 431,439 ----
  	}
  	idModTime = statBuf.st_mtime;
  	fread(&idh, sizeof(struct idhead), 1, idFILE);
+ #ifdef COMMON_FILE_FORMAT
+ 	massage_in(&idh);
+ #endif
  	if (!strnequ(idh.idh_magic, IDH_MAGIC, sizeof(idh.idh_magic))) {
  		fprintf(stderr, "%s: Not an id file: `%s'\n", MyName, idFile);
  		exit(1);
***************
*** 478,483 ****
--- 499,507 ----
  	if ((idFILE = fopen(idFile, "r")) == NULL)
  		filerr("open", idFile);
  	fread(&idh, sizeof(struct idhead), 1, idFILE);
+ #ifdef COMMON_FILE_FORMAT
+ 	massage_in(&idh);
+ #endif
  
  	entry = malloc(idh.idh_bsiz);
  
---end of diffs------------------------------------------------------------

Also needed is massage.c: 
----------------------cut here----------------
#include "id.h"

#ifdef COMMON_FILE_FORMAT
	/* next two are for htons(), etc. defines */
#include <sys/types.h>
#include <netinet/in.h>

/*
 * Convert the idhead structure to a common format, in preparation for
 * writing to a file for storage.
 * The established "network" order is used (as defined in 4.[23]bsd Unix).
 */
void
massage_out(idh)
register struct idhead *idh;
{
    idh->idh_vers = (short) htons(idh->idh_vers);
    idh->idh_argc = (int) htonl(idh->idh_argc);
    idh->idh_pthc = (int) htonl(idh->idh_pthc);
    idh->idh_namc = (int) htonl(idh->idh_namc);
    idh->idh_vecc = (int) htonl(idh->idh_vecc);
    idh->idh_bsiz = (int) htonl(idh->idh_bsiz);
    idh->idh_argo = (long) htonl(idh->idh_argo);
    idh->idh_namo = (long) htonl(idh->idh_namo);
    idh->idh_endo = (long) htonl(idh->idh_endo);
    return;
}

/*
 * Convert the idhead structure to a common format, after reading the
 * structure from a file (which is assumed to be using the common
 * file format).
 * The established "network" order is used (as defined in 4.[23]bsd Unix).
 */
void
massage_in(idh)
register struct idhead *idh;
{
    idh->idh_vers = (short) ntohs(idh->idh_vers);
    idh->idh_argc = (int) ntohl(idh->idh_argc);
    idh->idh_pthc = (int) ntohl(idh->idh_pthc);
    idh->idh_namc = (int) ntohl(idh->idh_namc);
    idh->idh_vecc = (int) ntohl(idh->idh_vecc);
    idh->idh_bsiz = (int) ntohl(idh->idh_bsiz);
    idh->idh_argo = (long) ntohl(idh->idh_argo);
    idh->idh_namo = (long) ntohl(idh->idh_namo);
    idh->idh_endo = (long) ntohl(idh->idh_endo);
    return;
}
#endif COMMON_FILE_FORMAT
---------------------------------cut here--------------------

To the makefile, add "massage.o" to the list of OFILES.
You should also add the output of "cc -M -I. *.c" to the end of the
makefile.  That way make will notice that when a header file changes
the corresponding source files will be re-built.

Another change I would make to the source is to use #include "...."
for local (in current directory) include files rather than #include <...>.
That way -I. wouldn't have to used (in the makefile and with mkflist).

For those who don't have htons(), etc., those are used to convert
to/from a "network" byte order.  They are normally just used in
programs dealing with networking.  The "network" byte order is
that of 680x0's.

Stan Tazuma
Applied Microsystems Corp.
	...uw-beaver!tikal!amc!stan

jfh@killer.UUCP (The Beach Bum) (11/03/87)

Now I'm totally confused.  This is getting as bad as the ARC conversation
was.  Would someone please collect all of the patches they used or post
diffs against their current working version and the original source?

I'm just so confused ...

- John.
-- 
John F. Haugh II		HECI Exploration Co. Inc.
UUCP:	...!ihnp4!killer!jfh	11910 Greenville Ave, Suite 600
"Don't Have an Oil Well?"	Dallas, TX. 75243
" ... Then Buy One!"		(214) 231-0993

gordon@prls.UUCP (Gordon Vickers) (11/04/87)

On one fine November day, John (John Haugh II) wrote:
->Now I'm totally confused.  This is getting as bad as the ARC conversation
->was.  Would someone please collect all of the patches they used or post
->diffs against their current working version and the original source?
->
->I'm just so confused ...
->
->- John.
->-- 
->John F. Haugh II		HECI Exploration Co. Inc.

   I'll second that!  I don't know which patch is which anymore.
  Prehaps the orignal author would care to do the re-post ?