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