home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1821.lha / XDME / refs.c < prev    next >
C/C++ Source or Header  |  1993-03-14  |  11KB  |  619 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     refs.c
  5.  
  6.     DESCRIPTION
  7.     Bringup a cross reference editor window.  The file S:dme.refs and
  8.     dme.refs in the current directory are searched for the reference.
  9.     If found, the file specified is searched and the segment specified
  10.     loaded as a new file in a new window.
  11.  
  12.     NOTES
  13.  
  14.     BUGS
  15.  
  16.     TODO
  17.  
  18.     EXAMPLES
  19.  
  20.     SEE ALSO
  21.  
  22.     INDEX
  23.  
  24.     HISTORY
  25.     25. Nov 1992    ada created
  26.  
  27. ******************************************************************************/
  28.  
  29. /**************************************
  30.         Includes
  31. **************************************/
  32. #include "defs.h"
  33.  
  34.  
  35. /**************************************
  36.         Globale Variable
  37. **************************************/
  38. Prototype void do_addpath  (void);
  39. Prototype void do_rempath  (void);
  40. Prototype void do_refctags (void);
  41. Prototype void do_ctags    (void);
  42. Prototype void do_refs       (void);
  43. Prototype int searchref    (char *, char *, char **, char **, int *, char **);
  44. Prototype int dirpart       (char *);
  45.  
  46. Prototype LIST PBase;
  47.  
  48. LIST    PBase;            /*  special XDME paths     */
  49.  
  50.  
  51. /**************************************
  52.       Interne Defines & Strukturen
  53. **************************************/
  54. typedef struct _PEN
  55. {
  56.     NODE    Node;
  57.     char    path[1];
  58. } PEN;
  59.  
  60.  
  61. /**************************************
  62.         Interne Variable
  63. **************************************/
  64.  
  65.  
  66. /**************************************
  67.        Interne Prototypes
  68. **************************************/
  69. void path_init (void);
  70.  
  71.  
  72. __autoinit void path_init (void)
  73. {
  74.     PEN * pen;
  75.  
  76.     NewList ((struct List *)&PBase);
  77.  
  78.     if (pen = malloc (sizeof(PEN)))
  79.     {
  80.     *pen->path = 0;
  81.     pen->Node.ln_Name = pen->path;
  82.  
  83.     AddTail ((struct List *)&PBase, (struct Node *)pen);
  84.     }
  85. } /* path_init */
  86.  
  87.  
  88. /*
  89.  *  Special XDME paths for REF and CTAGS
  90.  */
  91.  
  92. void do_addpath (void)
  93. {
  94.     PEN * pen;
  95.     short len = strlen (av[1]);
  96.  
  97.     for (pen = (PEN *)GetHead(&PBase); pen; pen=(PEN *)GetSucc((struct Node *)pen))
  98.     {
  99.     if (stricmp (av[1], pen->path) == 0)
  100.         return;
  101.     }
  102.  
  103.     if (pen = malloc (sizeof (PEN) + len))
  104.     strcpy (pen->path, av[1]);
  105.  
  106.     AddTail ((LIST *) & PBase, (NODE *) pen);
  107.  
  108.     pen->Node.ln_Name = pen->path;
  109. } /* do_addpath */
  110.  
  111.  
  112. void do_rempath (void)
  113. {
  114.     PEN * pen;
  115.  
  116.     for (pen = (PEN *)GetHead(&PBase); pen; pen = (PEN *)GetSucc((struct Node *)pen))
  117.     {
  118.     if (!stricmp (av[1], pen->path))
  119.     {
  120.         Remove ((NODE *) pen);
  121.         free (pen);
  122.     }
  123.     }
  124. } /* do_rempath */
  125.  
  126.  
  127. void do_refctags (void)
  128. {
  129.     BOOL requester;
  130.     BOOL title;
  131.  
  132.     requester = globalflags.NoRequest;
  133.     title     = globalflags.Showtitle;
  134.  
  135.     globalflags.NoRequest = TRUE;
  136.     globalflags.Showtitle = FALSE;
  137.  
  138.     do_ctags ();
  139.  
  140.     if (globalflags.Abortcommand)
  141.     do_refs ();
  142.  
  143.     globalflags.NoRequest = requester;
  144.     globalflags.Showtitle = title;
  145.  
  146.     if (globalflags.Abortcommand)
  147.     error ("%s:\nCannot find anything about\n`%s'.", av[0],
  148.         ((av[1] != NULL) ? (char *)av[1] : current_word ()));
  149. } /* do_refctags */
  150.  
  151.  
  152. /*
  153.  *  Implement ctags
  154.  */
  155.  
  156. void do_ctags (void)
  157. {
  158.     char    str[64];
  159.     char    path[128];
  160.     char    buf[128];
  161.     char    sbuf[128];
  162.     short   xlen;
  163.     short   slen;
  164.     short   dbaselen;
  165.     BPTR    oldlock = CurrentDir (Ep->dirlock);
  166.     ED      * ed;
  167.  
  168.     if (av[1] != NULL)
  169.     {
  170.     strcpy (str, av[1]);
  171.     xlen = strlen (str);
  172.     } else
  173.     {
  174.     strcpy (str, current_word ());
  175.     xlen = strlen (str);
  176.     }
  177.  
  178.     if (!Ep->iconmode)
  179.     title ("search tags");
  180.  
  181.     {
  182.     FILE * fi;
  183.     PEN  * pen;
  184.     long   i;
  185.     short  j,
  186.            len;
  187.  
  188.     /*
  189.      *  Note: pen not used first pass and set to list head, so next
  190.      *  pass it will be the first element.
  191.      *
  192.      *  Note2:  The file path depends on several factors.  (1) tags in
  193.      *        'current' directory, use path to name of current window.
  194.      *        (2) tags in directory in XDME special path, use special
  195.      *        path.  (3) tag entry is a full path name, override
  196.      *        previous directories.
  197.      */
  198.  
  199.     mountrequest (0);
  200.  
  201.     for (pen=(PEN *)GetHead(&PBase); pen;
  202.                     pen=(PEN *)GetSucc((struct Node *)pen))
  203.     {
  204.         strcpy (path, pen->path);
  205.         AddPart (path, "tags", sizeof(path));
  206.         dbaselen = strlen (pen->path);
  207.  
  208.         if (fi = fopen (path, "r"))
  209.         {
  210.         mountrequest (1);
  211.  
  212.         while ((len = xefgets (fi, buf, 128)) >= 0)
  213.         {
  214.             for (j = 0; buf[j] && buf[j] != ' '; ++j);
  215.  
  216.             if (j == 0 || buf[0] == '#')
  217.             continue;
  218.  
  219.             if (j == xlen && strncmp (str, buf, j) == 0)
  220.             {
  221.             while (buf[j] == ' ')
  222.                 ++j;
  223.  
  224.             /*
  225.              *  Extract the file name into str.  If the
  226.              *  filename does not contain an absolute path,
  227.              *  prepend it with such.
  228.              */
  229.             {
  230.                 char prep = 1;
  231.  
  232.                 for (i = 0; buf[j] && buf[j] != ' '; ++i, ++j)
  233.                 {
  234.                 str[i] = buf[j];
  235.                 if (str[i] == ':')
  236.                     prep = 0;
  237.                 }
  238.  
  239.                 if (prep)
  240.                 {
  241.                 movmem (str, str + dbaselen, i);
  242.                 movmem (path, str, dbaselen);
  243.  
  244.                 i += dbaselen;
  245.                 }
  246.             }
  247.  
  248.             str[i] = 0;
  249.  
  250.             while (buf[j] && buf[j] != '^') /*  SEARCH ARG */
  251.                 ++j;
  252.  
  253.             fclose (fi);
  254.  
  255.             if (buf[j] != '^')
  256.             {
  257.                 error ("ctags:\nError in tags-file");
  258.                 goto done;
  259.             }
  260.  
  261.             ++j;    /* Skip ^ */
  262.  
  263.             /* UN*X FIX: Dme works for Aztec ctags, which has the format:    */
  264.             /*    <tag>    <file>    /^<pattern>                */
  265.             /* However, ctags under UN*X has the following format:        */
  266.             /*    <tag>    <file>    /^<pattern>[$]/             */
  267.             /* We just ignore the '$' and '/' so that both foramts work     */
  268.             /* Thomas Rolfs 27/3/91                     */
  269.  
  270.             {
  271.                 short i = 0;
  272.  
  273.                 while (buf[j] && buf[j] != '$' && buf[j] != '/')
  274.                 {
  275.                 sbuf[i++] = buf[j++];
  276.                 }
  277.  
  278.                 sbuf[i] = 0;
  279.             }
  280.  
  281.             /* End of fix.    */
  282.  
  283.             slen = strlen (sbuf);
  284.  
  285.             if ((ed = finded (str, 0)) == NULL)
  286.             {
  287.                 strcpy (buf, "newwindow newfile `");
  288.                 strcat (buf, str);
  289.                 strcat (buf, "'");
  290.                 do_command (buf);
  291.  
  292.                 /* remove path */
  293.                 strcpy (str, FilePart (str));
  294.  
  295.                 ed = finded (str, 0);
  296.             } else
  297.             {
  298.                 WindowToFront (ed->win);
  299.                 ActivateWindow (ed->win);
  300.             }
  301.  
  302.             if (ed == NULL)
  303.             {
  304.                 error ("ctags:\nunable to load file\n`%s'", str);
  305.                 goto done;
  306.             }
  307.  
  308.             switch_ed (ed);
  309.             text_cursor (0);
  310.  
  311.             for (i = 0; i < ed->lines; ++i)
  312.             {
  313.                 if (strncmp (ed->list[i], sbuf, slen) == 0)
  314.                 break;
  315.             }
  316.  
  317.             sprintf (buf, "first goto %ld", i + 1);
  318.             do_command (buf);
  319.             text_cursor (1);    /* turn cursor on */
  320.  
  321.             goto done;
  322.             }
  323.         }
  324.  
  325.         fclose (fi);
  326.  
  327.         mountrequest (0);
  328.         }
  329.     }
  330.  
  331.     error ("ctags:\ntag `%s'\nnot found", str);
  332.  
  333.     mountrequest (1);
  334.     }
  335. done:
  336.  
  337.     CurrentDir (oldlock);
  338. } /* do_ctags */
  339.  
  340.  
  341. /*
  342.  *  Implement references
  343.  */
  344.  
  345. void do_refs (void)
  346. {
  347.     static char str[MAXLINELEN];
  348.     static char tmpfile[128];
  349.     static char path[128];
  350.     char      * srch;
  351.     char      * file;
  352.     char      * estr;
  353.     long    len;
  354.     int     bcnt = 10;
  355.     short    slen,
  356.         elen;
  357.     FILE      * fi,
  358.           * fj;
  359.     short    tmph,
  360.         tmpw;
  361.     BPTR    oldlock = CurrentDir (Ep->dirlock);
  362.  
  363.     if (av[1] != NULL)
  364.     {
  365.     strcpy (str, av[1]);
  366.     }
  367.     else
  368.     strcpy (str, current_word ());
  369.  
  370.     strcpy (tmpfile, "t:ref_");
  371.     strncat (tmpfile, str, sizeof (tmpfile) - 32);
  372.  
  373.     title ("search .refs");
  374.  
  375.     {
  376.     PEN * pen;
  377.  
  378.     mountrequest (0);
  379.  
  380.     /* search all paths */
  381.     for (pen = (PEN *)GetHead(&PBase); pen; pen=(PEN *)GetSucc(pen))
  382.     {
  383.         strcpy (path, pen->path);
  384.         AddPart (path, "dme.refs", sizeof (path));
  385.  
  386.         if (searchref (path, str, &srch, &file, &len, &estr))
  387.         {
  388.         mountrequest (1);
  389.         goto found;
  390.         }
  391.     }
  392.  
  393.     error ("refs:\nReference `%s'\nnot found", str);
  394.     mountrequest (1);
  395.     goto done;
  396.     }
  397.  
  398. found:
  399.     title ("search file");
  400.     slen = strlen (srch);
  401.  
  402.     if (estr)
  403.     elen = strlen (estr);
  404.  
  405.     fi = fopen (file, "r");
  406.  
  407.     if (fi == NULL)
  408.     {        /*  try using path prefix   */
  409.     strcpy (str, path);
  410.     strcpy (str + strlen (str) - 8, file);
  411.     fi = fopen (str, "r");
  412.     }
  413.  
  414.     if (fi)
  415.     {
  416.     short lenstr;
  417.  
  418.     if (srch[0] == '@' && srch[1] == '@')
  419.     {
  420.         fseek (fi, atoi (srch + 2), 0);
  421.         if ((lenstr = xefgets (fi, str, MAXLINELEN)) >= 0)
  422.         goto autoseek;
  423.     }
  424.  
  425.     while ((lenstr = xefgets (fi, str, MAXLINELEN)) >= 0)
  426.     {
  427.         if (strncmp (str, srch, slen) == 0)
  428.         {
  429. autoseek:
  430.         title ("load..");
  431.         if (fj = fopen (tmpfile, "w"))
  432.         {
  433.             tmph = 0;
  434.             tmpw = 0;
  435.  
  436.             do
  437.             {
  438.             if (lenstr > tmpw)
  439.                 tmpw = strlen (str);
  440.  
  441.             tmph ++;
  442.  
  443.             fputs (str, fj);
  444.             fputc ('\n', fj);
  445.  
  446.             if (estr && strncmp (str, estr, elen) == 0)
  447.                 break;
  448.  
  449.             len --;
  450.             }
  451.  
  452.             while ((lenstr = xefgets (fi, str, MAXLINELEN)) >= 0 && len);
  453.  
  454.             fclose (fj);
  455.  
  456.             if (tmph > 10)
  457.             tmph = 10;
  458.             if (tmpw > 80)
  459.             tmpw = 80;
  460.  
  461.             sprintf (str, "openwindow +0+0+%d+%d newfile %s", (tmpw << 3) + 24, (tmph << 3) + 24, tmpfile);
  462.             do_command (str);
  463.             text_cursor (1);    /* turn cursor on */
  464.             unlink (tmpfile);
  465.         } else
  466.         {
  467.             error ("refs:\nUnable to open\n`%s'\nfor write", tmpfile);
  468.         }
  469.  
  470.         fclose (fi);
  471.         free (srch);
  472.         free (file);
  473.  
  474.         if (estr)
  475.             free (estr);
  476.  
  477.         goto done;
  478.         }
  479.         if (--bcnt == 0)
  480.         {  /* check break every so so  */
  481.         bcnt = 50;
  482.  
  483.         if (breakcheck ())
  484.             break;
  485.         }
  486.     }
  487.     fclose (fi);
  488.  
  489.     error ("refs:\nSearch for `%s'\nfailed", str);
  490.     } else
  491.     {
  492.     error ("refs:\nUnable to open\nsub document");
  493.     }
  494.  
  495.     free (srch);
  496.     free (file);
  497.  
  498.     if (estr)
  499.     free (estr);
  500. done:
  501.     CurrentDir (oldlock);
  502. } /* do_refs */
  503.  
  504.  
  505. /*
  506.  *  Reference file format:
  507.  *
  508.  *  `key' `lines' `file' `searchstring'
  509.  *
  510.  *  where `lines' can be a string instead ... like a read-until, otherwise
  511.  *  the number of lines to read from the reference.
  512.  */
  513.  
  514. int searchref (char * file, char * find, char ** psstr, char ** pfile, int * plines, char **pestr)
  515. {
  516.     FILE  * fi;
  517.     char    buf[MAXLINELEN];
  518.     char  * ptr,
  519.       * base;
  520.     char  * b1,
  521.       * b2,
  522.       * b3,
  523.       * b4;
  524.     char    quoted;
  525.  
  526.     /* short findlen = strlen(find); TODO */
  527.  
  528.     if (fi = fopen (file, "r"))
  529.     {
  530.     while (xefgets (fi, (base = buf), MAXLINELEN) >= 0)
  531.     {
  532.         if (buf[0] == '#')
  533.         continue;
  534.  
  535.         ptr = breakout (&base, "ed, &b1);
  536.  
  537.         /* TODO if (ptr && *ptr && strncmp(ptr, find, findlen) == 0) */
  538.         if (ptr && *ptr && strcmp (ptr, find) == 0)
  539.         {
  540.         if (ptr = breakout (&base, "ed, &b2))
  541.         {
  542.             *pestr = NULL;
  543.             *plines = atoi (ptr);
  544.  
  545.             if (*plines == 0)
  546.             {
  547.             *pestr = (char *) malloc (strlen (ptr) + 1);
  548.             strcpy (*pestr, ptr);
  549.             }
  550.  
  551.             if (ptr = breakout (&base, "ed, &b3))
  552.             {
  553.             *pfile = (char *) malloc (strlen (ptr) + 1);
  554.             strcpy (*pfile, ptr);
  555.  
  556.             if (ptr = breakout (&base, "ed, &b4))
  557.             {
  558.                 *psstr = (char *) malloc (strlen (ptr) + 1);
  559.  
  560.                 strcpy (*psstr, ptr);
  561.                 fclose (fi);
  562.  
  563.                 if (b1)
  564.                 free (b1);
  565.                 if (b2)
  566.                 free (b2);
  567.                 if (b3)
  568.                 free (b3);
  569.                 if (b4)
  570.                 free (b4);
  571.  
  572.                 return (1);
  573.             }
  574.  
  575.             free (*pfile);
  576.  
  577.             if (b4)
  578.                 free (b4);
  579.             }
  580.  
  581.             if (pestr)
  582.             free (*pestr);
  583.             if (b3)
  584.             free (b3);
  585.         }
  586.  
  587.         if (b2)
  588.             free (b2);
  589.         }
  590.  
  591.         if (b1)
  592.         free (b1);
  593.     }
  594.  
  595.     fclose (fi);
  596.     }
  597.  
  598.     return (0);
  599. } /* searchref */
  600.  
  601.  
  602. int dirpart (char * str)
  603. {
  604.     short   i;
  605.  
  606.     for (i = strlen (str) - 1; i >= 0; --i)
  607.     {
  608.     if (str[i] == '/' || str[i] == ':')
  609.         break;
  610.     }
  611.  
  612.     return (i + 1);
  613. } /* dirpart */
  614.  
  615.  
  616. /******************************************************************************
  617. *****  ENDE refs.c
  618. ******************************************************************************/
  619.