home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / text / jed / src / jed.lha / makerefs.c < prev    next >
C/C++ Source or Header  |  1992-11-10  |  7KB  |  355 lines

  1.  
  2. /*
  3.  * MAKEREFS.C
  4.  * (c)1992 J.Harper
  5.  *
  6.  * Creates reference entries from autodoc style documents, C source files and
  7.  * C header files.
  8.  *
  9.  * usage: makerefs [options] reffile srcfiles...
  10.  *
  11.  * options,
  12.  *    -new    don't append to reffile - create it.
  13.  *    -full    fully expand file names in ref entries
  14.  *
  15.  * what it makes refs for,
  16.  *    *.c    function definitions
  17.  *    *.h    structure definitions
  18.  *    *    anything else - looks for aaaa/bbbb type refs (autodocs, etc)
  19.  */
  20.  
  21. #include <exec/types.h>
  22. #include <exec/libraries.h>
  23. #include <dos/dos.h>
  24. #include <dos/dosasl.h>
  25. #include <clib/dos_protos.h>
  26.  
  27. #include <ctype.h>
  28. #include <string.h>
  29.  
  30. #define DOS36_MSG "Need dos.library V36+\n"
  31. #define NAME_LEN 300
  32.  
  33. extern struct Library *DOSBase;
  34.  
  35. BOOL NewRefs =     FALSE; /* -new */
  36. BOOL FullName =     FALSE; /* -full */
  37.  
  38. UWORD    main        (UWORD, STRPTR *);
  39. VOID    makerefs    (BPTR, struct AnchorPath *);
  40. VOID    scanheader  (BPTR, BPTR, STRPTR);
  41. VOID    scandoc        (BPTR, BPTR, STRPTR);
  42. VOID    scansource  (BPTR, BPTR, STRPTR);
  43. VOID    copyrefname (BPTR, STRPTR);
  44. LONG    index        (STRPTR, STRPTR);
  45. BOOL    mystrcmp    (STRPTR, STRPTR);
  46. STRPTR    myFGets        (BPTR, STRPTR, LONG);
  47.  
  48. UWORD
  49. main(UWORD argc, STRPTR *argv)
  50. {
  51.     if(DOSBase->lib_Version <= 36)
  52.     {
  53.     Write(Output(), DOS36_MSG, sizeof(DOS36_MSG));
  54.     return(RETURN_WARN);
  55.     }
  56.     else
  57.     {
  58.     if(argc == 1)
  59.     {
  60.         PutStr("usage: makerefs [-new] [-full] reffile srcfiles...\nstandard wildcards are supported.\n");
  61.         return(RETURN_WARN);
  62.     }
  63.     else
  64.     {
  65.         BPTR outfh;
  66.         argc--;
  67.         argv++;
  68.  
  69.         while(**argv == '-')
  70.         {
  71.         if(!(stricmp(*argv, "-new")))
  72.         {
  73.             NewRefs = TRUE;
  74.             argv++;
  75.             argc--;
  76.         }
  77.         else if(!(stricmp(*argv, "-full")))
  78.         {
  79.             FullName = TRUE;
  80.             argv++;
  81.             argc--;
  82.         }
  83.         else
  84.         {
  85.             Printf("makerefs: incorrect argument %s\n", (LONG)*argv);
  86.             return(RETURN_WARN);
  87.         }
  88.         }
  89.         if(outfh = Open(*argv++, NewRefs ? MODE_NEWFILE : MODE_READWRITE))
  90.         {
  91.         argc--;
  92.  
  93.         Seek(outfh, 0, OFFSET_END);
  94.         while(argc--)
  95.         {
  96.             __aligned struct AnchorPath myanc;
  97.             clrmem(&myanc, sizeof(struct AnchorPath));
  98.  
  99.             if(CheckSignal(SIGBREAKF_CTRL_C))
  100.             goto broke;
  101.             if(!(MatchFirst(*argv++, &myanc)))
  102.             {
  103.             makerefs(outfh, &myanc);
  104.             while(!(MatchNext(&myanc)))
  105.             {
  106.                 if(CheckSignal(SIGBREAKF_CTRL_C))
  107.                 goto broke;
  108.                 makerefs(outfh, &myanc);
  109.             }
  110.             }
  111.             if(0)
  112. broke:
  113.             PutStr("^C\n");
  114.             MatchEnd(&myanc);
  115.         }
  116.         Close(outfh);
  117.         return(RETURN_OK);
  118.         }
  119.         else
  120.         {
  121.         Printf("makerefs: can't open %s for output\n", (LONG)argv[-1]);
  122.         return(RETURN_WARN);
  123.         }
  124.     }
  125.     }
  126. }
  127.  
  128. VOID
  129. makerefs(BPTR refs, struct AnchorPath *anc)
  130. {
  131.     UBYTE cdname[NAME_LEN];
  132.     if(GetCurrentDirName(cdname, NAME_LEN))
  133.     {
  134.     BPTR olddir = CurrentDir(anc->ap_Current->an_Lock);
  135.     BPTR fh = Open(anc->ap_Info.fib_FileName, MODE_OLDFILE);
  136.     if(fh)
  137.     {
  138.         UBYTE fullname[NAME_LEN];
  139.         if(NameFromFH(fh, fullname, NAME_LEN))
  140.         {
  141.         STRPTR name;
  142.         if(FullName || mystrcmp(cdname, fullname))
  143.             name = fullname;
  144.         else
  145.         {
  146.             name = fullname + strlen(cdname);
  147.             if((*name == '/') || (*name == ':'))
  148.             name++;
  149.         }
  150.         Printf("Scanning %s...\n", (LONG)anc->ap_Info.fib_FileName);
  151.         FPrintf(refs, "\n# References from %s\n", (LONG)anc->ap_Info.fib_FileName);
  152.  
  153.         if(index(anc->ap_Info.fib_FileName, ".h") != -1)
  154.             scanheader(refs, fh, name);
  155.         else if(index(anc->ap_Info.fib_FileName, ".c") != -1)
  156.             scansource(refs, fh, name);
  157.         else
  158.             scandoc(refs, fh, name);
  159.         }
  160.         Close(fh);
  161.     }
  162.     else
  163.         Printf("makerefs: can't open %s for input\n", (LONG)anc->ap_Info.fib_FileName);
  164.     CurrentDir(olddir);
  165.     }
  166. }
  167.  
  168. /*
  169.  * Needs serious work.
  170.  * currently just finds the structure name and references it in the file,
  171.  * doesn't bother searching for the end.
  172.  * also assumes all structure definitions will be in col #1.
  173.  * in fact this is really crap.
  174.  */
  175. VOID
  176. scanheader(BPTR dstfh, BPTR srcfh, STRPTR fileName)
  177. {
  178.     UBYTE line[256];
  179.     LONG linenum = 0;
  180.     while(FGets(srcfh, line, 255))
  181.     {
  182.     linenum++;
  183.     if(!mystrcmp("struct", line) && isspace(line[6]))
  184.     {
  185.         copyrefname(dstfh, line + 7);
  186.         FPrintf(dstfh, "%s@#%ld@\n", (LONG)fileName, Seek(srcfh, 0, OFFSET_CURRENT) - strlen(line));
  187.     }
  188.     else if(!mystrcmp("typedef", line) && isspace(line[7]) && !mystrcmp("struct", line + 8))
  189.     {
  190.         LONG slinenum = linenum;
  191.         BOOL foundend = FALSE;
  192.         while(!foundend && FGets(srcfh, line, 255))
  193.         {
  194.         linenum++;
  195.         if(!mystrcmp("}", line))
  196.         {
  197.             STRPTR nstart = line + 1;
  198.             while(isspace(*nstart++))
  199.             ;
  200.             nstart--;
  201.             copyrefname(dstfh, nstart);
  202.             FPrintf(dstfh, "%s@^%ld@\n", (LONG)fileName, slinenum);
  203.             foundend = TRUE;
  204.         }
  205.         }
  206.     }
  207.     }
  208. }
  209.  
  210. VOID
  211. scandoc(BPTR dstfh, BPTR srcfh, STRPTR fileName)
  212. {
  213.     UBYTE line[256];
  214.     BOOL gotline = FALSE;
  215.     while(gotline || myFGets(srcfh, line, 255))
  216.     {
  217.     LONG i;
  218.     gotline = FALSE;
  219.     if((i = index(line, "/")) != -1)
  220.     {
  221.         UBYTE name[100];
  222.         LONG j = ++i;
  223.         LONG linelen = strlen(line);
  224.         while((isalnum(line[j])) || (line[j] == '_'))
  225.         j++;
  226.         line[j++] = 0;
  227.         if(index(line + j, line) != -1)
  228.         {
  229.         LONG refstart = Seek(srcfh, 0, OFFSET_CURRENT) - linelen;
  230.         LONG refend = 0;
  231.         Printf("\tMade reference to %s\n", (LONG)line + i);
  232.         FPrintf(dstfh, "@%s@%s@", (LONG)line + i, fileName);
  233.         while((refend < refstart) && myFGets(srcfh, line, 255))
  234.         {
  235.             if(!refend)
  236.             {
  237.             if(isspace(line[0]))
  238.                 refend = -1;
  239.             }
  240.             else
  241.             {
  242.             if(!isspace(line[0]))
  243.                 refend = Seek(srcfh, 0, OFFSET_CURRENT) - strlen(line);
  244.             }
  245.         }
  246.         if(refend < refstart)
  247.             refend = Seek(srcfh, 0, OFFSET_CURRENT);
  248.         FPrintf(dstfh, "#%ld/#%ld@\n", refstart, refend);
  249.         gotline = TRUE;
  250.         }
  251.     }
  252.     }
  253. }
  254.  
  255. VOID
  256. scansource(BPTR dstfh, BPTR srcfh, STRPTR fileName)
  257. {
  258.     UBYTE line1[256];
  259.     UBYTE line2[256];
  260.     STRPTR l1, l2;
  261.  
  262.     l1 = line1;
  263.     l2 = line2;
  264.     if(FGets(srcfh, l1, 255))
  265.     {
  266.     while(FGets(srcfh, l2, 255))
  267.     {
  268.         LONG par1;
  269.         STRPTR temp;
  270.         if(((par1 = index(l1, "(")) != -1) && (index(l1, ")") > par1) && (*l2 == '{'))
  271.         {
  272.         STRPTR ref = l1;
  273.         copyrefname(dstfh, l1);
  274.         while(*ref++ != '(')
  275.             ;
  276.         *ref = 0;
  277.         FPrintf(dstfh, "%s@%s@\n", (LONG)fileName, l1);
  278.         }
  279.         temp = l1;
  280.         l1 = l2;
  281.         l2 = temp;
  282.     }
  283.     }
  284. }
  285.  
  286. VOID
  287. copyrefname(BPTR fh, STRPTR name)
  288. {
  289.     UBYTE copy[100];
  290.     WORD len = 0;
  291.     UBYTE c;
  292.     while((isalnum(c = name[len++])) || (c == '_'))
  293.     ;
  294.     len--;
  295.     memcpy(copy, name, len);
  296.     copy[len] = 0;
  297.     Printf("\tMade reference to %s\n", (LONG)copy);
  298.     FPrintf(fh, "@%s@", (LONG)copy);
  299. }
  300.  
  301. /*
  302.  * Returns the offset that pattern occurs in string, or -1 if it doesn't
  303.  */
  304. LONG
  305. index(STRPTR string, STRPTR pattern)
  306. {
  307.     STRPTR current = string;
  308.     while(*current)
  309.     {
  310.     if(!(mystrcmp(pattern, current)))
  311.         return((LONG)(current - string));
  312.     current++;
  313.     }
  314.     return(-1L);
  315. }
  316.  
  317. /*
  318.  * strcmp() type function but string2 doesn't have to end when string1 does to
  319.  * match.
  320.  */
  321. BOOL
  322. mystrcmp(STRPTR string1, STRPTR string2)
  323. {
  324.     while(*string1)
  325.     {
  326.     if((*string1++) != (*string2++))
  327.         return(1);
  328.     }
  329.     return(0);
  330. }
  331.  
  332. /*
  333.  * FGets() style function but also takes '\f' as the end of a line.
  334.  */
  335. STRPTR
  336. myFGets(BPTR fh, STRPTR dst, LONG max)
  337. {
  338.     LONG i;
  339.     UBYTE c;
  340.     for(i = 0; (i < max) && ((c = (UBYTE)FGetC(fh)) != -1); i++)
  341.     {
  342.     dst[i] = c;
  343.     if((c == '\n') || (c == '\f'))
  344.     {
  345.         i++;
  346.         break;
  347.     }
  348.     }
  349.     dst[i] = 0;
  350.     if(!i || (c == -1))
  351.     return(NULL);
  352.     return(dst);
  353. }
  354.  
  355.