home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1821.lha
/
XDME
/
refs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-14
|
11KB
|
619 lines
/******************************************************************************
MODUL
refs.c
DESCRIPTION
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.
NOTES
BUGS
TODO
EXAMPLES
SEE ALSO
INDEX
HISTORY
25. Nov 1992 ada created
******************************************************************************/
/**************************************
Includes
**************************************/
#include "defs.h"
/**************************************
Globale Variable
**************************************/
Prototype void do_addpath (void);
Prototype void do_rempath (void);
Prototype void do_refctags (void);
Prototype void do_ctags (void);
Prototype void do_refs (void);
Prototype int searchref (char *, char *, char **, char **, int *, char **);
Prototype int dirpart (char *);
Prototype LIST PBase;
LIST PBase; /* special XDME paths */
/**************************************
Interne Defines & Strukturen
**************************************/
typedef struct _PEN
{
NODE Node;
char path[1];
} PEN;
/**************************************
Interne Variable
**************************************/
/**************************************
Interne Prototypes
**************************************/
void path_init (void);
__autoinit void path_init (void)
{
PEN * pen;
NewList ((struct List *)&PBase);
if (pen = malloc (sizeof(PEN)))
{
*pen->path = 0;
pen->Node.ln_Name = pen->path;
AddTail ((struct List *)&PBase, (struct Node *)pen);
}
} /* path_init */
/*
* Special XDME paths for REF and CTAGS
*/
void do_addpath (void)
{
PEN * pen;
short len = strlen (av[1]);
for (pen = (PEN *)GetHead(&PBase); pen; pen=(PEN *)GetSucc((struct Node *)pen))
{
if (stricmp (av[1], pen->path) == 0)
return;
}
if (pen = malloc (sizeof (PEN) + len))
strcpy (pen->path, av[1]);
AddTail ((LIST *) & PBase, (NODE *) pen);
pen->Node.ln_Name = pen->path;
} /* do_addpath */
void do_rempath (void)
{
PEN * pen;
for (pen = (PEN *)GetHead(&PBase); pen; pen = (PEN *)GetSucc((struct Node *)pen))
{
if (!stricmp (av[1], pen->path))
{
Remove ((NODE *) pen);
free (pen);
}
}
} /* do_rempath */
void do_refctags (void)
{
BOOL requester;
BOOL title;
requester = globalflags.NoRequest;
title = globalflags.Showtitle;
globalflags.NoRequest = TRUE;
globalflags.Showtitle = FALSE;
do_ctags ();
if (globalflags.Abortcommand)
do_refs ();
globalflags.NoRequest = requester;
globalflags.Showtitle = title;
if (globalflags.Abortcommand)
error ("%s:\nCannot find anything about\n`%s'.", av[0],
((av[1] != NULL) ? (char *)av[1] : current_word ()));
} /* do_refctags */
/*
* Implement ctags
*/
void do_ctags (void)
{
char str[64];
char path[128];
char buf[128];
char sbuf[128];
short xlen;
short slen;
short dbaselen;
BPTR oldlock = CurrentDir (Ep->dirlock);
ED * ed;
if (av[1] != NULL)
{
strcpy (str, av[1]);
xlen = strlen (str);
} else
{
strcpy (str, current_word ());
xlen = strlen (str);
}
if (!Ep->iconmode)
title ("search tags");
{
FILE * fi;
PEN * pen;
long i;
short j,
len;
/*
* 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 XDME special path, use special
* path. (3) tag entry is a full path name, override
* previous directories.
*/
mountrequest (0);
for (pen=(PEN *)GetHead(&PBase); pen;
pen=(PEN *)GetSucc((struct Node *)pen))
{
strcpy (path, pen->path);
AddPart (path, "tags", sizeof(path));
dbaselen = strlen (pen->path);
if (fi = fopen (path, "r"))
{
mountrequest (1);
while ((len = xefgets (fi, 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)
{
movmem (str, str + dbaselen, i);
movmem (path, str, dbaselen);
i += dbaselen;
}
}
str[i] = 0;
while (buf[j] && buf[j] != '^') /* SEARCH ARG */
++j;
fclose (fi);
if (buf[j] != '^')
{
error ("ctags:\nError in tags-file");
goto done;
}
++j; /* Skip ^ */
/* UN*X FIX: Dme works for Aztec ctags, which has the format: */
/* <tag> <file> /^<pattern> */
/* However, ctags under UN*X has the following format: */
/* <tag> <file> /^<pattern>[$]/ */
/* We just ignore the '$' and '/' so that both foramts work */
/* Thomas Rolfs 27/3/91 */
{
short i = 0;
while (buf[j] && buf[j] != '$' && buf[j] != '/')
{
sbuf[i++] = buf[j++];
}
sbuf[i] = 0;
}
/* End of fix. */
slen = strlen (sbuf);
if ((ed = finded (str, 0)) == NULL)
{
strcpy (buf, "newwindow newfile `");
strcat (buf, str);
strcat (buf, "'");
do_command (buf);
/* remove path */
strcpy (str, FilePart (str));
ed = finded (str, 0);
} else
{
WindowToFront (ed->win);
ActivateWindow (ed->win);
}
if (ed == NULL)
{
error ("ctags:\nunable to load file\n`%s'", str);
goto done;
}
switch_ed (ed);
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);
text_cursor (1); /* turn cursor on */
goto done;
}
}
fclose (fi);
mountrequest (0);
}
}
error ("ctags:\ntag `%s'\nnot found", str);
mountrequest (1);
}
done:
CurrentDir (oldlock);
} /* do_ctags */
/*
* Implement references
*/
void do_refs (void)
{
static char str[MAXLINELEN];
static char tmpfile[128];
static char path[128];
char * srch;
char * file;
char * estr;
long len;
int bcnt = 10;
short slen,
elen;
FILE * fi,
* fj;
short tmph,
tmpw;
BPTR oldlock = CurrentDir (Ep->dirlock);
if (av[1] != NULL)
{
strcpy (str, av[1]);
}
else
strcpy (str, current_word ());
strcpy (tmpfile, "t:ref_");
strncat (tmpfile, str, sizeof (tmpfile) - 32);
title ("search .refs");
{
PEN * pen;
mountrequest (0);
/* search all paths */
for (pen = (PEN *)GetHead(&PBase); pen; pen=(PEN *)GetSucc(pen))
{
strcpy (path, pen->path);
AddPart (path, "dme.refs", sizeof (path));
if (searchref (path, str, &srch, &file, &len, &estr))
{
mountrequest (1);
goto found;
}
}
error ("refs:\nReference `%s'\nnot found", str);
mountrequest (1);
goto done;
}
found:
title ("search file");
slen = strlen (srch);
if (estr)
elen = strlen (estr);
fi = fopen (file, "r");
if (fi == NULL)
{ /* try using path prefix */
strcpy (str, path);
strcpy (str + strlen (str) - 8, file);
fi = fopen (str, "r");
}
if (fi)
{
short lenstr;
if (srch[0] == '@' && srch[1] == '@')
{
fseek (fi, atoi (srch + 2), 0);
if ((lenstr = xefgets (fi, str, MAXLINELEN)) >= 0)
goto autoseek;
}
while ((lenstr = xefgets (fi, str, MAXLINELEN)) >= 0)
{
if (strncmp (str, srch, slen) == 0)
{
autoseek:
title ("load..");
if (fj = fopen (tmpfile, "w"))
{
tmph = 0;
tmpw = 0;
do
{
if (lenstr > tmpw)
tmpw = strlen (str);
tmph ++;
fputs (str, fj);
fputc ('\n', fj);
if (estr && strncmp (str, estr, elen) == 0)
break;
len --;
}
while ((lenstr = xefgets (fi, str, MAXLINELEN)) >= 0 && len);
fclose (fj);
if (tmph > 10)
tmph = 10;
if (tmpw > 80)
tmpw = 80;
sprintf (str, "openwindow +0+0+%d+%d newfile %s", (tmpw << 3) + 24, (tmph << 3) + 24, tmpfile);
do_command (str);
text_cursor (1); /* turn cursor on */
unlink (tmpfile);
} else
{
error ("refs:\nUnable to open\n`%s'\nfor write", tmpfile);
}
fclose (fi);
free (srch);
free (file);
if (estr)
free (estr);
goto done;
}
if (--bcnt == 0)
{ /* check break every so so */
bcnt = 50;
if (breakcheck ())
break;
}
}
fclose (fi);
error ("refs:\nSearch for `%s'\nfailed", str);
} else
{
error ("refs:\nUnable to open\nsub document");
}
free (srch);
free (file);
if (estr)
free (estr);
done:
CurrentDir (oldlock);
} /* do_refs */
/*
* 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.
*/
int searchref (char * file, char * find, char ** psstr, char ** pfile, int * plines, char **pestr)
{
FILE * fi;
char buf[MAXLINELEN];
char * ptr,
* base;
char * b1,
* b2,
* b3,
* b4;
char quoted;
/* short findlen = strlen(find); TODO */
if (fi = fopen (file, "r"))
{
while (xefgets (fi, (base = buf), MAXLINELEN) >= 0)
{
if (buf[0] == '#')
continue;
ptr = breakout (&base, "ed, &b1);
/* TODO if (ptr && *ptr && strncmp(ptr, find, findlen) == 0) */
if (ptr && *ptr && strcmp (ptr, find) == 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);
fclose (fi);
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);
}
fclose (fi);
}
return (0);
} /* searchref */
int dirpart (char * str)
{
short i;
for (i = strlen (str) - 1; i >= 0; --i)
{
if (str[i] == '/' || str[i] == ':')
break;
}
return (i + 1);
} /* dirpart */
/******************************************************************************
***** ENDE refs.c
******************************************************************************/