home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
text
/
jed
/
src
/
jed.lha
/
makerefs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-10
|
7KB
|
355 lines
/*
* MAKEREFS.C
* (c)1992 J.Harper
*
* Creates reference entries from autodoc style documents, C source files and
* C header files.
*
* usage: makerefs [options] reffile srcfiles...
*
* options,
* -new don't append to reffile - create it.
* -full fully expand file names in ref entries
*
* what it makes refs for,
* *.c function definitions
* *.h structure definitions
* * anything else - looks for aaaa/bbbb type refs (autodocs, etc)
*/
#include <exec/types.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <dos/dosasl.h>
#include <clib/dos_protos.h>
#include <ctype.h>
#include <string.h>
#define DOS36_MSG "Need dos.library V36+\n"
#define NAME_LEN 300
extern struct Library *DOSBase;
BOOL NewRefs = FALSE; /* -new */
BOOL FullName = FALSE; /* -full */
UWORD main (UWORD, STRPTR *);
VOID makerefs (BPTR, struct AnchorPath *);
VOID scanheader (BPTR, BPTR, STRPTR);
VOID scandoc (BPTR, BPTR, STRPTR);
VOID scansource (BPTR, BPTR, STRPTR);
VOID copyrefname (BPTR, STRPTR);
LONG index (STRPTR, STRPTR);
BOOL mystrcmp (STRPTR, STRPTR);
STRPTR myFGets (BPTR, STRPTR, LONG);
UWORD
main(UWORD argc, STRPTR *argv)
{
if(DOSBase->lib_Version <= 36)
{
Write(Output(), DOS36_MSG, sizeof(DOS36_MSG));
return(RETURN_WARN);
}
else
{
if(argc == 1)
{
PutStr("usage: makerefs [-new] [-full] reffile srcfiles...\nstandard wildcards are supported.\n");
return(RETURN_WARN);
}
else
{
BPTR outfh;
argc--;
argv++;
while(**argv == '-')
{
if(!(stricmp(*argv, "-new")))
{
NewRefs = TRUE;
argv++;
argc--;
}
else if(!(stricmp(*argv, "-full")))
{
FullName = TRUE;
argv++;
argc--;
}
else
{
Printf("makerefs: incorrect argument %s\n", (LONG)*argv);
return(RETURN_WARN);
}
}
if(outfh = Open(*argv++, NewRefs ? MODE_NEWFILE : MODE_READWRITE))
{
argc--;
Seek(outfh, 0, OFFSET_END);
while(argc--)
{
__aligned struct AnchorPath myanc;
clrmem(&myanc, sizeof(struct AnchorPath));
if(CheckSignal(SIGBREAKF_CTRL_C))
goto broke;
if(!(MatchFirst(*argv++, &myanc)))
{
makerefs(outfh, &myanc);
while(!(MatchNext(&myanc)))
{
if(CheckSignal(SIGBREAKF_CTRL_C))
goto broke;
makerefs(outfh, &myanc);
}
}
if(0)
broke:
PutStr("^C\n");
MatchEnd(&myanc);
}
Close(outfh);
return(RETURN_OK);
}
else
{
Printf("makerefs: can't open %s for output\n", (LONG)argv[-1]);
return(RETURN_WARN);
}
}
}
}
VOID
makerefs(BPTR refs, struct AnchorPath *anc)
{
UBYTE cdname[NAME_LEN];
if(GetCurrentDirName(cdname, NAME_LEN))
{
BPTR olddir = CurrentDir(anc->ap_Current->an_Lock);
BPTR fh = Open(anc->ap_Info.fib_FileName, MODE_OLDFILE);
if(fh)
{
UBYTE fullname[NAME_LEN];
if(NameFromFH(fh, fullname, NAME_LEN))
{
STRPTR name;
if(FullName || mystrcmp(cdname, fullname))
name = fullname;
else
{
name = fullname + strlen(cdname);
if((*name == '/') || (*name == ':'))
name++;
}
Printf("Scanning %s...\n", (LONG)anc->ap_Info.fib_FileName);
FPrintf(refs, "\n# References from %s\n", (LONG)anc->ap_Info.fib_FileName);
if(index(anc->ap_Info.fib_FileName, ".h") != -1)
scanheader(refs, fh, name);
else if(index(anc->ap_Info.fib_FileName, ".c") != -1)
scansource(refs, fh, name);
else
scandoc(refs, fh, name);
}
Close(fh);
}
else
Printf("makerefs: can't open %s for input\n", (LONG)anc->ap_Info.fib_FileName);
CurrentDir(olddir);
}
}
/*
* Needs serious work.
* currently just finds the structure name and references it in the file,
* doesn't bother searching for the end.
* also assumes all structure definitions will be in col #1.
* in fact this is really crap.
*/
VOID
scanheader(BPTR dstfh, BPTR srcfh, STRPTR fileName)
{
UBYTE line[256];
LONG linenum = 0;
while(FGets(srcfh, line, 255))
{
linenum++;
if(!mystrcmp("struct", line) && isspace(line[6]))
{
copyrefname(dstfh, line + 7);
FPrintf(dstfh, "%s@#%ld@\n", (LONG)fileName, Seek(srcfh, 0, OFFSET_CURRENT) - strlen(line));
}
else if(!mystrcmp("typedef", line) && isspace(line[7]) && !mystrcmp("struct", line + 8))
{
LONG slinenum = linenum;
BOOL foundend = FALSE;
while(!foundend && FGets(srcfh, line, 255))
{
linenum++;
if(!mystrcmp("}", line))
{
STRPTR nstart = line + 1;
while(isspace(*nstart++))
;
nstart--;
copyrefname(dstfh, nstart);
FPrintf(dstfh, "%s@^%ld@\n", (LONG)fileName, slinenum);
foundend = TRUE;
}
}
}
}
}
VOID
scandoc(BPTR dstfh, BPTR srcfh, STRPTR fileName)
{
UBYTE line[256];
BOOL gotline = FALSE;
while(gotline || myFGets(srcfh, line, 255))
{
LONG i;
gotline = FALSE;
if((i = index(line, "/")) != -1)
{
UBYTE name[100];
LONG j = ++i;
LONG linelen = strlen(line);
while((isalnum(line[j])) || (line[j] == '_'))
j++;
line[j++] = 0;
if(index(line + j, line) != -1)
{
LONG refstart = Seek(srcfh, 0, OFFSET_CURRENT) - linelen;
LONG refend = 0;
Printf("\tMade reference to %s\n", (LONG)line + i);
FPrintf(dstfh, "@%s@%s@", (LONG)line + i, fileName);
while((refend < refstart) && myFGets(srcfh, line, 255))
{
if(!refend)
{
if(isspace(line[0]))
refend = -1;
}
else
{
if(!isspace(line[0]))
refend = Seek(srcfh, 0, OFFSET_CURRENT) - strlen(line);
}
}
if(refend < refstart)
refend = Seek(srcfh, 0, OFFSET_CURRENT);
FPrintf(dstfh, "#%ld/#%ld@\n", refstart, refend);
gotline = TRUE;
}
}
}
}
VOID
scansource(BPTR dstfh, BPTR srcfh, STRPTR fileName)
{
UBYTE line1[256];
UBYTE line2[256];
STRPTR l1, l2;
l1 = line1;
l2 = line2;
if(FGets(srcfh, l1, 255))
{
while(FGets(srcfh, l2, 255))
{
LONG par1;
STRPTR temp;
if(((par1 = index(l1, "(")) != -1) && (index(l1, ")") > par1) && (*l2 == '{'))
{
STRPTR ref = l1;
copyrefname(dstfh, l1);
while(*ref++ != '(')
;
*ref = 0;
FPrintf(dstfh, "%s@%s@\n", (LONG)fileName, l1);
}
temp = l1;
l1 = l2;
l2 = temp;
}
}
}
VOID
copyrefname(BPTR fh, STRPTR name)
{
UBYTE copy[100];
WORD len = 0;
UBYTE c;
while((isalnum(c = name[len++])) || (c == '_'))
;
len--;
memcpy(copy, name, len);
copy[len] = 0;
Printf("\tMade reference to %s\n", (LONG)copy);
FPrintf(fh, "@%s@", (LONG)copy);
}
/*
* Returns the offset that pattern occurs in string, or -1 if it doesn't
*/
LONG
index(STRPTR string, STRPTR pattern)
{
STRPTR current = string;
while(*current)
{
if(!(mystrcmp(pattern, current)))
return((LONG)(current - string));
current++;
}
return(-1L);
}
/*
* strcmp() type function but string2 doesn't have to end when string1 does to
* match.
*/
BOOL
mystrcmp(STRPTR string1, STRPTR string2)
{
while(*string1)
{
if((*string1++) != (*string2++))
return(1);
}
return(0);
}
/*
* FGets() style function but also takes '\f' as the end of a line.
*/
STRPTR
myFGets(BPTR fh, STRPTR dst, LONG max)
{
LONG i;
UBYTE c;
for(i = 0; (i < max) && ((c = (UBYTE)FGetC(fh)) != -1); i++)
{
dst[i] = c;
if((c == '\n') || (c == '\f'))
{
i++;
break;
}
}
dst[i] = 0;
if(!i || (c == -1))
return(NULL);
return(dst);
}