home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxregexp.zip / rxregexp.c < prev    next >
Text File  |  1998-04-14  |  13KB  |  293 lines

  1. /*---------------------------------------------------------------------------+
  2. |     MODULE NAME:   RxRegExp.C
  3. |
  4. |
  5. |         $Author:   Dennis_Bareis  $
  6. |       $Revision:   1.1  $
  7. |           $Date:   25 Mar 1996 15:21:54  $
  8. |        $Logfile:   V:/SUEPVCS/SUPPORT/TEMPLATE.C_V  $
  9. |
  10. |     DESCRIPTION:   Regular Expression Interface for REXX code.
  11. |
  12. +---------------------------------------------------------------------------*/
  13.  
  14. /*------ Make constant string definition more efficient & protect them! -----*/
  15. #pragma  strings(readonly)
  16.  
  17. /*------ Include required Header files --------------------------------------*/
  18. #define  INCL_DOSPROCESS
  19. #define  INCL_NOPMAPI
  20. #define  INCL_REXXSAA
  21. #define  _DLL
  22. #define  _MT
  23. #include <os2.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <rexxsaa.h>
  28. #include "RexxDll.H"
  29. #include "RegExp.H"
  30.  
  31.  
  32. /*--- Version Information ---------------------------------------------------*/
  33. #define REXXDLL_VERSION_INFO                   \
  34.         "98.104"                               \
  35.         " "                                    \
  36.         "http://www.ozemail.com.au/~dbareis"   \
  37.         " "                                    \
  38.         "db0@anz.com"                          \
  39.         " "                                    \
  40.         "Dennis Bareis"
  41.  
  42. /*--- Hold Compiled Regular Expression --------------------------------------*/
  43. static regexp * CompiledRe = NULL;
  44. static char   * LastString = NULL;
  45.  
  46. /*--- Hold Error Messages ---------------------------------------------------*/
  47. static char * ErrorReason = "";
  48.               #define CLEAR_ERROR_BUFFER() ErrorReason = "";
  49.  
  50.  
  51. /*===========================================================================*/
  52. static void ReleaseLastString(void)
  53. /*===========================================================================*/
  54. {
  55.     if  (LastString != NULL)
  56.     {
  57.         free(LastString);
  58.         LastString = NULL;
  59.     }
  60. }
  61.  
  62.  
  63.  
  64. /*===========================================================================*/
  65. void regerror(char * ErrorText)
  66. /*===========================================================================*/
  67. {
  68.     /*--- Set up error message (its in a constant buffer) -------------------*/
  69.     ErrorReason = ErrorText;
  70. }
  71.  
  72.  
  73. /*===========================================================================*/
  74. REX_DECLARE_REXX_ENTRY_POINT(RegExpVersion)
  75. /*                                                                           */
  76. /* This routine requires the following parameters:                           */
  77. /*                                                                           */
  78. /*      1. The name of a variable that will be updated with the version      */
  79. /*         information.                                                      */
  80. /*===========================================================================*/
  81. {
  82.     UCHAR       * VariableName = REX_ASCIIZ_ARGV(0);
  83.     LongRc0IfOk   AddRc;
  84.  
  85.     /*--- Validate parameter(s) ---------------------------------------------*/
  86.     CLEAR_ERROR_BUFFER();
  87.     RexCheckPassedVariableCountSetUpRcAndExitOnError(1);
  88.  
  89.     /*--- Set the information variable --------------------------------------*/
  90.     AddRc = RexSetRexxVariable(VariableName, REXXDLL_VERSION_INFO);
  91.     if  (AddRc == 0)
  92.         RexSetUpOkRc(RxFunctionRc);
  93.     else
  94.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not update the variable \"%s\" (Rc = %lu).", VariableName, AddRc);
  95.  
  96.     /*--- Thats all Folks ---------------------------------------------------*/
  97.     REX_RETURN_TO_CMD();
  98. }
  99.  
  100.  
  101. /*===========================================================================*/
  102. REX_DECLARE_REXX_ENTRY_POINT(RegExpCompile)
  103. /*                                                                           */
  104. /* This routine requires the following parameters:                           */
  105. /*                                                                           */
  106. /*      1. The Regular Expression OR "ReClose".                              */
  107. /*                                                                           */
  108. /* If "ReClose" is passed we don't wish to compile a regular expression but  */
  109. /* terminate a previous one (releasing any held memory etc).                 */
  110. /*===========================================================================*/
  111. {
  112.     UCHAR * Re = REX_ASCIIZ_ARGV(0);
  113.  
  114.     /*--- Validate parameter(s) ---------------------------------------------*/
  115.     CLEAR_ERROR_BUFFER();
  116.     RexCheckPassedVariableCountSetUpRcAndExitOnError(1);
  117.  
  118.     /*--- The user may wish to close the regular expression -----------------*/
  119.     if  (strcmp(Re, "ReClose") == 0)
  120.     {
  121.         /*--- Close Expression ----------------------------------------------*/
  122.         if  (CompiledRe != NULL)
  123.         {
  124.             /*--- Free memory and clear pointer -----------------------------*/
  125.             free(CompiledRe);
  126.             CompiledRe = NULL;
  127.             ReleaseLastString();
  128.         }
  129.         RexSetUpOkRc(RxFunctionRc);
  130.     }
  131.     else
  132.     {
  133.         /*--- Compile the Passed Regular Expression -------------------------*/
  134.         CompiledRe = regcomp(Re);
  135.         if (CompiledRe != NULL)
  136.             RexSetUpOkRc(RxFunctionRc);
  137.         else
  138.             RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not compile the regular expression %s (%s)", Re, ErrorReason);
  139.     }
  140.  
  141.     /*--- Thats all Folks ---------------------------------------------------*/
  142.     REX_RETURN_TO_CMD();
  143. }
  144.  
  145.  
  146. /*===========================================================================*/
  147. REX_DECLARE_REXX_ENTRY_POINT(RegExpMatch)
  148. /*                                                                           */
  149. /* This routine requires the following parameters:                           */
  150. /*                                                                           */
  151. /*      1. A string which we will attempt to match.                          */
  152. /*                                                                           */
  153. /* Returns:                                                                  */
  154. /*                                                                           */
  155. /*      'N' = No Match.                                                      */
  156. /*      Start position and length of match (seperated by a space)            */
  157. /*                                                                           */
  158. /*===========================================================================*/
  159. {
  160.     UCHAR       * VariableName = REX_ASCIIZ_ARGV(1);
  161.     UCHAR         VariableValue[255+1];
  162.     UCHAR       * Ptr;
  163.     LongRc0IfOk   AddRc;
  164.     int           Index;
  165.  
  166.     /*--- Make sure clear error buffer and clear last match string ----------*/
  167.     CLEAR_ERROR_BUFFER();
  168.     ReleaseLastString();
  169.  
  170.     /*--- Validate parameter(s) ---------------------------------------------*/
  171.     RexCheckPassedVariableCountSetUpRcAndExitOnError(2);
  172.  
  173.     /*--- Make sure that we have a regular expression to match against ------*/
  174.     if  (CompiledRe == NULL)
  175.     {
  176.         /*--- Thats all Folks! ----------------------------------------------*/
  177.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "You must call \"RegExpCompile\" first!");
  178.         REX_RETURN_TO_CMD();
  179.     }
  180.  
  181.     /*--- Set up Success Rc -------------------------------------------------*/
  182.     RexSetUpRc(RxFunctionRc, "OK");
  183.  
  184.     /*--- Make a copy of the string (work around to buggy regexp code) ------*/
  185.     LastString = strdup(REX_ASCIIZ_ARGV(0));
  186.     if  (LastString == NULL)
  187.     {
  188.         /*--- Thats all Folks! ----------------------------------------------*/
  189.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not duplicate the compare string (low memory?)!");
  190.         REX_RETURN_TO_CMD();
  191.     }
  192.  
  193.     /*--- Look for a match --------------------------------------------------*/
  194.     if  (regexec(CompiledRe, LastString) != 0)
  195.     {
  196.         /*--- Found the regular expression (output the overall match --------*/
  197.         Ptr = VariableValue + sprintf(VariableValue, "%d %d", 1+(CompiledRe->startp[0]-LastString), (CompiledRe->endp[0]-CompiledRe->startp[0]));
  198.  
  199.         /*--- Add any subcomponents (stuff in round brackets) ---------------*/
  200.         for (Index=1; Index < NSUBEXP; Index++)
  201.         {
  202.             /*--- Exit if no such component ---------------------------------*/
  203.             if  (CompiledRe->startp[Index] == NULL)
  204.                 break;
  205.  
  206.             /*--- Add next bit ----------------------------------------------*/
  207.             Ptr += sprintf(Ptr, " %d %d", 1+(CompiledRe->startp[Index]-LastString), (CompiledRe->endp[Index]-CompiledRe->startp[Index]));
  208.         }
  209.     }
  210.     else
  211.     {
  212.         /*--- Did not find a match, did we have a failure? ------------------*/
  213.         if  (*ErrorReason != '\0')
  214.             RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Failed trying to find regular expression (%s)", ErrorReason);
  215.         *VariableValue = '\0';                       //Empty value on no match
  216.         ReleaseLastString();
  217.     }
  218.  
  219.     /*--- Set up the answer -------------------------------------------------*/
  220.     AddRc = RexSetRexxVariable(VariableName, VariableValue);
  221.     if  (AddRc != 0)
  222.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not update the variable \"%s\" (Rc = %lu).", VariableName, AddRc);
  223.  
  224.     /*--- Thats all Folks ---------------------------------------------------*/
  225.     REX_RETURN_TO_CMD();
  226. }
  227.  
  228.  
  229.  
  230.  
  231. /*===========================================================================*/
  232. REX_DECLARE_REXX_ENTRY_POINT(RegExpReplace)
  233. /*                                                                           */
  234. /* This routine requires the following parameters:                           */
  235. /*                                                                           */
  236. /*      1. A string which we will modify.                                    */
  237. /*      2. Name of variable to hold modified string.                         */
  238. /*                                                                           */
  239. /* Returns:                                                                  */
  240. /*                                                                           */
  241. /*      "OK" unless error occurs.                                            */
  242. /*===========================================================================*/
  243. {
  244.     UCHAR       * ChangeSpec   = REX_ASCIIZ_ARGV(0);
  245.     UCHAR       * VariableName = REX_ASCIIZ_ARGV(1);
  246.     UCHAR       * NewValue;
  247.     LongRc0IfOk   AddRc;
  248.  
  249.     /*--- Validate parameter(s) ---------------------------------------------*/
  250.     CLEAR_ERROR_BUFFER();
  251.     RexCheckPassedVariableCountSetUpRcAndExitOnError(2);
  252.  
  253.     /*--- Make sure that we have a regular expression to match against ------*/
  254.     if  (CompiledRe == NULL)
  255.     {
  256.         /*--- Die! ----------------------------------------------------------*/
  257.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "You must call \"RegExpCompile\" first!");
  258.         REX_RETURN_TO_CMD();
  259.     }
  260.     if  (LastString == NULL)
  261.     {
  262.         /*--- Die! ----------------------------------------------------------*/
  263.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "You must call \"RegExpMatch\" first (and it should find a match)!");
  264.         REX_RETURN_TO_CMD();
  265.     }
  266.  
  267.     /*--- Allocate memory for the change buffer -----------------------------*/
  268.     NewValue = malloc(50000);
  269.     if  (NewValue == NULL)
  270.     {
  271.         /*--- Die! ----------------------------------------------------------*/
  272.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not allocate memory for result!");
  273.         REX_RETURN_TO_CMD();
  274.     }
  275.  
  276.     /*--- Make the changes --------------------------------------------------*/
  277.     regsub(CompiledRe, ChangeSpec, NewValue);
  278.  
  279.     /*--- Set up the answer -------------------------------------------------*/
  280.     AddRc = RexSetRexxVariable(VariableName, NewValue);
  281.     free(NewValue);
  282.     if  (AddRc != 0)
  283.     {
  284.         /*--- Die! ----------------------------------------------------------*/
  285.         RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not update the variable \"%s\" (Rc = %lu).", VariableName, AddRc);
  286.         REX_RETURN_TO_CMD();
  287.     }
  288.  
  289.     /*--- Thats all Folks ---------------------------------------------------*/
  290.     RexSetUpRc(RxFunctionRc, "OK");
  291.     REX_RETURN_TO_CMD();
  292. }
  293.