home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 171.lha / DME_v1.30 / Sources / refs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-28  |  7.9 KB  |  391 lines

  1.  
  2. /*
  3.  *  REFS.C
  4.  *
  5.  *  Bringup a cross reference editor window.  The file S:dme.refs and
  6.  *  dme.refs in the current directory are searched for the reference.
  7.  *  If found, the file specified is searched and the segment specified
  8.  *  loaded as a new file in a new window.
  9.  */
  10.  
  11. #include "defs.h"
  12. #include <stdio.h>
  13.  
  14. #define PEN    struct _PEN
  15.  
  16. PEN {
  17.     MNODE   Node;
  18.     char    *path;
  19. };
  20.  
  21. extern char *breakout();
  22.  
  23. MLIST    PBase;        /*  special DME paths    */
  24.  
  25. /*
  26.  *  Special DME paths for REF and CTAGS
  27.  */
  28.  
  29. void
  30. do_addpath()
  31. {
  32.     register PEN *pen;
  33.     register short len = strlen(av[1]);
  34.  
  35.     for (pen = (PEN *)PBase.mlh_Head; pen->Node.mln_Succ; pen = (PEN *)pen->Node.mln_Succ) {
  36.     if (strcmp(av[1], pen->path) == 0)
  37.         return;
  38.     }
  39.     if (pen = malloc(sizeof(PEN)+len+2)) {
  40.     pen->path = (char *)(pen + 1);
  41.     strcpy(pen->path, av[1]);
  42.     switch(pen->path[len-1]) {
  43.     case ':':
  44.     case '/':
  45.         break;
  46.     default:
  47.         strcat(pen->path, "/");
  48.     }
  49.     }
  50.     AddTail(&PBase, pen);
  51. }
  52.  
  53. do_rempath()
  54. {
  55.     register PEN *pen, *npen;
  56.  
  57.     for (pen = (PEN *)PBase.mlh_Head; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  58.     if (wildcmp(av[1], pen->path)) {
  59.         Remove(pen);
  60.         free(pen);
  61.     }
  62.     }
  63. }
  64.  
  65. /*
  66.  *  Implement ctags
  67.  */
  68.  
  69. void
  70. do_ctags()
  71. {
  72.     char str[64];
  73.     char path[128];
  74.     char buf[128];
  75.     char sbuf[128];
  76.     long xfi;
  77.     short xlen;
  78.     short slen;
  79.     short dbaselen;
  80.     ED *ed;
  81.  
  82.     {
  83.     register short i, j;
  84.  
  85.     for (i = Ep->Column; Current[i] == ' '; ++i);
  86.     for (j = i; ; ++j) {
  87.         register short c = Current[j];
  88.         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'))
  89.         continue;
  90.         break;
  91.     }
  92.     j -= i;
  93.     if (j > 63)
  94.         j = 63;
  95.     bmov(Current+i, str, j);
  96.     str[j] = 0;
  97.     xlen = j;
  98.     }
  99.     if (!Ep->iconmode)
  100.     title("search tags");
  101.     {
  102.     long xfi;
  103.     PEN *pen, *npen;
  104.     register long i;
  105.     register short j, len;
  106.  
  107.     dbaselen = dirpart(Ep->Name);
  108.     bmov(Ep->Name, path, dbaselen);
  109.     strcpy(path+dbaselen, "tags");
  110.  
  111.     /*
  112.      *  Note: pen not used first pass and set to list head, so next
  113.      *  pass it will be the first element.
  114.      *
  115.      *  Note2:  The file path depends on several factors.  (1) tags in
  116.      *        'current' directory, use path to name of current window.
  117.      *        (2) tags in directory in DME special path, use special
  118.      *        path.  (3) tag entry is a full path name, override
  119.      *        previous directories.
  120.      */
  121.  
  122.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  123.         mountrequest(0);
  124.         if (xfi = xfopen(path, "r", 4096)) {
  125.         mountrequest(1);
  126.         while ((len = xefgets(xfi, buf, 128)) >= 0) {
  127.             for (j = 0; buf[j] && buf[j] != ' '; ++j);
  128.             if (j == 0 || buf[0] == '#')
  129.             continue;
  130.             if (j == xlen && strncmp(str, buf, j) == 0) {
  131.             while (buf[j] == ' ')
  132.                 ++j;
  133.             /*
  134.              *  Extract the file name into str.  If the
  135.              *  filename does not contain an absolute path,
  136.              *  prepend it with such.
  137.              */
  138.             {
  139.                 char prep = 1;
  140.                 for (i = 0; buf[j] && buf[j] != ' '; ++i, ++j) {
  141.                 str[i] = buf[j];
  142.                 if (str[i] == ':')
  143.                     prep = 0;
  144.                 }
  145.                 if (prep) {
  146.                 bmov(str, str + dbaselen, i);
  147.                 bmov(path, str, dbaselen);
  148.                 i += dbaselen;
  149.                 }
  150.             }
  151.             str[i] = 0;
  152.  
  153.             while (buf[j] && buf[j] != '^')     /*  SEARCH ARG */
  154.                 ++j;
  155.             xfclose(xfi);
  156.             if (buf[j] != '^') {
  157.                 title("tags error");
  158.                 return;
  159.             }
  160.             ++j;
  161.             strcpy(sbuf, buf+j);
  162.             slen = strlen(sbuf);
  163.             if ((ed = finded(str, 0)) == NULL) {
  164.                 strcpy(buf, "newwindow newfile ");
  165.                 strcat(buf, str);
  166.                 do_command(buf);
  167.                 ed = finded(str, 0);
  168.             } else {
  169.                 WindowToFront(ed->Win);
  170.                 ActivateWindow(ed->Win);
  171.             }
  172.             if (ed == NULL) {
  173.                 title("unable to load file");
  174.                 return;
  175.             }
  176.             text_switch(ed->Win);
  177.             if (Ep->iconmode)
  178.                 uniconify();
  179.             else
  180.                 text_cursor(0);
  181.             for (i = 0; i < ed->Lines; ++i) {
  182.                 if (strncmp(ed->List[i], sbuf, slen) == 0)
  183.                 break;
  184.             }
  185.             sprintf(buf, "first goto %ld", i+1);
  186.             do_command(buf);
  187.             return;
  188.             }
  189.         }
  190.         xfclose(xfi);
  191.         } else {
  192.         mountrequest(1);
  193.         }
  194.         if (npen->Node.mln_Succ) {
  195.         strcpy(path, npen->path);
  196.         strcat(path, "tags");
  197.         dbaselen = strlen(npen->path);
  198.         }
  199.     }
  200.     title("tag not found");
  201.     }
  202. }
  203.  
  204. /*
  205.  *  Implement references
  206.  */
  207.  
  208. void
  209. do_refs()
  210. {
  211.     char str[256];
  212.     char path[128];
  213.     char *srch;
  214.     char *file;
  215.     char *estr;
  216.     long len;
  217.     int bcnt = 10;
  218.     register short i, j;
  219.     short slen, elen;
  220.     long xfi, xfj;
  221.     short tmph, tmpw;
  222.  
  223.     for (i = Ep->Column; Current[i] == ' '; ++i);     /*  skip spaces     */
  224.     for (j = i       ; ; ++j) {
  225.     if (Current[j] && Current[j] != ' ')
  226.         continue;
  227.     break;
  228.     }
  229.     j -= i;
  230.     if (j > 63)
  231.     j = 63;
  232.     bmov(Current+i, str, j);
  233.     str[j] = 0;
  234.     title("search .refs");
  235.     {
  236.     register PEN *pen;
  237.     register PEN *npen;
  238.  
  239.     strcpy(path, "dme.refs");
  240.     mountrequest(0);
  241.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  242.         if (searchref(path, str, &srch, &file, &len, &estr)) {
  243.         mountrequest(1);
  244.         goto found;
  245.         }
  246.         if (npen->Node.mln_Succ) {
  247.         strcpy(path, npen->path);
  248.         strcat(path, "dme.refs");
  249.         }
  250.     }
  251.     title("Reference not found");
  252.     mountrequest(1);
  253.     return;
  254.     }
  255. found:
  256.     title("search file");
  257.     slen = strlen(srch);
  258.     if (estr)
  259.     elen = strlen(estr);
  260.     if (xfi = xfopen(file, "r", 4096)) {
  261.     short lenstr;
  262.     while ((lenstr = xefgets(xfi, str, 256)) >= 0) {
  263.         if (strncmp(str, srch, slen) == 0) {
  264.         title("load..");
  265.         if (xfj = xfopen("t:dme_ref", "w", 1024)) {
  266.             tmph = 0;
  267.             tmpw = 0;
  268.             do {
  269.             if (lenstr > tmpw)
  270.                 tmpw = strlen(str);
  271.             ++tmph;
  272.             xfwrite(xfj, str, strlen(str));
  273.             xfwrite(xfj, "\n", 1);
  274.             if (estr && strncmp(str,estr,elen) == 0)
  275.                 break;
  276.             --len;
  277.             } while ((lenstr=xefgets(xfi, str, 256)) >= 0 && len);
  278.             xfclose(xfj);
  279.             if (tmph > 10)
  280.             tmph = 10;
  281.             if (tmpw > 80)
  282.             tmpw = 80;
  283.             sprintf(str, "tmpheight %ld tmpwidth %ld newwindow newfile t:dme_ref", (tmph<<3)+24, (tmpw<<3)+24);
  284.             do_command(str);
  285.             unlink("t:dme_ref");
  286.         } else {
  287.             title("Unable to open t:dme_ref for write");
  288.         }
  289.         xfclose(xfi);
  290.         free(srch);
  291.         free(file);
  292.         if (estr)
  293.             free(estr);
  294.         return;
  295.         }
  296.         if (--bcnt == 0) {      /* check break every so so  */
  297.         bcnt = 50;
  298.         if (breakcheck())
  299.             break;
  300.         }
  301.     }
  302.     xfclose(xfi);
  303.     title("Search failed");
  304.     } else {
  305.     title("Unable to open sub document");
  306.     }
  307.     free(srch);
  308.     free(file);
  309.     if (estr)
  310.     free(estr);
  311. }
  312.  
  313. /*
  314.  *  Reference file format:
  315.  *
  316.  *  `key' `lines' `file' `searchstring'
  317.  *
  318.  *  where `lines' can be a string instead ... like a read-until, otherwise
  319.  *  the number of lines to read from the reference.
  320.  */
  321.  
  322. searchref(file, find, psstr, pfile, plines, pestr)
  323. char *file, *find;
  324. char **psstr, **pfile, **pestr;
  325. long *plines;
  326. {
  327.     long xfi;
  328.     char buf[256];
  329.     char *ptr, *base;
  330.     char *b1, *b2, *b3, *b4;
  331.     char quoted;
  332.  
  333.     if (xfi = xfopen(file, "r", 4096)) {
  334.     while (xefgets(xfi,(base=buf), 256) >= 0) {
  335.         if (buf[0]=='#')
  336.         continue;
  337.         ptr = breakout(&base, "ed, &b1);
  338.         if (ptr && *ptr && strncmp(ptr, find, strlen(ptr)) == 0) {
  339.         if (ptr = breakout(&base, "ed, &b2)) {
  340.             *pestr = NULL;
  341.             *plines = atoi(ptr);
  342.             if (*plines == 0) {
  343.             *pestr = (char *)malloc(strlen(ptr)+1);
  344.             strcpy(*pestr, ptr);
  345.             }
  346.             if (ptr = breakout(&base, "ed, &b3)) {
  347.             *pfile = (char *)malloc(strlen(ptr)+1);
  348.             strcpy(*pfile, ptr);
  349.             if (ptr = breakout(&base, "ed, &b4)) {
  350.                 *psstr = (char *)malloc(strlen(ptr)+1);
  351.                 strcpy(*psstr, ptr);
  352.                 xfclose(xfi);
  353.                 if (b1) free(b1);
  354.                 if (b2) free(b2);
  355.                 if (b3) free(b3);
  356.                 if (b4) free(b4);
  357.                 return(1);
  358.             }
  359.             free(*pfile);
  360.             if (b4)
  361.                 free(b4);
  362.             }
  363.             if (pestr)
  364.             free (*pestr);
  365.             if (b3)
  366.             free (b3);
  367.         }
  368.         if (b2)
  369.             free(b2);
  370.         }
  371.         if (b1)
  372.         free(b1);
  373.     }
  374.     xfclose(xfi);
  375.     }
  376.     return(0);
  377. }
  378.  
  379. dirpart(str)
  380. register char *str;
  381. {
  382.     register short i;
  383.  
  384.     for (i = strlen(str) - 1; i >= 0; --i) {
  385.     if (str[i] == '/' || str[i] == ':')
  386.         break;
  387.     }
  388.     return(i+1);
  389. }
  390.  
  391.