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