Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site mit-eddie.UUCP Path: utzoo!linus!decvax!harpo!eagle!mhuxl!ihnp4!mit-eddie!smh From: smh@mit-eddie.UUCP (Steven M. Haflich) Newsgroups: net.sources Subject: another crossref program Message-ID: <1080@mit-eddie.UUCP> Date: Wed, 21-Dec-83 21:49:00 EST Article-I.D.: mit-eddi.1080 Posted: Wed Dec 21 21:49:00 1983 Date-Received: Fri, 23-Dec-83 01:31:03 EST Organization: MIT, Cambridge, MA Lines: 262 What follows is a distribution for the crossref program. This version is for Unix 4.1bsd, but another is available for Version 7. To install it, save this mail file somewhere convenient, edit it to delete everything through the line of stars below, chmod the file to make it executable, and start a shell on it. Three files will be created: crossref.1 Manual page crossref1.c The second phase invoked by the crossref command. It should be compiled into /usr/local/lib, or wherever local conventions dictate. crossref.c The user-invoked command, which should be edited if crossref1 goes anywhere other than in /usr/local/lib, and then compiled into wherever local commands live. ********************************** cat > crossref.1 < crossref.c < #include char ref1[] = "/usr/local/lib/crossref1"; char sort[] = "sort"; char file[80], oldsym[20], symbol[20], thrownc[1]; int pip1[2], pip2[2]; int n; main(argc,argv) char **argv; { register char *p; pipe(pip1); pipe(pip2); if (fork()==0) { close(1); dup(pip1[1]); close(pip1[0]); close(pip1[2]); close(pip2[0]); close(pip2[1]); argv[argc] = 0; execv(ref1,argv); exit(1); } if (fork()==0) { close(0); dup(pip1[0]); close(1); dup(pip2[1]); close(pip1[0]); close(pip1[1]); close(pip2[0]); close(pip2[1]); execlp(sort,sort,0); exit(1); } close(0); dup(pip2[0]); close(pip1[0]); close(pip1[1]); close(pip2[0]); close(pip2[1]); while (scanf("%19[^<=>]%s\n",symbol,file) == 2) { switch (file[0]) { case '<': file[0]='@'; break; case '>': file[0]=' '; break; case '=': file[0]='#'; } if(strcmp(symbol,oldsym)){ if (n>0) putchar('\n'); printf("%-12s",symbol); n = 0; strcpy(oldsym,symbol); } if(n >= 6){ n = 0; printf("\n "); } printf(" %-10s",file); n++; } putchar('\n'); exit(0); } FuNkYsTuPh cat > crossref1.c < #include #include struct exec ahdr; struct ar_hdr arhdr; char arbuf[SARMAG]; FILE *file; char filename[40]; struct nlist nlist; streq(p,r,n) register char *p, *r; register int n; { while (n--) { if (*p==0 && *r==0) break; if (*p++ != *r++) return(0); } return(1); } main(argc,argv) int argc; char **argv; { register char *i, *p; int argi,flag; long base, lng; argi = 0; newfile: if(++argi >= argc) return(0); if((file = fopen(argv[argi],"r")) == NULL){ fprintf(stderr,"can't open %s\n",argv[argi]); exit(1); } fread(&flag,sizeof flag,1,file); switch (flag) { default: rewind(file); if ( (fread(arbuf,1,SARMAG,file)!=SARMAG) || !streq(arbuf,ARMAG,SARMAG)) yell(argv[argi],0); while ( fread(&arhdr,sizeof arhdr,1,file) == 1) { if (!streq(arhdr.ar_fmag,ARFMAG,2)) yell(argv[argi],0); base = ftell(file); lng = atoi(arhdr.ar_size); if (streq(arhdr.ar_name,"__.SYMDEF ",10)) { fseek(file,lng+(lng&1),1); continue; } for ( i=arhdr.ar_name,p=filename; i < &arhdr.ar_name[sizeof arhdr.ar_name] && *i!=' '; *p++ = *i++); *p = '\0'; if ( (*--p=='.') || (*p=='o' && *--p=='.') ) *p = '\0'; if (aout()) yell(arhdr.ar_name,argv[argi]); fseek(file,base+lng+(lng&1),0); } break; case OMAGIC: case NMAGIC: case ZMAGIC: for (i=p=argv[argi]; *i; ) if (*i++ == '/') p = i; strcpy(filename,p); for (p=filename; *p; p++); if ( (*--p=='.') || (*p=='o' && *--p=='.') ) *p = '\0'; fseek(file,0L,0); if (aout()) yell(argv[argi],0); break; } fclose(file); goto newfile; } aout() { long baseloc = ftell(file); long loc, len, symend; char symname[13]; fread(&ahdr,sizeof ahdr,1,file); switch(ahdr.a_magic) { default: return(1); case OMAGIC: case NMAGIC: case ZMAGIC: break; } loc = N_SYMOFF(ahdr); symend = N_STROFF(ahdr); while (loc < symend) { fseek(file, baseloc + loc,0); len = fread(&nlist, sizeof nlist, 1, file); if (len==0) return(-1); loc += sizeof nlist; if(nlist.n_type & N_EXT){ fseek(file, baseloc + symend + nlist.n_un.n_strx,0); fscanf(file,"%12s",symname); printf("%s",symname); if(nlist.n_type == N_EXT) if (nlist.n_value) putchar('='); else putchar('>'); else putchar('<'); printf("%s\n",filename); } } return(0); } yell(s,l) char *s, *l; { if (l) fprintf(stderr,"archive %s(%s) not in a.out format\n",l,s); else fprintf(stderr,"%s not in archive or a.out format\n",s); exit(1); } FuNkYsTuPh