Пример #1
0
strid_t startup_findfile(void)
{
  static DIR *dir = NULL;
  static char *pathstart = NULL;
  static char *path = NULL;
  strid_t stream;
  struct dirent *d;
  char *name = NULL;

  if(!pathstart) {
    char *p = search_path;
    if(!p)
      return 0;
    pathstart = n_strdup(p);
    if(!(path = n_strtok(pathstart, ":"))) {
      n_free(pathstart);
      pathstart = 0;
      return 0;
    }
  }

  do {
    if(!dir) {
      dir = opendir(path);
      if(!dir) {
	n_free(pathstart);
	pathstart = 0;
	return 0;
      }
    }
    d = readdir(dir);
    if(!d) {
      closedir(dir);
      dir = NULL;
      if(!(path = n_strtok(NULL, ":"))) {
	n_free(pathstart);
	pathstart = 0;
	return 0;
      }
    }
  } while(!dir);

  name = (char *) n_malloc(n_strlen(path) + n_strlen(d->d_name) + 2);
  n_strcpy(name, path);
  n_strcat(name, "/");
  n_strcat(name, d->d_name);
  stream = glkunix_stream_open_pathname(name, fileusage_Data |
					fileusage_BinaryMode, 0);
  if(stream)
    set_game_filename(name);
  n_free(name);
  return stream;
}
Пример #2
0
strid_t startup_open(const char *name)
{
  strid_t str;
  char *s;

  str = glkunix_stream_open_pathname((char *) name, fileusage_Data | fileusage_BinaryMode, 0);
  if(str) {
    set_game_filename(name);
#ifdef USE_GARGLK_FEATURES
    s = strrchr(name, '\\');
    if (!s) s = strrchr(name, '/');
    garglk_set_story_name(s ? s + 1 : name);
#endif
  } else {
    char *path = search_path;
    if(path) {
      char *p;
      char *newname = (char *) n_malloc(strlen(path) + strlen(name) + 2);
      path = n_strdup(path);
      for(p = n_strtok(path, ":"); p; p = n_strtok(NULL, ":")) {
	n_strcpy(newname, p);
	n_strcat(newname, "/");
	n_strcat(newname, name);
	str = glkunix_stream_open_pathname((char *) newname, fileusage_Data |
					   fileusage_BinaryMode, 0);
	if(str) {
	  set_game_filename(newname);
#ifdef USE_GARGLK_FEATURES
	  s = strrchr(newname, '\\');
	  if (!s) s = strrchr(newname, '/');
	  garglk_set_story_name(s ? s + 1 : newname);
#endif
	  break;
        }
      }
      n_free(path);
    }
  }

  if(!str)
    fprintf(stderr, "Cannot open '%s'\n", name);

  return str;
}
Пример #3
0
/*
 * sort and condense reference signals when they are placed in
 * the text. Viz, the signal 1,2,3,4 is condensed to 1-4 and signals
 * of the form 5,2,9 are converted to 2,5,9
 */
void
condense(int *wref, int wcnt, char *sig)
{
	register int i = 0;
	char wt[4];

	qsort(wref, wcnt, sizeof(int), wswap);
	sig[0] = 0;
	while (i < wcnt) {
		snprintf(wt, sizeof(wt), "%d",wref[i]);
		n_strcat(sig,wt, MXSIG);
		if ((i+2 < wcnt) && (wref[i] == (wref[i+2] - 2))) {
			while (wref[i] == (wref[i+1] - 1))
				i++;
			n_strcat(sig, "-", MXSIG);
		} else if (++i < wcnt)
			n_strcat(sig,",\\|", MXSIG);
	}
}
Пример #4
0
void
append(char *s)
{
	char *p;
	int lch;

	trimnl(buff);
	for (p = buff; *p; p++)
		;
	lch = *--p;
	if (postpunct && punctuat(lch))
		*p = 0;
	else /* pre-punctuation */
		switch (lch) {
		case '.': 
		case '?':
		case '!':
		case ',':
		case ';':
		case ':':
			*p++ = lch;
			*p = 0;
		}
	n_strcat(buff, s, sizeof(buff));
	if (postpunct)
		switch(lch) {
		case '.': 
		case '?':
		case '!':
		case ',':
		case ';':
		case ':':
			for(p = buff; *p; p++)
				;
			if (*--p == '\n')
				*p = 0;
			*p++ = lch;
			*p++ = '\n';
			*p = 0;
		}
	if (strlen(buff) > BUFSIZ)
		err("output buff too long (%d)", BUFSIZ);
}
Пример #5
0
void
doref(char *line1)
{
	char buff[QLEN], dbuff[3*QLEN];
	char answer[ANSLEN], temp[TLEN], line[BUFSIZ];
	char *p, **sr, *flds[NFLD], *r;
	int nf, nr, query = 0, alph, digs;

   again:
	buff[0] = dbuff[0] = 0;
	if (biblio && Iline == 1 && line1[0] == '%')
		n_strcat(dbuff, line1, sizeof(dbuff));
	while (input(line, sizeof(line))) {		/* get query */
		Iline++;
		if (prefix(line, ".]"))
			break;
		if (biblio && line[0] == '\n')
			break;
		if (biblio && line[0] == '%' && line[1] == *convert)
			break;
		if (control(line[0]))
			query = 1;
		n_strcat(query ? dbuff : buff, line, query ?
		    sizeof(dbuff) : sizeof(buff));
		if (strlen(buff) > QLEN)
			err("query too long (%d)", strlen(buff));
		if (strlen(dbuff) > 3 * QLEN)
			err("record at line %d too long", Iline-1);
	}
	if (biblio && line[0] == '\n' && feof(in))
		return;
	if (strcmp(buff, "$LIST$\n")==0) {
		assert (dbuff[0] == 0);
		dumpold();
		return;
	}
	answer[0] = 0;
	for (p = buff; *p; p++) {
		if (isupper((int)*p))
			*p |= 040;
	}
	alph = digs = 0;
	for (p = buff; *p; p++) {
		if (isalpha((int)*p))
			alph++;
		else
			if (isdigit((int)*p))
				digs++;
			else {
				*p = 0;
				if ((alph+digs < 3) || common(p-alph)) {
					r = p-alph;
					while (r < p)
						*r++ = ' ';
				}
				if (alph == 0 && digs > 0) {
					r = p-digs;
					if (digs != 4 || atoi(r)/100 != 19) { 
						while (r < p)
							*r++ = ' ';
					}
				}
				*p = ' ';
				alph = digs = 0;
			}
	}
	one[0] = 0;
	if (buff[0]) {	/* do not search if no query */
		for (sr = rdata; sr < search; sr++) {
			temp[0] = 0;
			corout(buff, temp, "hunt", *sr, TLEN);
			assert(strlen(temp) < TLEN);
			if (strlen(temp)+strlen(answer) > BUFSIZ)
				err("Accumulated answers too large",0);
			n_strcat(answer, temp, sizeof(answer));
			if (strlen(answer)>BUFSIZ)
				err("answer too long (%d)", strlen(answer));
			if (newline(answer) > 0)
				break;
		}
	}
	assert(strlen(one) < ANSLEN);
	assert(strlen(answer) < ANSLEN);
	if (buff[0])
		switch (newline(answer)) {
		case 0:
			fprintf(stderr, "No such paper: %s\n", buff);
			return;
		default:
			fprintf(stderr, "Too many hits: %s\n", trimnl(buff));
			choices(answer);
			p = buff;
			while (*p != '\n')
				p++;
			*++p = 0;
		case 1:
			if (endpush)
				if ((nr = chkdup(answer))) {
					if (bare < 2) {
						nf = tabs(flds, one);
						nf += tabs(flds+nf, dbuff);
						assert(nf < NFLD);
						putsig(nf,flds,nr,line1,line,0);
					}
					return;
				}
			if (one[0] == 0)
				corout(answer, one, "deliv", dr, QLEN);
			break;
		}
	assert(strlen(buff) < QLEN);
	assert(strlen(one) < ANSLEN);
	nf = tabs(flds, one);
	nf += tabs(flds+nf, dbuff);
	assert(nf < NFLD);
	refnum++;
	if (sort)
		putkey(nf, flds, refnum, keystr);
	if (bare < 2)
		putsig(nf, flds, refnum, line1, line, 1);
	else
		flout();
	putref(nf, flds);
	if (biblio && line[0] == '\n')
		goto again;
	if (biblio && line[0] == '%' && line[1] == *convert)
		fprintf(fo, "%s%c%s", convert+1, sep, line+3);
}
Пример #6
0
void
huntmain(int argc,char **argv)
{
	/* read query from stdin, expect name of indexes in argv[1] */
	static FILE *fa, *fb, *fc;
	char indexname[PATH_MAX], *qitem[100], *rprog = 0;
	char grepquery[200];
	static char oldname[30] ;
	static int nhash = 0;
	static int maxhash = 0;
	int falseflg = 0, nitem, nfound, frtbl;
	static long *hpt = 0;
	unsigned *masterp;

# if D1
	fprintf(stderr, "in glue1 argc %d argv %o %o\n", argc, argv[0],argv[1]);
# endif
	savedir();
	while (argv[1][0] == '-')
	{
# if D1
		fprintf(stderr, "argv.1 is %s\n",argv[1]);
# endif
		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 ((intptr_t) argv[2]<16000)
			{
				soutlen = (intptr_t) argv[2];
				argc--; 
				argv++;
			}
			break;
		case 't': /*tag output to string */
			argc--; 
			argv++;
			tagout = argv[1];
			if ((intptr_t)argv[2]<16000)
			{
				taglen = (intptr_t)argv[2];
				argc--; 
				argv++;
			}
			break;
		case 'l': /* specify length of lists */
			argc--; 
			argv++;
			lmaster = atoi(argv[1]);
# if D1
			fprintf(stderr, "lmaster now %d\n",lmaster);
# endif
			break;
		case 'C': 
			argc--; 
			argv++;
			colevel = atoi(argv[1]);
			break;
		}
		argc--; 
		argv++;
	}
	n_strcpy (indexname, todir(argv[1]), sizeof(indexname));
# if D1
	fprintf(stderr, "in huntmain indexname %s typeindex %d\n", indexname, typeindex);
# endif
	if (typeindex == 0 || strcmp (oldname, indexname) !=0)
	{
		n_strcpy (oldname, indexname, sizeof(oldname));
		unopen(fa); 
		unopen(fb); 
		unopen(fc);

		if (ckexist(indexname, ".ib"))
		{
# if D1
			fprintf(stderr, "found old index\n");
# endif
			fa = iopen(indexname, ".ia");
			fb = iopen(indexname, ".ib");
			fc = iopen(indexname, ".ic");
			typeindex =1;
# if D1
			fprintf(stderr, "opened f's as %o %o %o\n",fa,fb,fc);
# endif
			indexdate = gdate(fb);
			fread (&nhash, sizeof(nhash), 1, fa);
			fread (&iflong, sizeof(iflong), 1, fa);
			if (nhash > maxhash)
			{
				if (hpt)
					free (hpt);
				hpt=0;
				if (hfreq)
					free(hfreq);
				hfreq=0;
				maxhash=nhash;
# if D1
				fprintf(stderr, "Freed if needed maxhash %d\n",maxhash);
# endif
			}
			if (hpt==0)
				hpt = zalloc(nhash, sizeof(*hpt));
# if D1
			fprintf(stderr, "hpt now %o\n",hpt);
# endif
			if (hpt == NULL)
				err("No space for hash list (%d)", nhash);
			fread( hpt, sizeof(*hpt), nhash, fa);
			if (hfreq==0)
				hfreq=zalloc(nhash, sizeof(*hfreq));
			if (hfreq==NULL)
				err("No space for hash frequencies (%d)",
				    nhash);
			frtbl = fread(hfreq, sizeof(*hfreq), nhash, fa);
			hfrflg = (frtbl == nhash);
# if D1
			fprintf(stderr,"Read pointer files\n");
# endif
			if (master.a == NULL)
			{
				if (iflong)
					master.b = zalloc(lmaster, sizeof(long));
				else
					master.a = zalloc(lmaster, sizeof(int));
			}
			if (master.a == NULL)
				err("no space for answer list", 0);
		}
		else
			if (makefgrep(indexname))
				typeindex=2;
			else
			{
				err("No files %s\n", indexname);
				exit(1);
			}
	}

	if (iflong) 
		masterp = (unsigned *) master.b;
	else
		masterp = master.a;

# if D1
	fprintf(stderr, "typeindex now %d\n",typeindex);
# endif
	tagout[0]=0;
	if (typeindex==2)
	{
		grepcall(sinput, tagout, indexname);
# if D1
		fprintf(stderr, " back from grepcall\n");
# endif
		restodir();
		return;
	}
	nitem = getq(qitem);
# if D1
	fprintf(stderr, "approaching doquery fb %o\n", fb);
# endif
	nfound = doquery(hpt, nhash, fb, nitem, qitem, masterp);
# ifdef D1
	fprintf(stderr, "return from doquery with nfound %d\n", nfound);
# endif
	if (falseflg == 0)
		nfound = baddrop(masterp, nfound, fc, nitem, qitem, rprog, full);
# ifdef D1
	fprintf(stderr, "after baddrop with nfound %d\n",nfound);
	fprintf(stderr, "tagout is /%s/, sout /%s/\n",tagout, soutput);
# endif
	if (tags)
		result (masterp, nfound >tags ? tags : nfound, fc);
# if D1
	fprintf(stderr, "done with huntmain\n");
	fprintf(stderr, "tagout is /%s/\n", tagout);
	fprintf(stderr, "string out is /%s/\n", soutput);
# endif
	if (fgnamp>fgnames)
	{
		char **fgp;
		int k;
# if D1
		fprintf(stderr, "were %d bad files\n", fgnamp-fgnames);
# endif
		grepquery[0]=0;
		for(k=0; k<nitem; k++)
		{
			n_strcat(grepquery, " ", sizeof(grepquery));
			n_strcat(grepquery, qitem[k], sizeof(grepquery));
		}
		for(fgp=fgnames; fgp<fgnamp; fgp++)
		{
# if D1
			fprintf(stderr, "Now on %s query /%s/\n", *fgp, grepquery);
# endif
			makefgrep(*fgp);
			grepcall(grepquery, tagout, *fgp);
# if D1
			fprintf(stderr, "tagout now /%s/\n", tagout);
# endif
		}
	}
	restodir();
}
Пример #7
0
void
putsig (int nf, char **flds, int nref, char *nstline,
		char *endline, int toindex)   /* choose signal style */
{
	char t[100], t1[MXSIG], t2[100], format[10], *sd, *stline;
	int addon = 0, another = 0;
	static FILE *fhide = 0;

	if (labels) {
		if (nf == 0)	/* old */
			snprintf(t, sizeof(t), "%s%c", labtab[nref],
			    labc[nref]);
		else {
			*t = 0;
			if (keywant)
				fpar(nf, flds, t, sizeof(t), keywant, 1, 0);
			if (science && t[0] == 0) {
				if (fpar(nf, flds, t, sizeof(t), 'A', 1, 0)
				    != 0) {
					if (fpar(nf, flds, t2, sizeof(t2),
					    'D', 1, 0) != 0) {
						n_strcat(t, ", ", sizeof(t));
						n_strcat(t, t2, sizeof(t));
					}
				}
			} else if (t[0] == 0) {
				if (nmlen > 0) {
					snprintf(format, sizeof(format),
						"%%.%ds%%s", nmlen);
				} else {
					snprintf(format, sizeof(format),
						"%%s%%s");
				}
				/* format is %s%s for default labels */
				/* or %.3s%s eg if wanted */
				if (fpar(nf, flds, t2, sizeof(t2), 'D', 1, 0)) {
					sd = t2;
					if (dtlen > 0) {
						int n = strlen(sd) - dtlen;
						if (n > 0)
							sd += n;
					}
				} else {
					sd = "";
				}
				t1[0] = 0;
				fpar(nf, flds, t1, sizeof(t1), 'A', 1, 0);
				snprintf(t, sizeof(t), format, t1, sd);
			}
			if (keywant) {
				addon = 0;
				for (sd = t; *sd; sd++)
					;
				if (*--sd == '-') {
					addon = 1;
					*sd = 0;
				}
			}
			if ((!keywant || addon) && !science) {
			    addch(t, keylet(t, nref));
			}
			else {
			    tokeytab (t,nref);
			}
		}
	}
	else {
		if (sort)
			snprintf(t, sizeof(t), "%c%d%c", FLAG, nref, FLAG);
		else
			snprintf(t, sizeof(t), "%d", nref);
	}
	another = (sd = lookat()) ? prefix(sd, ".[") : 0;
	if (another && (strcmp(".[\n", sd) != SAME))
		fprintf(stderr, "File %s line %d: punctuation ignored from: %s",
			Ifile, Iline, sd);
	if ((strlen(sig) + strlen(t)) > MXSIG)
		err("sig overflow (%d)", MXSIG);
	n_strcat(sig, t, sizeof(sig));
#if EBUG
	fprintf(stderr, "sig is now %s leng %d\n",sig,strlen(sig));
#endif
	trimnl(nstline);
	trimnl(endline);
	stline = stbuff;
	if (prevsig == 0) {
		n_strcpy (stline, nstline, sizeof(stbuff));
		prevsig=1;
	}
	if (stline[2] || endline[2]) {
		stline += 2;
		endline += 2;
	}
	else {
		stline  = "\\*([.";
		endline = "\\*(.]";
	}
	if (science) {
		stline = " (";
		endline = ")";
	}
	if (bare == 0) {
		if (!another) {
			snprintf(t1, sizeof(t1), "%s%s%s\n", stline, sig,
			    endline);
			if (strlen(t1) > MXSIG)
				err("t1 overflow (%d)", MXSIG);
			append(t1);
			flout();
			sig[0] = 0;
			prevsig = 0;
			if (fo == fhide) {
				int ch;
				fclose(fhide); 
				fhide = fopen(hidenam, "r");
				fo = ftemp;
				while ((ch = getc(fhide)) != EOF)
					putc(ch, fo);
				fclose(fhide);
				unlink(hidenam);
			}
		}
		else {
			if (labels) {
				n_strcat(sig, ",\\|", sizeof(sig));
			} else {
				/*
				 * Seperate reference numbers with AFLAG
				 * for later sorting and condensing.
				 */
				t1[0] = AFLAG;
				t1[1] = '\0';
				n_strcat(sig, t1, sizeof(sig));
			}
			if (fo == ftemp) {	/* hide if need be */
				snprintf(hidenam, NTFILE,
				    "/tmp/rj%dc", (int)getpid());
#if EBUG
				fprintf(stderr, "hiding in %s\n", hidenam);
#endif
				fhide = fopen(hidenam, "w");
				if (fhide == NULL)
					err("Can't get scratch file %s",
						hidenam);
				fo = fhide;
			}
		}
	}
	if (bare < 2)
		if (nf > 0 && toindex)
			fprintf(fo,".ds [F %s%c",t,sep);
	if (bare > 0)
		flout();
#if EBUG
	fprintf(stderr, "sig is now %s\n",sig);
#endif
}