rxregexp.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2014 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* https://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* Object REXX Support rxregexp.cpp */
40 /* Regular Expression Utility functions */
41 /* */
42 /******************************************************************************/
43 #include "dblqueue.hpp"
44 #include "automaton.hpp"
45 #include "regexp.hpp"
46 
47 #include "oorexxapi.h"
48 #include <string.h>
49 
50 // strcasecmp is called _stricmp by MSVC
51 #ifdef WIN32
52  #define strcasecmp _stricmp
53 #endif
54 
55 RexxMethod2(int, RegExp_Init, OPTIONAL_CSTRING, expression, OPTIONAL_CSTRING, matchtype)
56 {
57  int iResult = 0;
58  automaton *pAutomaton = new automaton();
59 
60  // optional matchtype given?
61  if (matchtype != NULL)
62  {
63  if (strcasecmp(matchtype, "MINIMAL") == 0)
64  {
65  pAutomaton->setMinimal(true);
66  }
67  else if (strcasecmp(matchtype, "MAXIMAL") == 0)
68  {
69  pAutomaton->setMinimal(false);
70  }
71  else
72  {
73  context->RaiseException0(Rexx_Error_Incorrect_method);
74  }
75 }
76 
77  // optional expression given?
78  if (expression != NULL)
79  {
80  iResult = pAutomaton->parse(expression);
81  if (iResult != 0)
82  {
83  context->RaiseException0(Rexx_Error_Invalid_template);
84  }
85  }
86 
87  // this will be passed back into us on calls
88  context->SetObjectVariable("CSELF", context->NewPointer(pAutomaton));
89 
90  return 0;
91 }
92 
93 RexxMethod1(int, RegExp_Uninit, CSELF, self)
94 {
95  automaton *pAutomaton = (automaton *)self;
96  if (pAutomaton != NULL)
97  {
98  delete pAutomaton;
99  }
100  // ensure we don't do this twice
101  context->DropObjectVariable("CSELF");
102  return 0;
103 }
104 
105 RexxMethod3(int, // Return type
106  RegExp_Parse, // Object_method name
107  CSELF, self, // Pointer to automaton control block
108  CSTRING, expression, // regular expression to parse
109  OPTIONAL_CSTRING, matchtype) // optional match type (MAXIMAL (def.) or MINIMAL)
110 {
111  automaton *pAutomaton = (automaton *)self;
112  // moved some ptrs to re-use variables
113  // optional matchtype given?
114  if (matchtype != NULL)
115  {
116  if ( strcasecmp(matchtype, "MINIMAL") == 0)
117  {
118  pAutomaton->setMinimal(true); // set minimal matching
119  }
120  else if (strcasecmp(matchtype, "MAXIMAL") == 0)
121  {
122  pAutomaton->setMinimal(false); // set maximal matching
123  }
124  else if (strcasecmp(matchtype, "CURRENT") == 0)
125  {
126  ; // keep current matching
127  }
128  else
129  {
130  context->RaiseException0(Rexx_Error_Incorrect_method);
131  }
132  }
133  int i = pAutomaton->parse( expression);
134  context->SetObjectVariable("!POS", context->WholeNumber(pAutomaton->getCurrentPos()));
135  return i;
136 }
137 
138 RexxMethod2(int, // Return type
139  RegExp_Match, // Object_method name
140  CSELF, self, // Pointer to self
141  RexxStringObject, string) // string to match
142 {
143  automaton *pAutomaton = (automaton *)self;
144  int i = pAutomaton->match( context->StringData(string), (int)context->StringLength(string));
145  context->SetObjectVariable("!POS", context->WholeNumber(pAutomaton->getCurrentPos()));
146  return i;
147 }
148 
149 RexxMethod2(int, // Return type
150  RegExp_Pos, // Object_method name
151  CSELF, self, // Pointer to self
152  RexxStringObject, string) // string to match
153 {
154  automaton *pAutomaton = (automaton *)self;
155  bool fOldState;
156  const char *pszString;
157  int strlength;
158  int i;
159 
160  pszString = context->StringData(string);
161  strlength = (int)context->StringLength(string);
162  int matchPosition = 0;
163 
164 // if (strlength > 0) // allow null string
165  {
166  fOldState = pAutomaton->getMinimal();
167 
168  // we start out matching minimal
169  pAutomaton->setMinimal(true);
170  do
171  {
172  i = pAutomaton->match(pszString, strlength);
173  strlength--;
174  pszString++;
175  } while (i == 0 && strlength >= 0);
176  // can we match at all?
177  if (i != 0)
178  {
179  i = (int) (pszString - context->StringData(string));
180  // want a maximal match within string?
181  if (fOldState == false)
182  {
183  pAutomaton->setMinimal(false);
184  pszString--; // correct starting pos
185  strlength++; // correct starting len
186  while (strlength >= 0)
187  {
188  if (pAutomaton->match(pszString, strlength) != 0)
189  {
190  break;
191  }
192  strlength--;
193  }
194  }
195  matchPosition = i + pAutomaton->getCurrentPos() - 1;
196  }
197 
198  context->SetObjectVariable("!POS", context->WholeNumber(matchPosition));
199  pAutomaton->setMinimal(fOldState); // restore to state at POS invocation time
200  return i;
201  }
202 
203  return 0;
204 }
205 
206 // now build the actual entry list
208 {
209  REXX_METHOD(RegExp_Init, RegExp_Init),
210  REXX_METHOD(RegExp_Uninit, RegExp_Uninit),
211  REXX_METHOD(RegExp_Parse, RegExp_Parse),
212  REXX_METHOD(RegExp_Pos, RegExp_Pos),
213  REXX_METHOD(RegExp_Match, RegExp_Match),
215 };
216 
217 
219 {
221  REXX_INTERPRETER_4_0_0, // anything after 4.0.0 will work
222  "rxregexp", // name of the package
223  "4.0", // package information
224  NULL, // no load/unload functions
225  NULL,
226  NULL, // no functions in this package
227  rxregexp_methods // the exported methods
228 };
229 
230 // package loading stub.
int getCurrentPos()
Definition: automaton.hpp:61
int match(const char *, int)
Definition: automaton.cpp:783
int parse(const char *)
Definition: automaton.cpp:191
bool getMinimal()
Definition: automaton.hpp:64
void setMinimal(bool)
Definition: automaton.cpp:90
#define REXX_INTERPRETER_4_0_0
Definition: oorexxapi.h:216
void * CSELF
Definition: oorexxapi.h:4329
#define REXX_METHOD(n, e)
Definition: oorexxapi.h:211
#define REXX_LAST_METHOD()
Definition: oorexxapi.h:212
#define STANDARD_PACKAGE_HEADER
Definition: oorexxapi.h:230
#define Rexx_Error_Incorrect_method
Definition: oorexxerrors.h:521
#define Rexx_Error_Invalid_template
Definition: oorexxerrors.h:365
const char * CSTRING
Definition: rexx.h:78
struct _RexxStringObject * RexxStringObject
Definition: rexx.h:128
RexxMethod2(int, RegExp_Init, OPTIONAL_CSTRING, expression, OPTIONAL_CSTRING, matchtype)
Definition: rxregexp.cpp:55
RexxMethodEntry rxregexp_methods[]
Definition: rxregexp.cpp:207
RexxMethod3(int, RegExp_Parse, CSELF, self, CSTRING, expression, OPTIONAL_CSTRING, matchtype)
Definition: rxregexp.cpp:105
RexxMethod1(int, RegExp_Uninit, CSELF, self)
Definition: rxregexp.cpp:93
OOREXX_GET_PACKAGE(rxregexp)
RexxPackageEntry rxregexp_package_entry
Definition: rxregexp.cpp:218
Definition: oorexxapi.h:198
Definition: oorexxapi.h:242