home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff284.lzh
/
Dme
/
src
/
refs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-27
|
9KB
|
419 lines
/*
* 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>
#define PEN struct _PEN
PEN {
MNODE Node;
char *path;
};
extern char *breakout();
MLIST PBase; /* special DME paths */
/*
* Special DME paths for REF and CTAGS
*/
#ifndef NO_DO2
void
do_addpath()
{
register PEN *pen;
register short len = strlen(av[1]);
for (pen = (PEN *)PBase.mlh_Head; pen->Node.mln_Succ; pen = (PEN *)pen->Node.mln_Succ) {
if (strcmp(av[1], pen->path) == 0)
return;
}
if (pen = malloc(sizeof(PEN)+len+2)) {
pen->path = (char *)(pen + 1);
strcpy(pen->path, av[1]);
switch(pen->path[len-1]) {
case ':':
case '/':
break;
default:
strcat(pen->path, "/");
}
}
AddTail((LIST *)&PBase, (NODE *)pen);
}
void
do_rempath()
{
register PEN *pen, *npen;
for (pen = (PEN *)PBase.mlh_Head; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
if (WildCmp(av[1], pen->path)) {
Remove((NODE *)pen);
free(pen);
}
}
}
#endif
#ifndef NO_DO_CTAGS
/*
* Implement ctags
*/
void
do_ctags()
{
char str[64];
char path[128];
char buf[128];
char sbuf[128];
short xlen;
short slen;
short dbaselen;
long oldlock = CurrentDir(Ep->dirlock);
ED *ed;
{
register short i, j;
for (i = Ep->Column; Current[i] == ' '; ++i);
for (j = i; ; ++j) {
register short c = Current[j];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'))
continue;
break;
}
j -= i;
if (j > 63)
j = 63;
BMov(Current+i, str, j);
str[j] = 0;
xlen = j;
}
if (!Ep->iconmode)
title("search tags");
{
void *xfi;
PEN *pen, *npen;
register long i;
register short j, len;
dbaselen = dirpart(Ep->Name);
BMov(Ep->Name, path, dbaselen);
strcpy(path+dbaselen, "tags");
/*
* Note: pen not used first pass and set to list head, so next
* pass it will be the first element.
*
* Note2: The file path depends on several factors. (1) tags in
* 'current' directory, use path to name of current window.
* (2) tags in directory in DME special path, use special
* path. (3) tag entry is a full path name, override
* previous directories.
*/
for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
mountrequest(0);
if (xfi = xfopen(path, "r", 4096)) {
mountrequest(1);
while ((len = xefgets(xfi, buf, 128)) >= 0) {
for (j = 0; buf[j] && buf[j] != ' '; ++j);
if (j == 0 || buf[0] == '#')
continue;
if (j == xlen && strncmp(str, buf, j) == 0) {
while (buf[j] == ' ')
++j;
/*
* Extract the file name into str. If the
* filename does not contain an absolute path,
* prepend it with such.
*/
{
char prep = 1;
for (i = 0; buf[j] && buf[j] != ' '; ++i, ++j) {
str[i] = buf[j];
if (str[i] == ':')
prep = 0;
}
if (prep) {
BMov(str, str + dbaselen, i);
BMov(path, str, dbaselen);
i += dbaselen;
}
}
str[i] = 0;
while (buf[j] && buf[j] != '^') /* SEARCH ARG */
++j;
xfclose(xfi);
if (buf[j] != '^') {
title("tags error");
goto done;
}
++j;
strcpy(sbuf, buf+j);
slen = strlen(sbuf);
if ((ed = finded(str, 0)) == NULL) {
strcpy(buf, "newwindow newfile ");
strcat(buf, str);
do_command(buf);
ed = finded(str, 0);
} else {
WindowToFront(ed->Win);
ActivateWindow(ed->Win);
}
if (ed == NULL) {
title("unable to load file");
goto done;
}
text_switch(ed->Win);
if (Ep->iconmode)
uniconify();
else
text_cursor(0);
for (i = 0; i < ed->Lines; ++i) {
if (strncmp(ed->List[i], sbuf, slen) == 0)
break;
}
sprintf(buf, "first goto %ld", i+1);
do_command(buf);
goto done;
}
}
xfclose(xfi);
} else {
mountrequest(1);
}
if (npen->Node.mln_Succ) {
strcpy(path, npen->path);
strcat(path, "tags");
dbaselen = strlen(npen->path);
}
}
title("tag not found");
}
done:
CurrentDir(oldlock);
}
#endif
#ifndef NO_DO_REFS
/*
* Implement references
*/
void
do_refs()
{
char str[256];
char path[128];
char *srch;
char *file;
char *estr;
long len;
int bcnt = 10;
register short i, j;
short slen, elen;
void *xfi, *xfj;
short tmph, tmpw;
long oldlock = CurrentDir(Ep->dirlock);
for (i = Ep->Column; Current[i] == ' '; ++i); /* skip spaces */
for (j = i ; ; ++j) {
if (Current[j] && Current[j] != ' ')
continue;
break;
}
j -= i;
if (j > 63)
j = 63;
BMov(Current+i, str, j);
str[j] = 0;
title("search .refs");
{
register PEN *pen;
register PEN *npen;
strcpy(path, "dme.refs");
mountrequest(0);
for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
if (searchref(path, str, &srch, &file, &len, &estr)) {
mountrequest(1);
goto found;
}
if (npen->Node.mln_Succ) {
strcpy(path, npen->path);
strcat(path, "dme.refs");
}
}
title("Reference not found");
mountrequest(1);
goto done;
}
found:
title("search file");
slen = strlen(srch);
if (estr)
elen = strlen(estr);
if (xfi = xfopen(file, "r", 4096)) {
short lenstr;
if (srch[0] == '@' && srch[1] == '@') {
xfseek(xfi, atoi(srch+2));
if ((lenstr = xefgets(xfi, str, 256)) >= 0)
goto autoseek;
}
while ((lenstr = xefgets(xfi, str, 256)) >= 0) {
if (strncmp(str, srch, slen) == 0) {
autoseek:
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 > 10)
tmph = 10;
if (tmpw > 80)
tmpw = 80;
sprintf(str, "tmpheight %ld tmpwidth %ld newwindow newfile t:dme_ref", (tmph<<3)+24, (tmpw<<3)+24);
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);
goto done;
}
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);
done:
CurrentDir(oldlock);
}
/*
* 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;
{
void *xfi;
char buf[256];
char *ptr, *base;
char *b1, *b2, *b3, *b4;
char quoted;
if (xfi = xfopen(file, "r", 4096)) {
while (xefgets(xfi,(base=buf), 256) >= 0) {
if (buf[0]=='#')
continue;
ptr = breakout(&base, "ed, &b1);
if (ptr && *ptr && strncmp(ptr, find, strlen(ptr)) == 0) {
if (ptr = breakout(&base, "ed, &b2)) {
*pestr = NULL;
*plines = atoi(ptr);
if (*plines == 0) {
*pestr = (char *)malloc(strlen(ptr)+1);
strcpy(*pestr, ptr);
}
if (ptr = breakout(&base, "ed, &b3)) {
*pfile = (char *)malloc(strlen(ptr)+1);
strcpy(*pfile, ptr);
if (ptr = breakout(&base, "ed, &b4)) {
*psstr = (char *)malloc(strlen(ptr)+1);
strcpy(*psstr, ptr);
xfclose(xfi);
if (b1) free(b1);
if (b2) free(b2);
if (b3) free(b3);
if (b4) free(b4);
return(1);
}
free(*pfile);
if (b4)
free(b4);
}
if (pestr)
free (*pestr);
if (b3)
free (b3);
}
if (b2)
free(b2);
}
if (b1)
free(b1);
}
xfclose(xfi);
}
return(0);
}
#endif
#ifndef NO_DO_CTAGS
dirpart(str)
register char *str;
{
register short i;
for (i = strlen(str) - 1; i >= 0; --i) {
if (str[i] == '/' || str[i] == ':')
break;
}
return(i+1);
}
#endif