[comp.os.minix] REPOST - changes for ar.c lorder.c tsort.c for long command lines

walls@killer.DALLAS.TX.US (Monty Walls) (03/06/89)

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

	I have recently rewritten portions of 'ar', 'tsort', and 'lorder'
to address problems with the long argument list needed to rebuild
libc.a for minix.  My solution is based on the technique used under
MSDOS - command response files ( like - link @cmd ).  I had to make
a couple slight changes to 'lorder' & 'tsort' for this but the big changes
were in 'ar' to handle the response file ( ar [options] lib %response.file ).
Also included with the cdiffs is a shell command to automate the process
of rebuilding a ordered library ( a quick hack ) and a makefile for
'ar'.  Try the changes out and see if I missed anything.

-Monty Walls

---------------------------cut here---------------------------------------
echo x - ar.c.cdif
sed '/^X/s///' > ar.c.cdif << '/'
X*** ar.c.bkup
X--- ar.c
X**************
X*** 2,8
X  /* V7 upgrade			Author:	Monty Walls */
X  
X  /*
X!  * Usage: ar 'key' [posname] archive [file] ...
X   *
X   *	where 'key' is one of: qrqtpmx
X   *
X--- 2,8 -----
X  /* V7 upgrade			Author:	Monty Walls */
X  
X  /*
X!  * Usage: ar 'key' [posname] archive [file|%file] ...
X   *
X   *	where 'key' is one of: qrqtpmx
X   *
X**************
X*** 23,28
X   *	  i: before 'posname'
X   *	  c: create  (suppresses creation message)
X   *	  u: replace only if dated later than member in archive
X   */
X  
X  /* mods:
X--- 23,32 -----
X   *	  i: before 'posname'
X   *	  c: create  (suppresses creation message)
X   *	  u: replace only if dated later than member in archive
X+  *
X+  *	where [file|%file]
X+  *	  file: a normal input file
X+  *	  %file: file of filenames 
X   */
X  
X  /* mods:
X**************
X*** 31,36
X   *	full V7 functionality + complete rewrite (mrw).
X   *	changed verbose mode to give member name on print (mrw).
X   *	fixed up error messages to give more info (mrw).
X   *
X   * notes:
X   *	pdp11 long format & Intel long format are different.
X--- 35,41 -----
X   *	full V7 functionality + complete rewrite (mrw).
X   *	changed verbose mode to give member name on print (mrw).
X   *	fixed up error messages to give more info (mrw).
X+  *	handle MSDOS style response files (mrw)
X   *
X   * notes:
X   *	pdp11 long format & Intel long format are different.
X**************
X*** 125,130
X  extern print_date();
X  extern user_abort(), usage();
X  extern long lseek();
X  
X  int
X  main(argc, argv)
X--- 130,136 -----
X  extern print_date();
X  extern user_abort(), usage();
X  extern long lseek();
X+ extern void filelist();
X  
X  int
X  main(argc, argv)
X**************
X*** 137,143
X  	progname = argv[0];		
X  	if (argc < 3) 
X  		usage();
X! 
X  	for (av = argv[1]; *av; ++av) {	
X  		switch (*av) {		/* major option */
X  			case 'q':
X--- 143,151 -----
X  	progname = argv[0];		
X  	if (argc < 3) 
X  		usage();
X! 		
X! 	filelist(&argc, &argv);	/* do extend filelist processing */
X! 	
X  	for (av = argv[1]; *av; ++av) {	
X  		switch (*av) {		/* major option */
X  			case 'q':
/
echo x - lorder.c.cdif
sed '/^X/s///' > lorder.c.cdif << '/'
X*** /usr/src/commands/lorder.c
X--- lorder.c
X**************
X*** 21,26
X   *		oops reversed output filename order. 3/14/88 - mrw
X   *		progname = argv[0] - should be first. 5/25/88 - mbeck
X   *		dup define error needed newline. 10/24/88 - (net)
X   */
X  
X  #include <stdio.h>
X--- 21,27 -----
X   *		oops reversed output filename order. 3/14/88 - mrw
X   *		progname = argv[0] - should be first. 5/25/88 - mbeck
X   *		dup define error needed newline. 10/24/88 - (net)
X+  *		forgot to exit(0) when finished. 2/20/88 - mrw
X   */
X  
X  #include <stdio.h>
X**************
X*** 97,102
X  		/* then print list of files for ar also */
X  		for (; list; list = list->next) 
X  			fprintf(stdout,"%s %s\n",list->name, list->name);
X  	}
X  	else {
X  		fprintf(stderr,"Usage: %s file ....\n",progname);
X--- 98,104 -----
X  		/* then print list of files for ar also */
X  		for (; list; list = list->next) 
X  			fprintf(stdout,"%s %s\n",list->name, list->name);
X+ 		exit(0);
X  	}
X  	else {
X  		fprintf(stderr,"Usage: %s file ....\n",progname);
/
echo x - tsort.c.cdif
sed '/^X/s///' > tsort.c.cdif << '/'
X*** /usr/src/commands/tsort.c
X--- tsort.c
X**************
X*** 1,7
X  /*
X   * tsort - do a topological sort on the ordered pairs of names
X   *
X!  * syntax - tsort [ file ]
X   *
X   * based on the discussion in 'The AWK programming Language', by
X   * Aho, Kernighan, & Weinberger.
X--- 1,7 -----
X  /*
X   * tsort - do a topological sort on the ordered pairs of names
X   *
X!  * syntax - tsort [-n] [ file ]
X   *
X   * based on the discussion in 'The AWK programming Language', by
X   * Aho, Kernighan, & Weinberger.
X**************
X*** 25,30
X   *	possible bug in ungetc(), fixed readone() to avoid - 2/19/88 - mrw
X   *	massive design error, rewrote dump logic - 3/15/88 - mrw
X   *	stupid error causing overlay of s1 & s2 in readnode - 9/12/88 - mrw
X   *
X   */
X  
X--- 25,31 -----
X   *	possible bug in ungetc(), fixed readone() to avoid - 2/19/88 - mrw
X   *	massive design error, rewrote dump logic - 3/15/88 - mrw
X   *	stupid error causing overlay of s1 & s2 in readnode - 9/12/88 - mrw
X+  *	add [-n] option for '\n' seperator - 2/20/89 - mrw
X   *
X   */
X  
X**************
X*** 32,38
X  #include <errno.h>
X  #include <ctype.h>
X  
X! #define printmem(_s)	(fprintf(stdout,"%s ",(_s)))
X  #define MAXNAMELEN	32
X  #define MAXMEMBERS	1024
X  
X--- 33,39 -----
X  #include <errno.h>
X  #include <ctype.h>
X  
X! #define printmem(_s)	(fprintf(stdout,"%s%c",(_s),delimit))
X  #define MAXNAMELEN	32
X  #define MAXMEMBERS	1024
X  
X**************
X*** 61,66
X  struct node *tree, *lastnode, *q[MAXMEMBERS];
X  struct dependents *lastdepd;
X  int node_cnt, rc, front, back;
X  
X  main(argc, argv)
X  int argc;
X--- 62,68 -----
X  struct node *tree, *lastnode, *q[MAXMEMBERS];
X  struct dependents *lastdepd;
X  int node_cnt, rc, front, back;
X+ char delimit = ' ';	/*default value of ' ' */
X  
X  main(argc, argv)
X  int argc;
X**************
X*** 66,74
X  int argc;
X  char **argv;
X  {
X! 	progname = argv[0];
X! 	if (argc > 1) 
X! 		if (freopen(argv[1], "r", stdin) == (FILE *)NULL) {
X  			fprintf(stderr,"Error: %s - %s\n",progname, sys_errlist[errno]);
X  			exit(1);
X  		}
X--- 68,87 -----
X  int argc;
X  char **argv;
X  {
X! 	char **av = argv;
X! 	int argsleft = argc - 1;
X! 
X! 	progname = *av++;
X! 	if (argsleft > 0) {
X! 		if (strcmp(*av, "-n") == 0) {	/* use newline as seperator */
X! 			delimit = '\n';
X! 			argsleft--;		/* used up 1 arg */
X! 			av++;			/* point to next */
X! 		}
X! 	}
X! 	
X! 	if (argsleft > 0)
X! 		if (freopen(*av, "r", stdin) == (FILE *)NULL) {
X  			fprintf(stderr,"Error: %s - %s\n",progname, sys_errlist[errno]);
X  			exit(1);
X  		}
/
echo x - orderlib
sed '/^X/s///' > orderlib << '/'
X# !/bin/sh
X#
X# build.sh :	shell file to build an ordered library
X# author:	Monty Walls
X#
X#	given an unordered library -
X#	create an ordered one
X#
X# notes:	the error recovery is not real robust
X#
XPATH=:/bin:/usr/bin:/usr/local/bin:
X#	create a temporary working directory
X
Xif test $# -ne 1; then
X	echo "Usage: orderlib name"
X	exit 1
Xfi
X
Xmkdir work
Xcd work
X
X#	extract old archive
X
Xecho "Step010 - extracting $1"
Xar x ../$1
Xif test $? -ne 0; then
X	echo "Error: orderlib - could not extract $1"
X	exit 1
Xfi
X
X#	do the lorder | tsort -	generating the ar build list
X
Xecho "Step020 - lorder of $1"
Xlorder ../$1 >lorder.out
Xif test $? -ne 0; then
X	echo "Error: orderlib - could not lorder $1"
X	exit 1
Xfi
X
Xecho "Step030 - tsort of $1"
Xtsort -n lorder.out >tsort.out
Xif test $? -ne 0; then
X	echo "Error: orderlib - could not tsort $1"
X	exit 1
Xfi
X
X#	now do the add to create the new lib.a
X
Xecho "Step040 - rebuilding $1"
Xar qc $1 %tsort.out
Xif test $? -ne 0; then
X	echo "Error: orderlib - 'ar' could not build $1"
X	exit 1
Xfi
X
X#	now move the new one back 
X
Xecho "Step050 - replacing old $1 with new $1"
Xmv $1 ../$1
X
X#	now do your clean up
X
Xecho "Step060 - cleaning up the mess"
Xcd ..
Xrm -r work
Xexit 0
/
echo x - makefile
sed '/^X/s///' > makefile << '/'
X#
X#	makefile for ar
X#
Xl=/usr/lib
Xi=/usr/include
XCFLAGS=  -i -O
X
Xarobj = ar.s date.s basename.s filelist.s
Xar:	$(arobj)
X	asld -i -o ar $l/crtso.s $(arobj) $l/libc.a $l/end.s
X
Xar.s:	ar.h
/
echo x - filelist.c
sed '/^X/s///' > filelist.c << '/'
X/*
X * filelist(argc, argv) - process a file list for %file
X *
X *  Filelist will scan down the argv looking for %file.  Filelist
X *  will copy all the arguments on the old list except the %file,
X *  which Filelist will replace with the argument list consisting
X *  of all the filenames in the %file.
X */
X  
X#include <stdio.h>
X
X#ifndef STRINGS
X#define STRINGS         128
X#endif
X
X#define MAXNAMES        1024
X
Xchar filebuf[STRINGS];
X
Xextern char *progname;
X
Xvoid
Xcant(s)
Xchar *s;
X{
X    fprintf(stderr, "Error: %s - %s\n", progname, s);
X    exit(1);
X}
X
Xvoid
Xfilelist(argc, argv) 
Xint *argc;
Xchar ***argv;
X{
X    int fac, cnt, len;
X    char **fargv, **save;
X    char *fn, *sn;
X    FILE *fp;
X	
X    if ((fargv = (char **)malloc(sizeof(char **) * MAXNAMES)) == (char **)NULL)
X        cant("get enough memory for filelist");
X	
X    save = fargv;   /* save our new argument lists starting point */
X    cnt = 0;        /* intialize our argument count */
X    
X    for (fac = 0; fac < *argc; ++fac) { /* make a pass through the arguments */
X        fn = (*argv)[fac];
X                
X        /* is it a response file */
X        if (fn[0] == '%') {
X            if ((fp = fopen(&(fn[1]), "r")) != (FILE *)NULL) {
X                
X                /* get each filename from the
X                 * response file into our new argument list
X                 */
X                while (fgets(filebuf, STRINGS, fp) != (char *)NULL) {
X                        if ((len = strlen(filebuf)) > 1) {
X                            filebuf[len-1] = '\0';
X                            if ((sn = (char *)malloc(len)) == (char *)NULL)
X                                cant("get enough memory for a name");
X                            strcpy(sn, filebuf);
X                            *fargv++ = sn;
X                            cnt++;
X                        }
X                }
X            }
X            else {
X                fprintf(stderr,"Error: %s - cannot open %s\n", progname, fn);
X                exit(1);
X            }
X        }
X        else {
X            *fargv++ = fn;      /* copy item */
X            cnt++;              /* up count of items on this list */
X        }
X    }
X    *fargv = (char *)NULL;      /* mark end of list */
X    /* now we replace the original list with our new list */
X    *argv = save;
X    *argc = cnt;
X}
/
---------------------------end here---------------------------------------

Monty Walls
Work:						Home:
	MIS Division, Tech. Support			2224 Houston Apt #8
	Oklahoma Tax Commission				Norman, OK, 73701
	2501 N. Lincoln					USA
	OKC, OK, 73194 					Phone - 405-364-5123
	USA
	Phone - 405-521-4300