home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / misc / xref_v1.1.lha / XRef / Tools / rexx / findxref.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-09  |  6.2 KB  |  238 lines

  1. /*
  2. ** $PROJECT: rexxxref.library
  3. **
  4. ** $VER: findxref.c 1.1 (08.01.95)
  5. **
  6. ** by
  7. **
  8. ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
  9. **
  10. ** (C) Copyright 1995
  11. ** All Rights Reserved !
  12. **
  13. ** $HISTORY:
  14. **
  15. ** 08.01.95 : 001.001 : initial
  16. */
  17.  
  18. #include "rexxxref.h"
  19.  
  20. /*FS*/ /*"AutoDoc"*/
  21. /*GB*** rexxxref.library/FindXRef ********************************************
  22. *
  23. *    NAME
  24. *        FindXRef - searchs for a given pattern and returns the xref entries
  25. *
  26. *    SYNOPSIS
  27. *        FindXRef(STRING/A,CATEGORY,LIMIT/N,NOPATTERN/S,NOCASE/S,STEM)
  28. *
  29. *    FUNCTION
  30. *        Searchs for a given pattern or string. If one or more xref entries
  31. *        are found, this function returns the full information about the xref
  32. *        entry in the specified stem variable.
  33. *
  34. *    INPUTS
  35. *        STRING   - string/pattern to search for
  36. *        CATEGORY - category to search in
  37. *        LIMIT    - maximal number of entries to return
  38. *        NOPATTERN- string isn't a pattern
  39. *        NOCASE   - ignore case ('A'=='a')
  40. *        STEM     - stem variable to use, if not specified it uses the
  41. *                   "XRef" as stem base name !
  42. *                   The following stem field are supported :
  43. *                   XRef.Count
  44. *                   XRef.n.Type
  45. *                   XRef.n.Name
  46. *                   XRef.n.NodeName
  47. *                   XRef.n.File
  48. *                   XRef.n.Path
  49. *                   XRef.n.Line
  50. *
  51. *    RESULTS
  52. *        Set RC to WARN,if no entry was found. Otherwise set to RC_OK
  53. *
  54. *    SEE ALSO
  55. *        LoadXRef() ,ExpungeXRef() ,ParseXRef()
  56. *
  57. ******************************************************************************
  58. *
  59. */
  60. /*FE*/
  61.  
  62. const STRPTR xref_types[] = {
  63.    "Generic",
  64.    "Function",
  65.    "Command",
  66.    "Include",
  67.    "Macro",
  68.    "Structure",
  69.    "Field",
  70.    "Typedef",
  71.    "Define",
  72.    NULL};
  73.  
  74. struct FindXRefData
  75. {
  76.    struct RexxMsg *RMsg;
  77.    STRPTR Stem;
  78.    struct RexxXRefBase *LibBase;
  79.    ULONG Number;
  80.    UBYTE StemBuf[100];
  81.    UBYTE Buf[20];
  82. };
  83.  
  84. static RegCall GetA4 ULONG findxreffunc(REGA0 struct Hook *hook,REGA2 struct XRefFileNode *xref,REGA1 struct xrmXRef *msg)
  85. {
  86.    if(msg->Msg == XRM_XREF)
  87.    {
  88.       struct FindXRefData *fxd = (struct FindXRefData *) hook->h_Data;
  89.       struct RexxXRefBase *rxb = (struct RexxXRefBase *) fxd->LibBase;
  90.       struct TagItem *tstate = msg->xref_Attrs;
  91.       struct TagItem *tag;
  92.       STRPTR value;
  93.       STRPTR field;
  94.       ULONG len;
  95.       BOOL noline = TRUE;
  96.  
  97.       DB(("Name : \"%s\"\n",GetTagData(ENTRYA_Name,(ULONG) "noname",tstate)));
  98.  
  99.       fxd->Number++;
  100.  
  101.       while((tag = NextTagItem(&tstate)))
  102.       {
  103.          value = (STRPTR) tag->ti_Data;
  104.          field = NULL;
  105.          len   = 0;
  106.  
  107.          switch(tag->ti_Tag)
  108.          {
  109.          case ENTRYA_Type:
  110.             field = "TYPE";
  111.             if(tag->ti_Data < XREFT_MAXTYPES)
  112.             {
  113.                value = (STRPTR) xref_types[tag->ti_Data];
  114.                len = strlen(value);
  115.             } else
  116.                value = 0;
  117.             break;
  118.          case ENTRYA_File:
  119.             field = "FILE";
  120.             break;
  121.          case ENTRYA_Name:
  122.             field = "NAME";
  123.             break;
  124.          case ENTRYA_Line:
  125.             noline =  FALSE;
  126.             field = "LINE";
  127.             value = fxd->Buf;
  128.             sprintf(fxd->Buf,"%ld",tag->ti_Data);
  129.             break;
  130.          case ENTRYA_NodeName:
  131.             field = "NODENAME";
  132.             break;
  133.          case XREFA_Path:
  134.             field = "PATH";
  135.             break;
  136.          }
  137.  
  138.          if(field)
  139.          {
  140.             sprintf(fxd->StemBuf,"%s.%ld.%s",fxd->Stem,fxd->Number,field);
  141.             DB(("try to set : \"%s\" to \"%s\"\n",fxd->StemBuf,value));
  142.  
  143.             if(value)
  144.                SetRexxVar((struct Message *) fxd->RMsg,fxd->StemBuf,value,(len) ? len : strlen(value));
  145.             else
  146.                SetRexxVar((struct Message *) fxd->RMsg,fxd->StemBuf,"",0);
  147.  
  148.             DB(("after SetRexxVar()\n"));
  149.          }
  150.       }
  151.  
  152.       if(noline)
  153.       {
  154.          sprintf(fxd->StemBuf,"%s.%ld.LINE",fxd->Stem,fxd->Number);
  155.          SetRexxVar((struct Message *) fxd->RMsg,fxd->StemBuf,"0",1);
  156.       }
  157.    }
  158.    return(0);
  159. }
  160.  
  161. ULONG findxref(struct ARexxFunction *func,struct RexxMsg *rmsg,STRPTR *argstr,struct RexxXRefBase *rxb)
  162. {
  163.    ULONG rc  = RC_OK;
  164.  
  165.    if(!rmsg->rm_Args[FX_STRING])
  166.       rc = RXERR_REQUIRED_ARG_MISSING;
  167.    else
  168.    {
  169.       struct FindXRefData fxd;
  170.       struct TagItem tags[5];
  171.       struct Hook hook;
  172.  
  173.       ULONG matching = XREFMATCH_PATTERN_CASE;
  174.       ULONG limit    = ~0;
  175.  
  176.       BOOL nopattern = (rmsg->rm_Args[FX_NOPATTERN] && !Stricmp(rmsg->rm_Args[FX_NOPATTERN],"NOPATTERN"));
  177.       BOOL nocase    = (rmsg->rm_Args[FX_NOCASE]    && !Stricmp(rmsg->rm_Args[FX_NOCASE],"NOCASE"));
  178.  
  179.       GetXRefBaseAttrs(XREFBA_DefaultLimit,&limit,TAG_DONE);
  180.  
  181.       fxd.RMsg    = rmsg;
  182.       fxd.Stem    = (rmsg->rm_Args[FX_STEM]) ? rmsg->rm_Args[FX_STEM] : "XREF";
  183.       fxd.Number  = 0;
  184.       fxd.LibBase = rxb;
  185.  
  186.       hook.h_Data  = &fxd;
  187.       hook.h_Entry = (HOOKFUNC) findxreffunc;
  188.  
  189.       if(nopattern)
  190.          if(nocase)
  191.             matching = XREFMATCH_COMPARE_NOCASE;
  192.          else
  193.             matching = XREFMATCH_COMPARE_CASE;
  194.       else
  195.          if(nocase)
  196.             matching = XREFMATCH_PATTERN_NOCASE;
  197.  
  198.       if(rmsg->rm_Args[FX_LIMIT])
  199.          StrToLong(rmsg->rm_Args[FX_LIMIT],(LONG *) &limit);
  200.  
  201.       tags[0].ti_Tag  = XREFA_Category;
  202.       tags[0].ti_Data = (ULONG) rmsg->rm_Args[FX_CATEGORY];
  203.       tags[1].ti_Tag  = XREFA_Matching;
  204.       tags[1].ti_Data = matching;
  205.       tags[2].ti_Tag  = XREFA_XRefHook;
  206.       tags[2].ti_Data = (ULONG) &hook;
  207.       tags[3].ti_Tag  = XREFA_Limit;
  208.       tags[3].ti_Data = limit;
  209.       tags[4].ti_Tag  = TAG_DONE;
  210.  
  211.       if(ParseXRef(rmsg->rm_Args[FX_STRING],tags))
  212.       {
  213.          DB(("returned from ParseXRef()\n"));
  214.          if(fxd.Number == 0)
  215.             rc = RC_WARN;
  216.          else
  217.          {
  218.             sprintf(fxd.Buf,"%ld",fxd.Number);
  219.             sprintf(fxd.StemBuf,"%s.COUNT",fxd.Stem);
  220.  
  221.             SetRexxVar((struct Message *) rmsg,fxd.StemBuf,fxd.Buf,strlen(fxd.Buf));
  222.  
  223.             if(!(*argstr = CreateArgstring("1",1)))
  224.                rc = RXERR_NO_FREE_STORE;
  225.  
  226.             DB(("after set \"%s\" to \"%s\"\n",fxd.StemBuf,fxd.Buf));
  227.          }
  228.       } else
  229.          rc = RC_FATAL;
  230.  
  231.    }
  232.  
  233.    DB(("now returning to ARexx\n"));
  234.  
  235.    return(rc);
  236. }
  237.  
  238.