RexxCompoundTail.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.ibm.com/developerworks/oss/CPLv1.0.htm */
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 /* REXX Kernel RexxCompoundTail.cpp */
40 /* */
41 /* Support class for building a compound variable tail. */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "StringClass.hpp"
47 #include "RexxCompoundTail.hpp"
48 #include "BufferClass.hpp"
49 #include "Numerics.hpp"
50 #include "ExpressionVariable.hpp"
51 
52 
54  RexxObject **tails, /* tail elements */
55  size_t count) /* number of tail elements */
56 /******************************************************************************/
57 /* Function: Build a tail value from a set of tail elements without doing */
58 /* variable resolution. */
59 /******************************************************************************/
60 {
61  bool first = true; /* first tail piece indicator */
62 
63  for (size_t i = 0; i < count; i++)
64  {
65  if (!first)
66  { /* if not the first tail piece */
67  addDot(); /* add a dot to the buffer */
68  }
69  first = false; /* we need to add a dot from here on */
70  RexxObject *part = tails[i];
71  // this could be ommitted
72  if (part != OREF_NULL)
73  {
74  // if this is a variable, just copy the name. Otherwixe, copy the value
75  if (isOfClass(VariableTerm, part))
76  {
77  ((RexxParseVariable *)part)->getName()->copyIntoTail(this);
78  }
79  else
80  {
81  part->stringValue()->copyIntoTail(this);
82  }
83  }
84  }
85  length = current - tail; /* set the final, updated length */
86 }
87 
88 
90  RexxVariableDictionary *dictionary, /* source dictionary for tail piece values */
91  RexxObject **tails, /* the count of tail pieces */
92  size_t tailCount)
93 /******************************************************************************/
94 /* Function: Construct a tail from its elements */
95 /******************************************************************************/
96 {
97  if (tailCount == 1)
98  {
99  /* get the tail value */
100  RexxObject *_tail = tails[0]->getValue(dictionary);
101  /* if it is an integer type, we might be able to address the string representation directly. */
102  if (isInteger(_tail))
103  {
104  RexxString *rep = ((RexxInteger *)_tail)->getStringrep();
105  if (rep != OREF_NULL)
106  {
107  /* point directly to the value */
108  /* and the length */
109  this->tail = rep->getWritableData();
110  length = rep->getLength();
111  remainder = 0; /* belt and braces...this will force a reallocation if we append */
112  value = rep; /* save this reference in case we're asked for it later */
113  return;
114  }
115  }
116  /* if this is directly a string, we can use this directly */
117  if (isString(_tail))
118  {
119  /* point directly to the value */
120  /* and the length */
121  this->tail = ((RexxString *)_tail)->getWritableData();
122  length = ((RexxString *)_tail)->getLength();
123  remainder = 0; /* belt and braces...this will force a reallocation if we append */
124  value = (RexxString *)_tail; /* save this reference in case we're asked for it later */
125  return;
126  }
127  /* some other type of object, or an integer without a string */
128  /* rep. We need to have it do the copy operation. */
129  _tail->copyIntoTail(this);
130  length = current - this->tail; /* set the final, updated length */
131  }
132  else
133  {
134  tails[0]->getValue(dictionary)->copyIntoTail(this);
135  for (size_t i = 1; i < tailCount; i++) /* process each element */
136  {
137  addDot(); /* add a dot to the buffer */
138  tails[i]->getValue(dictionary)->copyIntoTail(this);
139  }
140 
141  length = current - tail; /* set the final, updated length */
142  }
143 }
144 
145 
147  RexxActivation *context, /* source context for tail piece values */
148  RexxObject **tails, /* the count of tail pieces */
149  size_t tailCount)
150 /******************************************************************************/
151 /* Function: Construct a tail from its elements */
152 /******************************************************************************/
153 {
154  if (tailCount == 1)
155  {
156  /* get the tail value */
157  RexxObject *_tail = tails[0]->getValue(context);
158  /* if it is an integer type, we might be able to address the string representation directly. */
159  if (isInteger(_tail))
160  {
161  RexxString *rep = ((RexxInteger *)_tail)->getStringrep();
162  if (rep != OREF_NULL)
163  {
164  /* point directly to the value */
165  /* and the length */
166  this->tail = rep->getWritableData();
167  length = rep->getLength();
168  remainder = 0; /* belt and braces...this will force a reallocation if we append */
169  value = rep; /* save this reference in case we're asked for it later */
170  return;
171  }
172  }
173  /* if this is directly a string, we can use this directly */
174  if (isString(_tail))
175  {
176  /* point directly to the value */
177  /* and the length */
178  this->tail = ((RexxString *)_tail)->getWritableData();
179  length = ((RexxString *)_tail)->getLength();
180  remainder = 0; /* belt and braces...this will force a reallocation if we append */
181  value = (RexxString *)_tail; /* save this reference in case we're asked for it later */
182  return;
183  }
184  /* some other type of object, or an integer without a string */
185  /* rep. We need to have it do the copy operation. */
186  _tail->copyIntoTail(this);
187  length = current - this->tail; /* set the final, updated length */
188  }
189  else
190  {
191  /* tail building buffer */
192  tails[0]->getValue(context)->copyIntoTail(this);
193  for (size_t i = 1; i < tailCount; i++) /* process each element */
194  {
195  addDot(); /* add a dot to the buffer */
196  tails[i]->getValue(context)->copyIntoTail(this);
197  }
198 
199  length = current - tail; /* set the final, updated length */
200  }
201 }
202 
203 
205  RexxObject **tails, /* tail elements */
206  size_t count) /* number of tail elements */
207 /******************************************************************************/
208 /* Function: Resolve the "stem.[a,b,c]=" pieces to a fullly qualified stem */
209 /* name. */
210 /******************************************************************************/
211 {
212  bool first = true; /* first tail piece indicator */
213 
214  for (size_t i = 0; i < count; i++)
215  {
216  if (!first) /* if not the first tail piece */
217  {
218  addDot(); /* add a dot to the buffer */
219  }
220  first = false; /* we need to add a dot from here on */
221  RexxString *part = (RexxString *)tails[i]; /* get the next element */
222  if (part == OREF_NULL) /* omitted piece? */
223  {
224  part = OREF_NULLSTRING; /* use a null string */
225  }
226  part->copyIntoTail(this); /* add this to our tail */
227  }
228  length = current - tail; /* set the final, updated length */
229 }
230 
231 
233  RexxString *_tail) /* the single string index */
234 /******************************************************************************/
235 /* Function: Construct a tail from a single string index */
236 /******************************************************************************/
237 {
238  /* point directly to the value */
239  this->tail = _tail->getWritableData();
240  length = _tail->getLength(); /* and the length */
241  remainder = 0; /* belt and braces...this will force a reallocation if we append */
242  value = _tail; /* save this reference in case we're asked for it later */
243 }
244 
245 
246 /**
247  * Build a tail directly from a single character string value.
248  *
249  * @param t The pointer to the tail name (as an asciiz string);
250  */
251 void RexxCompoundTail::buildTail(const char *t)
252 {
253  this->tail = const_cast<char *>(t);
254  length = strlen(t);
255  remainder = 0;
256 }
257 
258 
260  RexxString *_tail, size_t index) /* the single string index */
261 /******************************************************************************/
262 /* Function: Construct a tail from a string and an index */
263 /******************************************************************************/
264 {
265  /* point directly to the value */
266  if (_tail->getStringData() != OREF_NULL)
267  {
268  _tail->copyIntoTail(this); /* add this to our tail */
269  }
270  length = length + _tail->getLength();
272  current += length;
273  remainder -= length;
274 }
275 
277  size_t index) /* the single numeric index */
278 /******************************************************************************/
279 /* Function: Construct a tail from a single numeric index */
280 /******************************************************************************/
281 {
283  length = strlen((char *)current);
284  current += length;
285  remainder -= length;
286 }
287 
288 
290  size_t needed) /* length we require */
291 /******************************************************************************/
292 /* Function: Ensure the buffer has sufficient space */
293 /******************************************************************************/
294 {
295  length = current - tail; /* update the accumulated length */
296 
297  if (temp != OREF_NULL) /* have we already allocated a buffer? */
298  {
299  /* expand the size of our existing buffer */
300  temp->expand(needed + ALLOCATION_PAD);
301  tail = temp->getData();
302  current = tail + length;
303  remainder += needed + ALLOCATION_PAD;
304  }
305  else
306  {
307  /* get a new buffer size */
308  size_t newLength = length + needed + ALLOCATION_PAD;
309  temp = (RexxBuffer *)new_buffer(newLength);
310  p = temp; // this protects the buffer
311  tail = temp->getData();
312  current = tail + length;
313  memcpy(tail, buffer, length); /* make sure we copy the old data */
314  remainder = newLength - length; /* set the new remainder */
315  }
316 }
317 
318 
320 /******************************************************************************/
321 /* Function: Create a fully resolved compound name from a tail buffer */
322 /******************************************************************************/
323 {
324  size_t len1 = stem->getLength(); /* get the stem length */
325  /* create a new string */
326  RexxString *result = (RexxString *)raw_string(len1 + length);
327  char *data = result->getWritableData(); /* point to the string data */
328  if (len1 != 0) /* have real data? */
329  {
330  /* copy the front part */
331  memcpy(data, stem->getStringData(), len1);
332  data += len1; /* step past the length */
333  }
334  if (length != 0) /* have a second length */
335  {
336  /* and the second part */
337  memcpy(data, tail, length);
338  }
339  return result; /* return the result */
340 
341 }
342 
344 {
345  if (value == NULL)
346  {
347  /* create a new string */
349  }
350  return value; /* return the result */
351 }
RexxBuffer * new_buffer(size_t s)
bool isInteger(RexxObject *o)
Definition: RexxCore.h:282
#define OREF_NULL
Definition: RexxCore.h:61
bool isString(RexxObject *o)
Definition: RexxCore.h:281
#define isOfClass(t, r)
Definition: RexxCore.h:224
RexxString * raw_string(stringsize_t l)
RexxString * new_string(const char *s, stringsize_t l)
static size_t formatWholeNumber(wholenumber_t integer, char *dest)
Definition: Numerics.cpp:572
virtual char * getData()
RexxBuffer * expand(size_t)
Definition: BufferClass.cpp:63
ProtectedObject p
RexxString * makeString()
void expandCapacity(size_t needed)
char buffer[MAX_SYMBOL_LENGTH]
void buildUnresolvedTail(RexxObject **tails, size_t count)
void buildTail(RexxVariableDictionary *dictionary, RexxObject **tails, size_t tailCount)
RexxString * createCompoundName(RexxString *)
virtual RexxObject * getValue(RexxActivation *)
RexxString * stringValue()
void copyIntoTail(RexxCompoundTail *buffer)
size_t getLength()
const char * getStringData()
char * getWritableData()
void copyIntoTail(RexxCompoundTail *buffer)