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