home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rxregexp.zip
/
rxregexp.c
< prev
next >
Wrap
Text File
|
1998-04-14
|
13KB
|
293 lines
/*---------------------------------------------------------------------------+
| MODULE NAME: RxRegExp.C
|
|
| $Author: Dennis_Bareis $
| $Revision: 1.1 $
| $Date: 25 Mar 1996 15:21:54 $
| $Logfile: V:/SUEPVCS/SUPPORT/TEMPLATE.C_V $
|
| DESCRIPTION: Regular Expression Interface for REXX code.
|
+---------------------------------------------------------------------------*/
/*------ Make constant string definition more efficient & protect them! -----*/
#pragma strings(readonly)
/*------ Include required Header files --------------------------------------*/
#define INCL_DOSPROCESS
#define INCL_NOPMAPI
#define INCL_REXXSAA
#define _DLL
#define _MT
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <rexxsaa.h>
#include "RexxDll.H"
#include "RegExp.H"
/*--- Version Information ---------------------------------------------------*/
#define REXXDLL_VERSION_INFO \
"98.104" \
" " \
"http://www.ozemail.com.au/~dbareis" \
" " \
"db0@anz.com" \
" " \
"Dennis Bareis"
/*--- Hold Compiled Regular Expression --------------------------------------*/
static regexp * CompiledRe = NULL;
static char * LastString = NULL;
/*--- Hold Error Messages ---------------------------------------------------*/
static char * ErrorReason = "";
#define CLEAR_ERROR_BUFFER() ErrorReason = "";
/*===========================================================================*/
static void ReleaseLastString(void)
/*===========================================================================*/
{
if (LastString != NULL)
{
free(LastString);
LastString = NULL;
}
}
/*===========================================================================*/
void regerror(char * ErrorText)
/*===========================================================================*/
{
/*--- Set up error message (its in a constant buffer) -------------------*/
ErrorReason = ErrorText;
}
/*===========================================================================*/
REX_DECLARE_REXX_ENTRY_POINT(RegExpVersion)
/* */
/* This routine requires the following parameters: */
/* */
/* 1. The name of a variable that will be updated with the version */
/* information. */
/*===========================================================================*/
{
UCHAR * VariableName = REX_ASCIIZ_ARGV(0);
LongRc0IfOk AddRc;
/*--- Validate parameter(s) ---------------------------------------------*/
CLEAR_ERROR_BUFFER();
RexCheckPassedVariableCountSetUpRcAndExitOnError(1);
/*--- Set the information variable --------------------------------------*/
AddRc = RexSetRexxVariable(VariableName, REXXDLL_VERSION_INFO);
if (AddRc == 0)
RexSetUpOkRc(RxFunctionRc);
else
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not update the variable \"%s\" (Rc = %lu).", VariableName, AddRc);
/*--- Thats all Folks ---------------------------------------------------*/
REX_RETURN_TO_CMD();
}
/*===========================================================================*/
REX_DECLARE_REXX_ENTRY_POINT(RegExpCompile)
/* */
/* This routine requires the following parameters: */
/* */
/* 1. The Regular Expression OR "ReClose". */
/* */
/* If "ReClose" is passed we don't wish to compile a regular expression but */
/* terminate a previous one (releasing any held memory etc). */
/*===========================================================================*/
{
UCHAR * Re = REX_ASCIIZ_ARGV(0);
/*--- Validate parameter(s) ---------------------------------------------*/
CLEAR_ERROR_BUFFER();
RexCheckPassedVariableCountSetUpRcAndExitOnError(1);
/*--- The user may wish to close the regular expression -----------------*/
if (strcmp(Re, "ReClose") == 0)
{
/*--- Close Expression ----------------------------------------------*/
if (CompiledRe != NULL)
{
/*--- Free memory and clear pointer -----------------------------*/
free(CompiledRe);
CompiledRe = NULL;
ReleaseLastString();
}
RexSetUpOkRc(RxFunctionRc);
}
else
{
/*--- Compile the Passed Regular Expression -------------------------*/
CompiledRe = regcomp(Re);
if (CompiledRe != NULL)
RexSetUpOkRc(RxFunctionRc);
else
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not compile the regular expression %s (%s)", Re, ErrorReason);
}
/*--- Thats all Folks ---------------------------------------------------*/
REX_RETURN_TO_CMD();
}
/*===========================================================================*/
REX_DECLARE_REXX_ENTRY_POINT(RegExpMatch)
/* */
/* This routine requires the following parameters: */
/* */
/* 1. A string which we will attempt to match. */
/* */
/* Returns: */
/* */
/* 'N' = No Match. */
/* Start position and length of match (seperated by a space) */
/* */
/*===========================================================================*/
{
UCHAR * VariableName = REX_ASCIIZ_ARGV(1);
UCHAR VariableValue[255+1];
UCHAR * Ptr;
LongRc0IfOk AddRc;
int Index;
/*--- Make sure clear error buffer and clear last match string ----------*/
CLEAR_ERROR_BUFFER();
ReleaseLastString();
/*--- Validate parameter(s) ---------------------------------------------*/
RexCheckPassedVariableCountSetUpRcAndExitOnError(2);
/*--- Make sure that we have a regular expression to match against ------*/
if (CompiledRe == NULL)
{
/*--- Thats all Folks! ----------------------------------------------*/
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "You must call \"RegExpCompile\" first!");
REX_RETURN_TO_CMD();
}
/*--- Set up Success Rc -------------------------------------------------*/
RexSetUpRc(RxFunctionRc, "OK");
/*--- Make a copy of the string (work around to buggy regexp code) ------*/
LastString = strdup(REX_ASCIIZ_ARGV(0));
if (LastString == NULL)
{
/*--- Thats all Folks! ----------------------------------------------*/
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not duplicate the compare string (low memory?)!");
REX_RETURN_TO_CMD();
}
/*--- Look for a match --------------------------------------------------*/
if (regexec(CompiledRe, LastString) != 0)
{
/*--- Found the regular expression (output the overall match --------*/
Ptr = VariableValue + sprintf(VariableValue, "%d %d", 1+(CompiledRe->startp[0]-LastString), (CompiledRe->endp[0]-CompiledRe->startp[0]));
/*--- Add any subcomponents (stuff in round brackets) ---------------*/
for (Index=1; Index < NSUBEXP; Index++)
{
/*--- Exit if no such component ---------------------------------*/
if (CompiledRe->startp[Index] == NULL)
break;
/*--- Add next bit ----------------------------------------------*/
Ptr += sprintf(Ptr, " %d %d", 1+(CompiledRe->startp[Index]-LastString), (CompiledRe->endp[Index]-CompiledRe->startp[Index]));
}
}
else
{
/*--- Did not find a match, did we have a failure? ------------------*/
if (*ErrorReason != '\0')
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Failed trying to find regular expression (%s)", ErrorReason);
*VariableValue = '\0'; //Empty value on no match
ReleaseLastString();
}
/*--- Set up the answer -------------------------------------------------*/
AddRc = RexSetRexxVariable(VariableName, VariableValue);
if (AddRc != 0)
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not update the variable \"%s\" (Rc = %lu).", VariableName, AddRc);
/*--- Thats all Folks ---------------------------------------------------*/
REX_RETURN_TO_CMD();
}
/*===========================================================================*/
REX_DECLARE_REXX_ENTRY_POINT(RegExpReplace)
/* */
/* This routine requires the following parameters: */
/* */
/* 1. A string which we will modify. */
/* 2. Name of variable to hold modified string. */
/* */
/* Returns: */
/* */
/* "OK" unless error occurs. */
/*===========================================================================*/
{
UCHAR * ChangeSpec = REX_ASCIIZ_ARGV(0);
UCHAR * VariableName = REX_ASCIIZ_ARGV(1);
UCHAR * NewValue;
LongRc0IfOk AddRc;
/*--- Validate parameter(s) ---------------------------------------------*/
CLEAR_ERROR_BUFFER();
RexCheckPassedVariableCountSetUpRcAndExitOnError(2);
/*--- Make sure that we have a regular expression to match against ------*/
if (CompiledRe == NULL)
{
/*--- Die! ----------------------------------------------------------*/
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "You must call \"RegExpCompile\" first!");
REX_RETURN_TO_CMD();
}
if (LastString == NULL)
{
/*--- Die! ----------------------------------------------------------*/
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "You must call \"RegExpMatch\" first (and it should find a match)!");
REX_RETURN_TO_CMD();
}
/*--- Allocate memory for the change buffer -----------------------------*/
NewValue = malloc(50000);
if (NewValue == NULL)
{
/*--- Die! ----------------------------------------------------------*/
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not allocate memory for result!");
REX_RETURN_TO_CMD();
}
/*--- Make the changes --------------------------------------------------*/
regsub(CompiledRe, ChangeSpec, NewValue);
/*--- Set up the answer -------------------------------------------------*/
AddRc = RexSetRexxVariable(VariableName, NewValue);
free(NewValue);
if (AddRc != 0)
{
/*--- Die! ----------------------------------------------------------*/
RexSetUpErrorRc(MODULEID(), RxFunctionRc, "Could not update the variable \"%s\" (Rc = %lu).", VariableName, AddRc);
REX_RETURN_TO_CMD();
}
/*--- Thats all Folks ---------------------------------------------------*/
RexSetUpRc(RxFunctionRc, "OK");
REX_RETURN_TO_CMD();
}