OpenSolaris_b135/cmd/refer/hunt1.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved  	*/

/*
 * Copyright (c) 1980 Regents of the University of California.
 * All rights reserved. The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <locale.h>
#include <stdio.h>
#include <assert.h>
extern char refdir[];
extern int keepold;
extern char *fgnames[];
extern char **fgnamp;
FILE *fd = NULL;
int lmaster = 500;
int *hfreq, hfrflg;
int colevel = 0;
int measure = 0;
int soutlen = 1000;
int reached = 0;
int iflong = 0;
int prfreqs = 0;
char usedir[100];
char *calloc();
char *todir();
char gfile[50];
static int full = 1000;
static int tags = 0;
char *sinput, *soutput, *tagout;
long indexdate = 0, gdate();

extern int baddrop();
extern int doquery();
extern void err();
extern long findline();
extern int getq();
extern void grepcall();
extern int makefgrep();
extern void result();
extern void tick();
extern void tock();

static int setfrom(char);

int
main(int argc, char *argv[])
{
	/* read query from stdin, expect name of indexes in argv[1] */
	static FILE *fa, *fb, *fc;
	char nma[100], nmb[100], nmc[100], *qitem[100], *rprog = NULL;
	char nmd[100], grepquery[256];
	static char oldname[30];
	static int was = 0;
	/* these pointers are unions of pointer to int and pointer to long */
	long *hpt;
	unsigned *master = 0;
	int falseflg, nhash, nitem, nfound, frtbl, kk;

	/* special wart for refpart: default is tags only */

	(void) setlocale(LC_ALL, "");

#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	falseflg = 0;

	while (argc > 1 && argv[1][0] == '-') {
		switch (argv[1][1]) {
		case 'a': /* all output, incl. false drops */
			falseflg = 1;
			break;
		case 'r':
			argc--;
			argv++;
			rprog = argv[1];
			break;
		case 'F': /* put out full text */
			full = setfrom(argv[1][2]);
			break;
		case 'T': /* put out tags */
			tags = setfrom(argv[1][2]);
			break;
		case 'i': /* input in argument string */
			argc--;
			argv++;
			sinput = argv[1];
			break;
		case 's': /* text output to string */
		case 'o':
			argc--;
			argv++;
			soutput = argv[1];
			if ((int)argv[2] < 16000) {
				soutlen = (int)argv[2];
				argc--;
				argv++;
			}
			break;
		case 't': /* tag output to string */
			argc--;
			argv++;
			tagout = argv[1];
			break;
		case 'l': /* length of internal lists */
			argc--;
			argv++;
			lmaster = atoi(argv[1]);
			break;
		case 'g': /* suppress fgrep search on old files */
			keepold = 0;
			break;
		case 'C': /* coordination level */
			colevel = atoi(argv[1]+2);
#if D1
			fprintf(stderr, "colevel set to %d\n", colevel);
#endif
			break;
		case 'P': /* print term freqs */
			prfreqs = 1;
			break;
		case 'm':
			measure = 1;
			break;
		}
		argc--;
		argv++;
	}
	if (argc < 2)
		exit(1);
	strcpy(nma, todir(argv[1]));
	if (was == 0 || strcmp(oldname, nma) != 0) {
		strcpy(oldname, nma);
		strcpy(nmb, nma);
		strcpy(nmc, nmb);
		strcpy(nmd, nma);
		strcat(nma, ".ia");
		strcat(nmb, ".ib");
		strcat(nmc, ".ic");
		strcat(nmd, ".id");
		if (was) {
			fclose(fa);
			fclose(fb);
			fclose(fc);
		}

		fa = fopen(nma, "r");
		if (fa == NULL) {
			strcpy(*fgnamp++ = calloc(strlen(oldname)+2, 1),
			    oldname);
			fb = NULL;
			goto search;
		}
		fb = fopen(nmb, "r");
		fc = fopen(nmc, "r");
		was = 1;
		if (fb == NULL || fc == NULL) {
			err(gettext("Index incomplete %s"), nmb);
			exit(1);
		}
		indexdate = gdate(fb);
		fd = fopen(nmd, "r");
	}
	fseek(fa, 0L, 0);
	fread(&nhash, sizeof (nhash), 1, fa);
	fread(&iflong, sizeof (iflong), 1, fa);
	if (master == 0)
		master = (unsigned *)calloc(lmaster, iflong ?
		    sizeof (long) : sizeof (unsigned));
	hpt = (long *)calloc(nhash, sizeof (*hpt));
	kk = fread(hpt, sizeof (*hpt), nhash, fa);
#if D1
	fprintf(stderr, "read %d hashes, iflong %d, nhash %d\n",
	    kk, iflong, nhash);
#endif
	assert(kk == nhash);
	hfreq = (int *)calloc(nhash, sizeof (*hfreq));
	assert(hfreq != NULL);
	frtbl = fread(hfreq, sizeof (*hfreq), nhash, fa);
	hfrflg = (frtbl == nhash);
#if D1
	fprintf(stderr, "read freqs %d\n", frtbl);
#endif

search:
	while (1) {
		nitem = getq(qitem);
		if (measure) tick();
		if (nitem == 0) continue;
		if (nitem < 0) break;
		if (tagout) tagout[0] = 0;
		if (fb != NULL) {
			nfound = doquery(hpt, nhash, fb, nitem, qitem, master);
#if D1
			fprintf(stderr, "after doquery nfound %d\n", nfound);
#endif
			fgnamp = fgnames;
			if (falseflg == 0)
				nfound = baddrop(master, nfound, fc,
				    nitem, qitem, rprog, full);
#if D1
			fprintf(stderr, "after baddrop nfound %d\n", nfound);
#endif
		}
		if (fgnamp > fgnames) {
			char **fgp, tgbuff[100];
			int k;
#if D1
			fprintf(stderr, "were %d bad files\n", fgnamp-fgnames);
#endif
			(void) memset(tgbuff, 0, sizeof (tgbuff));
			grepquery[0] = 0;
			for (k = 0; k < nitem; k++) {
				strcat(grepquery, " ");
				strcat(grepquery, qitem[k]);
			}
#if D1
			fprintf(stderr, "grepquery %s\n", grepquery);
#endif
			for (fgp = fgnames; fgp < fgnamp; fgp++) {
#if D1
				fprintf(stderr, "Now on %s query /%s/\n",
				    *fgp, grepquery);
#endif
				makefgrep(*fgp);
#if D1
				fprintf(stderr, "grepmade\n");
#endif
				if (tagout == 0)
					tagout = tgbuff;
				grepcall(grepquery, tagout, *fgp);
#if D1
				fprintf(stderr, "tagout now /%s/\n", tagout);
#endif
				if (full) {
					int nout;
					char *bout;
					char *tagp;
					char *oldtagp;
					tagp = tagout;
					while (*tagp) {
						oldtagp = tagp;
						while (*tagp &&
						    (*tagp != '\n'))
							tagp++;
						if (*tagp)
							tagp++;
						nout = findline(oldtagp, &bout,
						    1000, 0L);
						if (nout > 0) {
							fputs(bout, stdout);
							free(bout);
						}
					}
				}
			}
		}
		if (tags)
			result(master, nfound > tags ? tags : nfound, fc);
		if (measure) tock();
	}
	return (0);
}

char *
todir(char *t)
{
	char *s;
	s = t;
	while (*s) s++;
	while (s >= t && *s != '/') s--;
	if (s < t)
		return (t);
	*s++ = 0;
	t = (*t ? t : "/");
	chdir(t);
	strcpy(usedir, t);
	return (s);
}

static int
setfrom(char c)
{
	switch (c) {
	case 'y':
	case '\0':
	default:
		return (1000);
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		return (c-'0');
	case 'n':
	case '0':
		return (0);
	}
}