
/*
 *  REFS.C
 *
 *  Bringup a cross reference editor window.  The file S:dme.refs and
 *  dme.refs in the current directory are searched for the reference.
 *  If found, the file specified is searched and the segment specified
 *  loaded as a new file in a new window.
 */

#include "defs.h"
#include <stdio.h>

extern char *breakout();

void
do_refs()
{
    char str[256];
    char *srch;
    char *file;
    char *estr;
    long len;
    int bcnt = 10;
    register short i, j;
    short slen, elen;
    long xfi, xfj;
    short tmph, tmpw;

    for (i = E.Column; Current[i] == ' '; ++i);     /*  skip spaces     */
    for (j = i	     ; ; ++j) { 		    /*	alpha-num only	*/
	register short c = Current[j];
	if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
	    continue;
	break;
    }
    j -= i;
    if (j > 63)
	j = 63;
    bmov(Current+i, str, j);
    str[j] = 0;
    title("search .refs");
    if (!searchref("s:dme.refs",    str,&srch,&file,&len,&estr) &&
	!searchref("dme.refs",      str,&srch,&file,&len,&estr) &&
	!searchref("df0:s/dme.refs",str,&srch,&file,&len,&estr) &&
	!searchref("df1:s/dme.refs",str,&srch,&file,&len,&estr) &&
	!searchref("df2:s/dme.refs",str,&srch,&file,&len,&estr) &&
	!searchref("df3:s/dme.refs",str,&srch,&file,&len,&estr)
    ) {
	title("Reference not found");
	return;
    }
    title("search file");
    slen = strlen(srch);
    if (estr)
	elen = strlen(estr);
    if (xfi = xfopen(file, "r", 4096)) {
	short lenstr;
	while ((lenstr = xefgets(xfi, str, 256)) >= 0) {
	    if (strncmp(str, srch, slen) == 0) {
		title("load..");
		if (xfj = xfopen("t:dme_ref", "w", 1024)) {
		    tmph = 0;
		    tmpw = 0;
		    do {
			if (lenstr > tmpw)
			    tmpw = strlen(str);
			++tmph;
			xfwrite(xfj, str, strlen(str));
			xfwrite(xfj, "\n", 1);
			if (estr && strncmp(str,estr,elen) == 0)
			    break;
			--len;
		    } while ((lenstr=xefgets(xfi, str, 256)) >= 0 && len);
		    xfclose(xfj);
		    if (tmph > 23)
			tmph = 23;
		    if (tmpw > 80)
			tmpw = 80;
		    sprintf(str, "tmpheight %ld tmpwidth %ld newwindow newfile t:dme_ref", (tmph<<3)+16, (tmpw<<3)+16);
		    do_command(str);
		    unlink("t:dme_ref");
		} else {
		    title("Unable to open t:dme_ref for write");
		}
		xfclose(xfi);
		free(srch);
		free(file);
		if (estr)
		    free(estr);
		return;
	    }
	    if (--bcnt == 0) {	    /* check break every so so	*/
		bcnt = 50;
		if (breakcheck())
		    break;
	    }
	}
	xfclose(xfi);
	title("Search failed");
    } else {
	title("Unable to open sub document");
    }
    free(srch);
    free(file);
    if (estr)
	free(estr);
}

/*
 *  Reference file format:
 *
 *  `key' `lines' `file' `searchstring'
 *
 *  where `lines' can be a string instead ... like a read-until, otherwise
 *  the number of lines to read from the reference.
 */

searchref(file, find, psstr, pfile, plines, pestr)
char *file, *find;
char **psstr, **pfile, **pestr;
long *plines;
{
    long xfi;
    char buf[256];
    char *ptr, *base;
    char quoted;

    mountrequest(0);
    if (xfi = xfopen(file, "r", 4096)) {
	while (xefgets(xfi,(base=buf), 256) >= 0) {
	    ptr = breakout(&base, &quoted);
	    if (ptr && strcmp(ptr, find) == 0) {
		if (ptr = breakout(&base, &quoted)) {
		    *pestr = NULL;
		    *plines = atoi(ptr);
		    if (*plines == 0) {
			*pestr = (char *)malloc(strlen(ptr)+1);
			strcpy(*pestr, ptr);
		    }
		    if (ptr = breakout(&base, &quoted)) {
			*pfile = (char *)malloc(strlen(ptr)+1);
			strcpy(*pfile, ptr);
			if (ptr = breakout(&base, &quoted)) {
			    *psstr = (char *)malloc(strlen(ptr)+1);
			    strcpy(*psstr, ptr);
			    xfclose(xfi);
			    mountrequest(1);
			    return(1);
			}
			free(*pfile);
		    }
		    if (pestr)
			free (*pestr);
		}
	    }
	}
	xfclose(xfi);
    }
    mountrequest(1);
    return(0);
}


