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-2009 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 /* http://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 RexxMethod2(int, RegExp_Init, OPTIONAL_CSTRING, expression, OPTIONAL_CSTRING, matchtype)
51 {
52  int iResult = 0;
53  automaton *pAutomaton = new automaton();
54 
55  // optional matchtype given?
56  if (matchtype != NULL)
57  {
58  if (strcmp(matchtype, "MINIMAL") == 0)
59  {
60  pAutomaton->setMinimal(true);
61  }
62  }
63 
64  // optional expression given?
65  if (expression != NULL)
66  {
67  iResult = pAutomaton->parse(expression);
68  if (iResult != 0)
69  {
70  context->RaiseException0(Rexx_Error_Invalid_template);
71  }
72  }
73 
74  // this will be passed back into us on calls
75  context->SetObjectVariable("CSELF", context->NewPointer(pAutomaton));
76 
77  return 0;
78 }
79 
80 RexxMethod1(int, RegExp_Uninit, CSELF, self)
81 {
82  automaton *pAutomaton = (automaton *)self;
83  if (pAutomaton != NULL)
84  {
85  delete pAutomaton;
86  }
87  // ensure we don't do this twice
88  context->DropObjectVariable("CSELF");
89  return 0;
90 }
91 
92 RexxMethod3(int, // Return type
93  RegExp_Parse, // Object_method name
94  CSELF, self, // Pointer to automaton control block
95  CSTRING, expression, // regular expression to parse
96  OPTIONAL_CSTRING, matchtype) // optional match type (MAXIMAL (def.) or MINIMAL)
97 {
98  automaton *pAutomaton = (automaton *)self;
99  // moved some ptrs to re-use variables
100  // optional matchtype given?
101  if (matchtype != NULL)
102  {
103  if ( strcmp(matchtype, "MINIMAL") == 0)
104  {
105  pAutomaton->setMinimal(true); // set minimal matching
106  }
107  else if (strcmp(matchtype, "CURRENT") != 0)
108  {
109  pAutomaton->setMinimal(false); // set maximal matching
110  }
111  }
112  int i = pAutomaton->parse( expression);
113  context->SetObjectVariable("!POS", context->WholeNumber(pAutomaton->getCurrentPos()));
114  return i;
115 }
116 
117 RexxMethod2(int, // Return type
118  RegExp_Match, // Object_method name
119  CSELF, self, // Pointer to self
120  RexxStringObject, string) // string to match
121 {
122  automaton *pAutomaton = (automaton *)self;
123  int i = pAutomaton->match( context->StringData(string), (int)context->StringLength(string));
124  context->SetObjectVariable("!POS", context->WholeNumber(pAutomaton->getCurrentPos()));
125  return i;
126 }
127 
128 RexxMethod2(int, // Return type
129  RegExp_Pos, // Object_method name
130  CSELF, self, // Pointer to self
131  RexxStringObject, string) // string to match
132 {
133  automaton *pAutomaton = (automaton *)self;
134  bool fOldState;
135  const char *pszString;
136  size_t strlength;
137  int i;
138 
139  pszString = context->StringData(string);
140  strlength = context->StringLength(string);
141  int matchPosition = 0;
142 
143  /* only check when input > 0 */
144  if (strlength > 0)
145  {
146  fOldState = pAutomaton->getMinimal();
147 
148  // we start out matching minimal
149  pAutomaton->setMinimal(true);
150  do
151  {
152  i = pAutomaton->match(pszString, (int)strlength);
153  strlength--;
154  pszString++;
155  } while (i == 0 && strlength != 0);
156  // can we match at all?
157  if (i != 0)
158  {
159  i = (int) (pszString - context->StringData(string));
160  // want a maximal match within string?
161  if (fOldState == false)
162  {
163  pAutomaton->setMinimal(false);
164  pszString--; // correct starting pos
165  strlength++; // correct starting len
166  while (strlength != 0)
167  {
168  if (pAutomaton->match(pszString, (int)strlength) != 0)
169  {
170  break;
171  }
172  strlength--;
173  }
174  }
175  matchPosition = i + pAutomaton->getCurrentPos() - 1;
176  }
177 
178  context->SetObjectVariable("!POS", context->WholeNumber(matchPosition));
179  pAutomaton->setMinimal(fOldState); // restore to state at POS invocation time
180  return i;
181  }
182 
183  return 0;
184 }
185 
186 // now build the actual entry list
188 {
189  REXX_METHOD(RegExp_Init, RegExp_Init),
190  REXX_METHOD(RegExp_Uninit, RegExp_Uninit),
191  REXX_METHOD(RegExp_Parse, RegExp_Parse),
192  REXX_METHOD(RegExp_Pos, RegExp_Pos),
193  REXX_METHOD(RegExp_Match, RegExp_Match),
195 };
196 
197 
199 {
201  REXX_INTERPRETER_4_0_0, // anything after 4.0.0 will work
202  "RXREGEXP", // name of the package
203  "4.0", // package information
204  NULL, // no load/unload functions
205  NULL,
206  NULL, // no functions in this package
207  rxregexp_methods // the exported methods
208 };
209 
210 // package loading stub.
int getCurrentPos()
Definition: automaton.hpp:61
int match(const char *, int)
Definition: automaton.cpp:696
int parse(const char *)
Definition: automaton.cpp:117
bool getMinimal()
Definition: automaton.hpp:64
void setMinimal(bool)
Definition: automaton.cpp:89
#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_Invalid_template
Definition: oorexxerrors.h:324
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:50
RexxMethodEntry rxregexp_methods[]
Definition: rxregexp.cpp:187
RexxMethod3(int, RegExp_Parse, CSELF, self, CSTRING, expression, OPTIONAL_CSTRING, matchtype)
Definition: rxregexp.cpp:92
RexxMethod1(int, RegExp_Uninit, CSELF, self)
Definition: rxregexp.cpp:80
OOREXX_GET_PACKAGE(rxregexp)
RexxPackageEntry rxregexp_package_entry
Definition: rxregexp.cpp:198
Definition: oorexxapi.h:198
Definition: oorexxapi.h:242