ooRexx  4.2.0-source
About: ooRexx (Open Object Rexx) is a free implementation of Object Rexx. Object Rexx is an enhancement of the classic Rexx interpreter; a full-featured programming language with a human-oriented syntax.
  Fossies Dox: ooRexx-4.2.0-source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

StringClass.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 /* REXX Kernel StringClass.c */
40 /* */
41 /* Primitive String Class */
42 /* */
43 /******************************************************************************/
44 #include <ctype.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <math.h>
48 #include <limits>
49 
50 #include "RexxCore.h"
51 #include "StringClass.hpp"
52 #include "DirectoryClass.hpp"
53 #include "RexxActivation.hpp"
54 #include "RexxActivity.hpp"
55 #include "ProtectedObject.hpp"
56 #include "StringUtil.hpp"
57 #include "RexxCompoundTail.hpp"
58 #include "SystemInterpreter.hpp"
59 
60 // singleton class instance
62 
63 
68 {
69  CLASS_CREATE(String, "String", RexxClass);
70 }
71 
72 
74 /******************************************************************************/
75 /* Function: retrieve the hash value of a string object */
76 /******************************************************************************/
77 {
78  if (!isString(this)) /* a nonprimitive object? */
79  {
80  /* see if == overridden. */
81  return this->sendMessage(OREF_STRICT_EQUAL)->requestString()->getStringHash();
82  }
83  else
84  {
85  return this->getHashValue(); /* return the string hash */
86  }
87 }
88 
89 
96 {
97  // this will calculate the hash if it hasn't been done yet
98  return getStringHash();
99 }
100 
101 
109 {
110  HashCode h;
111 
112  // ok, we need to pick this string apart and turn this into a numeric code
113  // a null string is simple.
114  if (getLength() == 0)
115  {
116  h = 1;
117  }
118 
119  // if we have at least 4 characters, use them as binary, since that's
120  // what is normally returned here.
121  else if (getLength() >= sizeof(HashCode))
122  {
123  h = *((HashCode *)getStringData());
124  }
125  else
126  {
127  // either 1 or 2 characters. Just pick up a short value, which will
128  // also pick up terminating null if only a single character
129  h = *((short *)getStringData());
130  }
131  return h;
132 }
133 
134 
135 
136 void RexxString::live(size_t liveMark)
137 /******************************************************************************/
138 /* Function: Normal garbage collection live marking */
139 /******************************************************************************/
140 {
141  memory_mark(this->NumberString);
142  memory_mark(this->objectVariables);
143 }
144 
145 void RexxString::liveGeneral(int reason)
146 /******************************************************************************/
147 /* Function: Generalized object marking */
148 /******************************************************************************/
149 {
151  memory_mark_general(this->objectVariables);
152 }
153 
155 /******************************************************************************/
156 /* Function: Flatten an object */
157 /******************************************************************************/
158 {
160 
161  flatten_reference(newThis->NumberString, envelope);
162  flatten_reference(newThis->objectVariables, envelope);
163 
165 }
166 
168 /******************************************************************************/
169 /* Function: unflatten an object */
170 /******************************************************************************/
171 {
172  if (this->isProxyObject())
173  { /* is this a proxy object? */
174  // just perform an environment lookup
175  return TheEnvironment->entry(this);
176  }
177  else
178  {
179  // perform a normal default unflatten op.
180  return this->RexxObject::unflatten(envelope);
181  }
182 }
183 
185 /******************************************************************************/
186 /* Function: Return the primitive string value of this object */
187 /******************************************************************************/
188 {
189  if (isOfClass(String, this)) /* already a primitive string? */
190  {
191  return this; /* just return our selves */
192  }
193  else /* need to build a new string */
194  {
195  return new_string(this->getStringData(), this->getLength());
196  }
197 }
198 
200 /******************************************************************************/
201 /* Function: Handle a REQUEST('STRING') request for a REXX string object */
202 /******************************************************************************/
203 {
204  if (this->isBaseClass()) /* really a primitive string? */
205  {
206  return this; /* this is easy */
207  }
208  else /* need to create a new string */
209  {
210  return new_string(this->getStringData(), this->getLength());
211  }
212 }
213 
220 {
221  // forward to the Rexx version with default arguments
222  return this->makeArrayRexx(OREF_NULL);
223 }
224 
225 
227 /******************************************************************************/
228 /* Function: Handle a tail construction request for an internal object */
229 /******************************************************************************/
230 {
231  /* copy this directly into the tail */
232  tail->append(this->getStringData(), this->getLength());
233 }
234 
235 
237 /******************************************************************************/
238 /* Function: Handle a REQUEST('STRING') request for a REXX string object */
239 /******************************************************************************/
240 {
241  return this; /* this is easy */
242 }
243 
245 /******************************************************************************/
246 /* Function: Convert a string object to a long value. Returns false */
247 /* it will not convert. */
248 /******************************************************************************/
249 {
250  if (!(isString(this))) /* subclassed string object? */
251  {
252  return this->requestString()->numberValue(result, digits);
253  }
254  /* get the string value's long value */
255  RexxNumberString *numberstring = this->fastNumberString();
256  if (numberstring != OREF_NULL ) /* convert ok? */
257  {
258  /* convert to integer with proper */
259  /* precision */
260  return numberstring->numberValue(result, digits);
261  }
262  return false; /* return the "not value long" value */
263 }
264 
266 /******************************************************************************/
267 /* Function: Convert a string object to a long value. Returns false */
268 /* it will not convert. */
269 /******************************************************************************/
270 {
271  if (!(isString(this))) /* subclassed string object? */
272  {
273  return this->requestString()->numberValue(result);
274  }
275  /* get the string value's long value */
276  RexxNumberString *numberstring = this->fastNumberString();
277  if (numberstring != OREF_NULL ) /* convert ok? */
278  {
279  /* convert to integer with proper */
280  /* precision */
281  return numberstring->numberValue(result);
282  }
283  return false; /* return the "not value long" value */
284 }
285 
286 
288 /******************************************************************************/
289 /* Function: Convert a string object to a long value. Returns false */
290 /* it will not convert. */
291 /******************************************************************************/
292 {
293  if (!(isString(this))) /* subclassed string object? */
294  {
295  return this->requestString()->unsignedNumberValue(result, digits);
296  }
297  /* get the string value's long value */
298  RexxNumberString *numberstring = this->fastNumberString();
299  if (numberstring != OREF_NULL ) /* convert ok? */
300  {
301  /* convert to integer with proper */
302  /* precision */
303  return numberstring->unsignedNumberValue(result, digits);
304  }
305  return false; /* return the "not value long" value */
306 }
307 
308 
310 /******************************************************************************/
311 /* Function: Convert a string object to a long value. Returns false */
312 /* it will not convert. */
313 /******************************************************************************/
314 {
315  if (!(isString(this))) /* subclassed string object? */
316  {
317  return this->requestString()->unsignedNumberValue(result);
318  }
319  /* get the string value's long value */
320  RexxNumberString *numberstring = this->fastNumberString();
321  if (numberstring != OREF_NULL ) /* convert ok? */
322  {
323  /* convert to integer with proper */
324  /* precision */
325  return numberstring->unsignedNumberValue(result);
326  }
327  return false; /* return the "not value long" value */
328 }
329 
330 bool RexxString::doubleValue(double &result)
331 /******************************************************************************/
332 /* Function: Convert a string object to a double value */
333 /******************************************************************************/
334 {
335  RexxNumberString *numberDouble = this->fastNumberString(); /* convert String to Numberstring */
336  if (numberDouble != OREF_NULL) /* Did we get a numberstring? */
337  {
338  return numberDouble->doubleValue(result);/* Yup, convert it to double */
339  }
340  // non numeric, so this could be one of the special cases
341  if (strCompare("nan"))
342  {
343  result = std::numeric_limits<double>::signaling_NaN();
344  // this will be false if this is really a NaN value. If true,
345  // then fall back and use the quiet version.
346  if (!isnan(result))
347  {
348  result = std::numeric_limits<double>::quiet_NaN();
349  }
350  return true;
351  }
352  if (strCompare("+infinity"))
353  {
354  result = +HUGE_VAL;
355  return true;
356  }
357  if (strCompare("-infinity"))
358  {
359  result = -HUGE_VAL;
360  return true;
361  }
362  return false; /* not number string, so NODOUBLE */
363 }
364 
365 
367 /******************************************************************************/
368 /* Function: Convert a String Object into a Number Object */
369 /******************************************************************************/
370 {
371  RexxString *newSelf; /* converted string value */
372 
373  if (this->nonNumeric()) /* Did we already try and convert to */
374  {
375  /* to a numberstring and fail? */
376  return OREF_NULL; /* Yes, no need to try agian. */
377  }
378 
379  if (this->NumberString != OREF_NULL) /* see if we have already converted */
380  {
381  return this->NumberString; /* return the numberString Object. */
382  }
383 
384  if (!isOfClass(String, this))
385  { /* not truly a string type? */
386  newSelf = this->requestString(); /* do the conversion */
387  /* get a new numberstring Obj */
388  OrefSet(this, this->NumberString, (RexxNumberString *)new_numberstring(newSelf->getStringData(), newSelf->getLength()));
389  if (this->NumberString != OREF_NULL) /* Did number convert OK? */
390  {
391  this->setHasReferences(); /* Make sure we are sent Live... */
392  }
393  }
394  else
395  { /* real primitive string */
396  /* get a new numberstring Obj */
398  if (this->NumberString == OREF_NULL) /* Did number convert OK? */
399  {
400  this->setNonNumeric(); /* mark as a nonnumeric */
401  }
402  else
403  {
404  this->setHasReferences(); /* Make sure we are sent Live... */
405  /* connect the string and number */
406  this->NumberString->setString(this);
407  }
408  }
409  return this->NumberString; /* return the numberString Object. */
410 }
411 
413 /******************************************************************************/
414 /* Function: Convert a String Object into a Number Object */
415 /******************************************************************************/
416 {
417  RexxString *newSelf; /* converted string value */
418 
419  if (!isOfClass(String, this))
420  { /* not truly a string type? */
421  newSelf = this->requestString(); /* do the conversion */
422  /* get a new numberstring Obj */
423  OrefSet(newSelf, newSelf->NumberString, (RexxNumberString *)new_numberstring(newSelf->getStringData(), newSelf->getLength()));
424  /* save the number string */
425  if (newSelf->NumberString != OREF_NULL) /* Did number convert OK? */
426  {
427  newSelf->setHasReferences(); /* Make sure we are sent Live... */
428  }
429  return newSelf->NumberString;
430  }
431  else
432  { /* real primitive string */
433  /* get a new numberstring Obj */
435  if (this->NumberString == OREF_NULL) /* Did number convert OK? */
436  {
437  this->setNonNumeric(); /* mark as a nonnumeric */
438  }
439  else
440  {
441  this->setHasReferences(); /* Make sure we are sent Live... */
442  /* connect the string and number */
443  this->NumberString->setString(this);
444  }
445  return this->NumberString;
446  }
447 }
448 
449 
450 size_t RexxString::copyData(size_t startPos, char *buffer, size_t bufl)
451 /******************************************************************************/
452 /* Function: Get a section of a string and copy it into a buffer */
453 /******************************************************************************/
454 {
455  size_t copylen = 0;
456 
457  if (startPos < this->getLength())
458  {
459  if (bufl <= this->getLength() - startPos)
460  {
461  copylen = bufl;
462  }
463  else
464  {
465  copylen = this->getLength() - startPos;
466  }
467  memcpy(buffer, this->getStringData() + startPos, (size_t)copylen);
468  }
469 
470  return copylen;
471 }
472 
474 /******************************************************************************/
475 /* Function: Return the length of a string as an integer object */
476 /******************************************************************************/
477 {
478  /* return string byte length */
479  return new_integer(getLength());
480 }
481 
483  RexxObject *otherObj) /* other comparison object */
484 /******************************************************************************/
485 /* Function: Primitive strict equal\not equal method. This determines */
486 /* only strict equality, not greater or less than values. */
487 /******************************************************************************/
488 {
489  requiredArgument(otherObj, ARG_ONE); /* this is required. */
490  if (!this->isBaseClass()) /* not a primitive? */
491  {
492  /* do the full lookup compare */
493  return this->sendMessage(OREF_STRICT_EQUAL, otherObj)->truthValue(Error_Logical_value_method);
494  }
495 
496  if (otherObj == TheNilObject) // strings never compare equal to the NIL object
497  {
498  return false;
499  }
500 
501  RexxString *other = REQUEST_STRING(otherObj); /* force into string form */
502  size_t otherLen = other->getLength(); /* get length of second string. */
503  if (otherLen != this->getLength()) /* lengths different? */
504  {
505  return false; /* also unequal */
506  }
507  /* now compare the actual string */
508  return !memcmp(this->getStringData(), other->getStringData(), otherLen);
509 }
510 
512  RexxObject *otherObj) /* other comparison object */
513 /******************************************************************************/
514 /* Function: Primitive strict equal\not equal method. This determines */
515 /* only strict equality, not greater or less than values. */
516 /******************************************************************************/
517 {
518  requiredArgument(otherObj, ARG_ONE); /* this is required. */
519  if (otherObj == TheNilObject) // strings never compare equal to the NIL object
520  {
521  return false;
522  }
523 
524  RexxString *other = REQUEST_STRING(otherObj); /* force into string form */
525  size_t otherLen = other->getLength(); /* get length of second string. */
526  if (otherLen != this->getLength()) /* lengths different? */
527  {
528  return false; /* also unequal */
529  }
530  /* now compare the actual string */
531  return !memcmp(this->getStringData(), other->getStringData(), otherLen);
532 }
533 
534 
543 {
544  // we have one required string object
545  requiredArgument(otherObj, ARG_ONE);
546  if (otherObj == TheNilObject) // strings never compare equal to the NIL object
547  {
548  return false;
549  }
550  RexxString *other = REQUEST_STRING(otherObj);
551  stringsize_t otherLen = other->getLength();
552  // can't compare equal if different lengths
553  if (otherLen != this->getLength())
554  {
555  return false;
556  }
557  // do the actual string compare
558  return StringUtil::caselessCompare(this->getStringData(), other->getStringData(), otherLen) == 0;
559 }
560 
561 
571 {
572  if (this->isBaseClass())
573  {
574  return compareToRexx((RexxString *)other, OREF_NULL, OREF_NULL)->getValue();
575  }
576  else
577  {
578  return RexxObject::compareTo(other);
579  }
580 }
581 
582 
584 /******************************************************************************/
585 /* Function: Do a value comparison of two strings for the non-strict */
586 /* comparisons. This returns for the compares: */
587 /* */
588 /* a value < 0 when this is smaller than other */
589 /* a value 0 when this is equal to other */
590 /* a value > 0 when this is larger than other */
591 /******************************************************************************/
592 {
593  RexxString *second; /* string value of other */
594  RexxNumberString *firstNum; /* numberstring value of this */
595  RexxNumberString *secondNum; /* numberstring value of other */
596  const char *firstStart; /* comparison start pointer */
597  const char *secondStart; /* other start pointer */
598  size_t firstLen; /* this compare length */
599  size_t secondLen; /* other compare length */
600  wholenumber_t result; /* compare result */
601 
602  /* We need to see if the objects can */
603  /* be Converted to NumberString Objs */
604  /* 1st, this way we know if the COMP */
605  /* method of number String will */
606  /* succeed. Will only fail if an */
607  /* object cannot be represented as a */
608  /* number. This is important since */
609  /* NumberString calls String to do */
610  /* the compare if it can't, since */
611  /* this is the method NumberString */
612  /* will call, we must make sure a */
613  /* call to NumberString succeeds or */
614  /* we will get into a loop. */
615  requiredArgument(other, ARG_ONE); /* make sure we have a real argument */
616  if (other == TheNilObject) // all conditionals return .false when compared to .nil
617  {
618  return false;
619  }
620  /* try and convert both numbers */
621  if (((firstNum = this->fastNumberString()) != OREF_NULL) && ((secondNum = other->numberString()) != OREF_NULL ))
622  {
623  /* yes, send converted numbers and do*/
624  /* the compare */
625  return firstNum->comp(secondNum);
626  }
627  second = REQUEST_STRING(other); /* yes, get a string object. */
628  /* objects are converted. now strip */
629  /* any leading/trailing blanks. */
630 
631  firstLen = this->getLength(); /* get the initial length */
632  firstStart = this->getStringData(); /* and starting position */
633 
634  secondLen = second->getLength(); /* get length of second string. */
635  secondStart = second->getStringData(); /* get pointer to start of data */
636 
637  /* while we have leading blanks. */
638  while (firstLen > 0 && (*firstStart == ch_BLANK || *firstStart == ch_TAB))
639  {
640  firstStart++; /* ignore character and look at next */
641  firstLen--; /* and string is now one char less. */
642  }
643  /* while we have leading blanks. */
644  while (secondLen > 0 && (*secondStart == ch_BLANK || *secondStart == ch_TAB))
645  {
646  secondStart++; /* ignore character and look at next */
647  secondLen--; /* and string is now one char less. */
648  }
649 
650  if (firstLen >= secondLen)
651  { /* determine the longer string. */
652  /* first string is larger, */
653 
654  /* do a memory compare of strings, */
655  /* use length of smaller string. */
656  result = memcmp(firstStart, secondStart, (size_t) secondLen);
657  /* equal but different lengths? */
658  if ((result == 0) && (firstLen != secondLen))
659  {
660  /* point to first remainder char */
661  firstStart = firstStart + secondLen;
662  while (firstLen-- > secondLen)
663  { /* while still have more to compare */
664  // Need unsigned char or chars above 0x7f will compare as less than
665  // blank.
666  unsigned char current = *firstStart++;
667  if (current != ch_BLANK && current != ch_TAB)
668  {
669  return current - ch_BLANK;
670  }
671  }
672  }
673  }
674 
675  else
676  { /* The length of second obj is longer*/
677  /* do memory compare of strings, use */
678  /* length of smaller string. */
679  result = memcmp(firstStart, secondStart, (size_t) firstLen);
680  if (result == 0)
681  { /* if strings compared equal, we have*/
682  /* we need to compare the trailing */
683  /* part with blanks */
684  secondStart = secondStart + firstLen;
685  while (secondLen-- > firstLen)
686  { /* while the longer string stills has*/
687  // Need unsigned char or chars above 0x7f will compare as less than
688  // blank.
689  unsigned char current = *secondStart++;
690  if (current != ch_BLANK && current != ch_TAB)
691  {
692  return ch_BLANK - current;
693  }
694  }
695  }
696  }
697  return result; /* return the compare result */
698 }
699 
701 /******************************************************************************/
702 /* Function: Do a strict comparison of two strings. This returns: */
703 /* */
704 /* a value < 0 when this is smaller than other */
705 /* a value 0 when this is equal to other */
706 /* a value > 0 when this is larger than other */
707 /******************************************************************************/
708 {
709  wholenumber_t result; /* compare result */
710 
711  requiredArgument(otherObj, ARG_ONE); /* this is required. */
712  RexxString *other = REQUEST_STRING(otherObj); /* force into string form */
713  size_t otherLen = other->getLength(); /* get length of second string. */
714  const char *otherData = other->getStringData(); /* get pointer to start of data. */
715 
716  if (this->getLength() >= otherLen)
717  { /* determine the longer string. */
718  /* first string is larger, */
719  /* do a memory compare of strings, */
720  /* use length of smaller string. */
721  result = memcmp(this->getStringData(), otherData, (size_t) otherLen);
722  /* if strings are equal, and */
723  /* are not equal, the self is greater*/
724  if ((result == 0) && (this->getLength() > otherLen))
725  {
726  result = 1; /* otherwise they are equal. */
727  }
728  }
729  else
730  { /* The length of second obj is longer*/
731  /* do memory compare of strings, use */
732  /* length of smaller string. */
733  result = memcmp(this->getStringData(), otherData, (size_t) this->getLength());
734  if (result == 0) /* if stings compared equal, */
735  {
736  result = -1; /* then the other string is bigger. */
737  }
738  }
739  return result; /* finished, return our result */
740 }
741 
743 /******************************************************************************/
744 /* Function: String addition...performed by RexxNumberString */
745 /******************************************************************************/
746 {
747  RexxNumberString *numstr; /* converted number string */
748 
749  /* non-numeric? */
750  if ((numstr = this->fastNumberString()) == OREF_NULL)
751  {
752  /* this is a conversion error */
754  }
755  return numstr->plus(right_term); /* have numberstring do this */
756 }
757 
759 /******************************************************************************/
760 /* Function: String subtraction...performed by RexxNumberString */
761 /******************************************************************************/
762 {
763  RexxNumberString *numstr; /* converted number string */
764 
765  /* non-numeric? */
766  if ((numstr = this->fastNumberString()) == OREF_NULL)
767  {
768  /* this is a conversion error */
770  }
771  return numstr->minus(right_term); /* have numberstring do this */
772 }
773 
775 /******************************************************************************/
776 /* Function: String multiplication...performed by RexxNumberString */
777 /******************************************************************************/
778 {
779  RexxNumberString *numstr; /* converted number string */
780 
781  /* non-numeric? */
782  if ((numstr = this->fastNumberString()) == OREF_NULL)
783  {
784  /* this is a conversion error */
786  }
787  return numstr->multiply(right_term); /* have numberstring do this */
788 }
789 
791 /******************************************************************************/
792 /* Function: String division...performed by RexxNumberString */
793 /******************************************************************************/
794 {
795  RexxNumberString *numstr; /* converted number string */
796 
797  /* non-numeric? */
798  if ((numstr = this->fastNumberString()) == OREF_NULL)
799  {
800  /* this is a conversion error */
802  }
803  return numstr->divide(right_term); /* have numberstring do this */
804 }
805 
807 /******************************************************************************/
808 /* Function: String division...performed by RexxNumberString */
809 /******************************************************************************/
810 {
811  RexxNumberString *numstr; /* converted number string */
812 
813  /* non-numeric? */
814  if ((numstr = this->fastNumberString()) == OREF_NULL)
815  {
816  /* this is a conversion error */
818  }
819  return numstr->integerDivide(right_term); /* have numberstring do this */
820 }
821 
823 /******************************************************************************/
824 /* Function: String division...performed by RexxNumberString */
825 /******************************************************************************/
826 {
827  RexxNumberString *numstr; /* converted number string */
828 
829  /* non-numeric? */
830  if ((numstr = this->fastNumberString()) == OREF_NULL)
831  {
832  /* this is a conversion error */
834  }
835  return numstr->remainder(right_term); /* have numberstring do this */
836 }
837 
839 /******************************************************************************/
840 /* Function: String division...performed by RexxNumberString */
841 /******************************************************************************/
842 {
843  RexxNumberString *numstr; /* converted number string */
844 
845  /* non-numeric? */
846  if ((numstr = this->fastNumberString()) == OREF_NULL)
847  {
848  /* this is a conversion error */
850  }
851  return numstr->power(right_term); /* have numberstring do this */
852 }
853 
855 /******************************************************************************/
856 /* Function: String absolute value...performed by RexxNumberString */
857 /******************************************************************************/
858 {
859  RexxNumberString *numstr; /* converted number string */
860 
861  /* non-numeric? */
862  if ((numstr = this->fastNumberString()) == OREF_NULL)
863  {
864  /* this is a conversion error */
866  }
867  return numstr->abs(); /* have numberstring do this */
868 }
869 
871 /******************************************************************************/
872 /* Function: String sign value...performed by RexxNumberString */
873 /******************************************************************************/
874 {
875  RexxNumberString *numstr; /* converted number string */
876 
877  /* non-numeric? */
878  if ((numstr = this->fastNumberString()) == OREF_NULL)
879  {
880  /* this is a conversion error */
882  }
883  return numstr->Sign(); /* have numberstring do this */
884 }
885 
886 RexxObject *RexxString::Max(RexxObject **arguments, size_t argCount)
887 /******************************************************************************/
888 /* Function: String max value...performed by RexxNumberString */
889 /******************************************************************************/
890 {
891  RexxNumberString *numstr; /* converted number string */
892 
893  /* non-numeric? */
894  if ((numstr = this->fastNumberString()) == OREF_NULL)
895  {
896  /* this is a conversion error */
898  }
899  /* have numberstring do this */
900  return numstr->Max(arguments, argCount);
901 }
902 
903 RexxObject *RexxString::Min(RexxObject **arguments, size_t argCount)
904 /******************************************************************************/
905 /* Function: String min value...performed by RexxNumberString */
906 /******************************************************************************/
907 {
908  RexxNumberString *numstr; /* converted number string */
909 
910  /* non-numeric? */
911  if ((numstr = this->fastNumberString()) == OREF_NULL)
912  {
913  /* this is a conversion error */
915  }
916  /* have numberstring do this */
917  return numstr->Min(arguments, argCount);
918 }
919 
921 /******************************************************************************/
922 /* Function: String Trunc...performed by RexxNumberString */
923 /******************************************************************************/
924 {
925  RexxNumberString *numstr; /* converted number string */
926 
927  /* non-numeric? */
928  if ((numstr = this->fastNumberString()) == OREF_NULL)
929  {
930  /* this is a conversion error */
932  }
933  return numstr->trunc(decimals); /* have numberstring do this */
934 }
935 
942 {
943  RexxNumberString *numstr; /* converted number string */
944 
945  /* non-numeric? */
946  if ((numstr = this->fastNumberString()) == OREF_NULL)
947  {
948  /* this is a conversion error */
950  }
951  return numstr->floor(); /* have numberstring do this */
952 }
953 
960 {
961  RexxNumberString *numstr; /* converted number string */
962 
963  /* non-numeric? */
964  if ((numstr = this->fastNumberString()) == OREF_NULL)
965  {
966  /* this is a conversion error */
968  }
969  return numstr->ceiling(); /* have numberstring do this */
970 }
971 
978 {
979  RexxNumberString *numstr; /* converted number string */
980 
981  /* non-numeric? */
982  if ((numstr = this->fastNumberString()) == OREF_NULL)
983  {
984  /* this is a conversion error */
986  }
987  return numstr->round(); /* have numberstring do this */
988 }
989 
990 RexxObject *RexxString::format(RexxObject *Integers, RexxObject *Decimals, RexxObject *MathExp, RexxObject *ExpTrigger)
991 /******************************************************************************/
992 /* Function: String Format...performed by RexxNumberString */
993 /******************************************************************************/
994 {
995  RexxNumberString *numstr; /* converted number string */
996 
997  /* non-numeric? */
998  if ((numstr = this->fastNumberString()) == OREF_NULL)
999  {
1000  /* this is a conversion error */
1002  }
1003  /* have numberstring do this */
1004  return numstr->formatRexx(Integers, Decimals, MathExp, ExpTrigger);
1005 }
1006 
1007 
1017 {
1018  return this->primitiveIsEqual(other) ? TheTrueObject : TheFalseObject;
1019 }
1020 
1030 {
1031  return this->primitiveCaselessIsEqual(other) ? TheTrueObject : TheFalseObject;
1032 }
1033 
1034 
1036 /******************************************************************************/
1037 /* Function: Strict ("==") equality operator...also returns the hash value */
1038 /* if sent with no other object */
1039 /******************************************************************************/
1040 {
1041  return this->primitiveIsEqual(other) ? TheTrueObject : TheFalseObject;
1042 }
1043 
1045 /******************************************************************************/
1046 /* Function: Strict ("\==") inequality operator */
1047 /******************************************************************************/
1048 {
1049  return !this->primitiveIsEqual(other) ? TheTrueObject : TheFalseObject;
1050 }
1051 
1053 /******************************************************************************/
1054 /* Function: Non-strict ("=") string equality operator */
1055 /******************************************************************************/
1056 {
1057  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1058  {
1059  return TheFalseObject;
1060  }
1061  return ((this->comp(other) == 0) ? TheTrueObject : TheFalseObject);
1062 }
1063 
1065 /******************************************************************************/
1066 /* Function: Non-Strict ("\=") string inequality operator */
1067 /******************************************************************************/
1068 {
1069  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1070  {
1071  return TheTrueObject;
1072  }
1073  return ((this->comp(other) != 0) ? TheTrueObject : TheFalseObject);
1074 }
1075 
1077 /******************************************************************************/
1078 /* Function: Non-strict greater than operator (">") */
1079 /******************************************************************************/
1080 {
1081  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1082  {
1083  return TheFalseObject;
1084  }
1085  return ((this->comp(other) > 0) ? TheTrueObject : TheFalseObject);
1086 }
1087 
1089 /******************************************************************************/
1090 /* Function: Non-strict less than operatore ("<") */
1091 /******************************************************************************/
1092 {
1093  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1094  {
1095  return TheFalseObject;
1096  }
1097  return ((this->comp(other) < 0) ? TheTrueObject : TheFalseObject);
1098 }
1099 
1101 /******************************************************************************/
1102 /* Function: Non-strict greater than or equal operator (">=" or "<") */
1103 /******************************************************************************/
1104 {
1105  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1106  {
1107  return TheFalseObject;
1108  }
1109  return ((this->comp(other) >= 0) ? TheTrueObject : TheFalseObject);
1110 }
1111 
1113 /******************************************************************************/
1114 /* Function: Non-strict less than or equal operator ("<=" or ">") */
1115 /******************************************************************************/
1116 {
1117  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1118  {
1119  return TheFalseObject;
1120  }
1121  return ((this->comp(other) <= 0) ? TheTrueObject : TheFalseObject);
1122 }
1123 
1125 /******************************************************************************/
1126 /* Function: Strict greater than comparison (">>") */
1127 /******************************************************************************/
1128 {
1129  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1130  {
1131  return TheFalseObject;
1132  }
1133  return (this->strictComp(other) > 0) ? TheTrueObject : TheFalseObject;
1134 }
1135 
1137 /******************************************************************************/
1138 /* Function: Strict less than comparison ("<<") */
1139 /******************************************************************************/
1140 {
1141  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1142  {
1143  return TheFalseObject;
1144  }
1145  return (this->strictComp(other) < 0) ? TheTrueObject : TheFalseObject;
1146 }
1147 
1149 /******************************************************************************/
1150 /* Function: Strict greater than or equal to comparison (">>=" or "<<") */
1151 /******************************************************************************/
1152 {
1153  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1154  {
1155  return TheFalseObject;
1156  }
1157  return (this->strictComp(other) >= 0) ? TheTrueObject : TheFalseObject;
1158 }
1159 
1161 /******************************************************************************/
1162 /* Function: Strict less than or equal to operatore ("<<=" or ">>") */
1163 /******************************************************************************/
1164 {
1165  if (other == TheNilObject) // all conditionals return .false when compared to .nil
1166  {
1167  return TheFalseObject;
1168  }
1169  return (this->strictComp(other) <= 0) ? TheTrueObject : TheFalseObject;
1170 }
1171 
1173 /******************************************************************************/
1174 /* Function: Concatenate two strings together */
1175 /******************************************************************************/
1176 {
1177  size_t len1; /* length of first string */
1178  size_t len2; /* length of second string */
1179  RexxString *result; /* result string */
1180  char *data; /* character pointer */
1181 
1182  len1 = this->getLength(); /* get this length */
1183  len2 = other->getLength(); /* and the other length */
1184 
1185  if (len2 == 0) // some people have taken to using a''b
1186  {
1187  // to perform concatenation operations
1188  return this; // it makes sense to optimize concatenation
1189  } // with a null string by just returning
1190  if (len1 == 0) // the non-null object.
1191  {
1192  return other;
1193  }
1194  /* create a new string */
1195  result = (RexxString *)raw_string(len1+len2);
1196  data = result->getWritableData(); /* point to the string data */
1197 
1198  // both lengths are non-zero because of the test above, so we can
1199  // unconditionally copy
1200  /* copy the front part */
1201  memcpy(data, this->getStringData(), len1);
1202  memcpy(data + len1, other->getStringData(), len2);
1203  return result; /* return the result */
1204 
1205 }
1206 
1208 /******************************************************************************/
1209 /* Function: Rexx level concatenate...requires conversion and checking */
1210 /******************************************************************************/
1211 {
1212  size_t len1; /* length of first string */
1213  size_t len2; /* length of second string */
1214  RexxString *result; /* result string */
1215  RexxString *other;
1216  char *data; /* character pointer */
1217 
1218  requiredArgument(otherObj, ARG_ONE); /* this is required. */
1219  /* ensure a string value */
1220  other = (RexxString *)REQUEST_STRING(otherObj);
1221 
1222  /* added error checking for NULL pointer (from NilObject) */
1223  if (other == OREF_NULL)
1224  {
1226  }
1227 
1228  /* the following logic also appears */
1229  /* in string_concat, but is repeated */
1230  /* here because this is a VERY high */
1231  /* use function */
1232  len1 = this->getLength(); /* get this length */
1233  len2 = other->getLength(); /* and the other length */
1234  /* create a new string */
1235  result = (RexxString *)raw_string(len1+len2);
1236  data = result->getWritableData(); /* point to the string data */
1237  if (len1 != 0)
1238  { /* have real data? */
1239  /* copy the front part */
1240  memcpy(data, this->getStringData(), len1);
1241  data += len1; /* step past the length */
1242  }
1243  if (len2 != 0) /* have a second length */
1244  {
1245  /* and the second part */
1246  memcpy(data, other->getStringData(), len2);
1247  }
1248  return result; /* return the result */
1249 }
1250 
1252 /******************************************************************************/
1253 /* Function: Concatenate a string object onto an ASCII-Z string */
1254 /******************************************************************************/
1255 {
1256  size_t len1; /* length of first string */
1257  size_t len2; /* length of ASCII-Z string */
1258  RexxString *result; /* result string */
1259 
1260  len1 = this->getLength(); /* get this length */
1261  len2 = strlen(other); /* and the other length */
1262  /* create a new string */
1263  result = (RexxString *)raw_string(len1+len2);
1264  /* copy the front part */
1265  memcpy(result->getWritableData(), other, len2);
1266  /* and the second part */
1267  memcpy(result->getWritableData() + len2, this->getStringData(), len1);
1268  return result;
1269 }
1270 
1272 /******************************************************************************/
1273 /* Function: Concatenate an ASCII-Z string onto a string object */
1274 /******************************************************************************/
1275 {
1276  size_t len1; /* length of first string */
1277  size_t len2; /* length of ASCII-Z string */
1278  RexxString *result; /* result string */
1279 
1280  len1 = this->getLength(); /* get this length */
1281  len2 = strlen(other); /* and the other length */
1282  /* create a new string */
1283  result = (RexxString *)raw_string(len1+len2);
1284  /* copy the string object */
1285  memcpy(result->getWritableData(), this->getStringData(), len1);
1286  /* copy the ASCII-Z string */
1287  memcpy(result->getWritableData() + len1, other, len2);
1288  return result;
1289 }
1290 
1292 /******************************************************************************/
1293 /* Function: Concatenate two strings with a blank in between */
1294 /******************************************************************************/
1295 {
1296  size_t len1; /* length of first string */
1297  size_t len2; /* length of second string */
1298  RexxString *result; /* result string */
1299  RexxString *other; /* result string */
1300  char *data; /* character pointer */
1301 
1302  requiredArgument(otherObj, ARG_ONE); /* this is required. */
1303  /* ensure a string value */
1304  other = (RexxString *)REQUEST_STRING(otherObj);
1305 
1306  /* added error checking for NULL pointer (from NilObject) */
1307  if (other == OREF_NULL)
1308  {
1310  }
1311 
1312  /* ensure a string value */
1313  other = (RexxString *)REQUEST_STRING(otherObj);
1314 
1315  /* added error checking for NULL pointer (from NilObject) */
1316  if (other == OREF_NULL)
1317  {
1319  }
1320  /* the following logic also appears */
1321  /* in string_concat_with, but is */
1322  /* repeated here because this is a */
1323  /* VERY high use function */
1324  len1 = this->getLength(); /* get this length */
1325  len2 = other->getLength(); /* and the other length */
1326  /* create a new string */
1327  result = (RexxString *)raw_string(len1+len2+1);
1328  data = result->getWritableData(); /* point to the string data */
1329  if (len1 != 0)
1330  { /* have a first string? */
1331  /* copy the front part */
1332  memcpy(data, this->getStringData(), len1);
1333  data += len1; /* step past the length */
1334  }
1335  *data++ = ' '; /* stuff in the seperating blank */
1336  if (len2 != 0) /* have a second string? */
1337  {
1338  /* and the second part */
1339  memcpy(data, other->getStringData(), len2);
1340  }
1341  return result;
1342 }
1343 
1344 bool RexxString::truthValue(int errorCode)
1345 /******************************************************************************/
1346 /* Function: Determine the truth value of a string object, raising the */
1347 /* given error if bad. */
1348 /******************************************************************************/
1349 {
1350  RexxString *testString; /* string to test */
1351 
1352  if (!isOfClass(String, this)) /* a nonprimitive object? */
1353  {
1354  testString = this->requestString();/* get the real string value */
1355  }
1356  else
1357  {
1358  testString = this; /* just use the string directly */
1359  }
1360  if (testString->getLength() != 1) /* not exactly 1 character long? */
1361  {
1362  /* report the error */
1363  reportException(errorCode, testString);
1364  }
1365  if (*(testString->getStringData()) == '0')/* exactly '0'? */
1366  {
1367  return false; /* have a false */
1368  }
1369  /* not exactly '1'? */
1370  else if (!(*(testString->getStringData()) == '1'))
1371  {
1372  reportException(errorCode, this);/* report the error */
1373  }
1374  return true; /* this is true */
1375 }
1376 
1377 
1387 {
1388  RexxString *testString; /* string to test */
1389 
1390  if (!isOfClass(String, this)) /* a nonprimitive object? */
1391  {
1392  testString = this->requestString();/* get the real string value */
1393  }
1394  else
1395  {
1396  testString = this; /* just use the string directly */
1397  }
1398 
1399  if (testString->getLength() != 1) /* not exactly 1 character long? */
1400  {
1401  return false; // not a valid logical
1402  }
1403  if (testString->getChar(0) == '0')/* exactly '0'? */
1404  {
1405  result = false; // this is false and the conversion worked
1406  return true;
1407  }
1408  /* exactly '1'? */
1409  else if (testString->getChar(0) == '1')
1410  {
1411  result = true; // this is true and the conversion worked
1412  return true;
1413  }
1414  return false; // did not convert correctly
1415 }
1416 
1418 /******************************************************************************/
1419 /* Function: Tests for existence of lowercase characters */
1420 /******************************************************************************/
1421 {
1422  const char *data; /* current data pointer */
1423  const char *endData; /* end location */
1424 
1425  data = this->getStringData(); /* point to the string */
1426  endData = data + this->getLength(); /* set the end point */
1427 
1428  while (data < endData)
1429  { /* loop through entire string */
1430  if (*data != toupper(*data))
1431  { /* have something to uppercase? */
1432  this->setHasLower(); /* remember we have this */
1433  return true; /* just return now */
1434  }
1435  data++; /* step the position */
1436  }
1437  /* no lowercase? */
1438  this->setUpperOnly(); /* set the upper only attribute */
1439  return false; /* return then translation flag */
1440 }
1441 
1443 /******************************************************************************/
1444 /* Function: Translate a string to uppercase...will only create a new */
1445 /* string if characters actually have to be translated. */
1446 /******************************************************************************/
1447 {
1448  RexxString *newstring; /* newly created string */
1449  const char *data; /* current data pointer */
1450  char * outdata; /* output data */
1451  const char *endData; /* end of the data */
1452 
1453  /* something to uppercase? */
1454  if (!this->upperOnly() && (this->hasLower() || this->checkLower()))
1455  {
1456  /* create a new string */
1457  newstring = (RexxString *)raw_string(this->getLength());
1458  data = this->getStringData(); /* point to the data start */
1459  /* point to output data */
1460  outdata = newstring->getWritableData();
1461  endData = data + this->getLength(); /* set the loop terminator */
1462  while (data < endData)
1463  { /* loop through entire string */
1464  *outdata = toupper(*data); /* copy the uppercase character */
1465  data++; /* step the position */
1466  outdata++; /* and the output position */
1467  }
1468  newstring->setUpperOnly(); /* flag the string as uppercased */
1469  return newstring; /* return the new string */
1470  }
1471  return this; /* return this unchanged */
1472 }
1473 
1475 /******************************************************************************/
1476 /* Function: Translate a string to "traceable" form, removing non-displayable*/
1477 /* characters */
1478 /******************************************************************************/
1479 {
1480  RexxString *newCopy; /* new copy of string */
1481  // NOTE: since we're doing value comparisons on single character values here,
1482  // we need to process this as unsigned characters to handle values
1483  // greater than 0x7f.
1484  const unsigned char *Current; /* current string location */
1485  size_t i; /* string length */
1486  bool NonDisplay; /* have non-displayables */
1487 
1488  i = this->getLength(); /* get the length */
1489  /* point to the start */
1490  Current = (const unsigned char *)this->getStringData();
1491  NonDisplay = false; /* no non-displayable characters */
1492 
1493  for (; i > 0; i--)
1494  { /* loop for the entire string */
1495  /* control character? */
1496  if (*Current < ch_SPACE)
1497  {
1498  NonDisplay = true; /* got a non-displayable */
1499  break; /* get out of here */
1500  }
1501  Current++; /* step the pointer */
1502  }
1503  if (!NonDisplay) /* all displayable? */
1504  {
1505  return this; /* leave unchanged */
1506  }
1507  /* copy the string */
1508  newCopy = (RexxString *) this->copy();
1509  i = newCopy->getLength(); /* get the length */
1510  /* point to the start */
1511  char *outptr = newCopy->getWritableData();
1512 
1513  for (; i > 0; i--)
1514  { /* loop for the entire string */
1515  /* control character? */
1516  if (*outptr < ch_SPACE && *outptr != ch_TAB)
1517  {
1518  *outptr = '?'; /* yes, change to question */
1519  }
1520  outptr++; /* step the pointer */
1521  }
1522  return newCopy; /* return the converted string */
1523 }
1524 
1525 
1527 /******************************************************************************/
1528 /* Function: Translate a string to lower case */
1529 /******************************************************************************/
1530 {
1531  RexxString *newstring; /* newly created string */
1532  const char * data; /* current data pointer */
1533  char * outdata; /* output data */
1534  size_t i; /* loop counter */
1535  bool needTranslation; /* translation required */
1536 
1537  data = this->getStringData(); /* point to the string */
1538  needTranslation = false; /* no translation required */
1539 
1540  for (i = 0; i < this->getLength(); i++)
1541  { /* loop through entire string */
1542  if (*data != tolower(*data))
1543  { /* have something to lowercase? */
1544  needTranslation = true; /* flag it */
1545  break; /* stop at the first one */
1546  }
1547  data++; /* step the position */
1548  }
1549  if (needTranslation)
1550  { /* something to uppercase? */
1551  /* create a new string */
1552  newstring = (RexxString *)raw_string(this->getLength());
1553  data = this->getStringData(); /* point to the data start */
1554  /* point to output data */
1555  outdata = newstring->getWritableData();
1556  /* loop through entire string */
1557  for (i = 0; i < this->getLength(); i++)
1558  {
1559  *outdata = tolower(*data); /* copy the lowercase character */
1560  data++; /* step the position */
1561  outdata++; /* and the output position */
1562  }
1563  }
1564  else
1565  {
1566  newstring = this; /* return untranslated string */
1567  }
1568  return newstring; /* return the new copy */
1569 }
1570 
1571 
1583 {
1584  size_t startPos = optionalPositionArgument(_start, 1, ARG_ONE) - 1;
1585  size_t rangeLength = optionalLengthArgument(_length, getLength(), ARG_TWO);
1586 
1587  // if we're starting beyond the end bounds, return unchanged
1588  if (startPos >= getLength())
1589  {
1590  return this;
1591  }
1592 
1593  rangeLength = Numerics::minVal(rangeLength, getLength() - startPos);
1594 
1595  // a zero length value is also a non-change.
1596  if (rangeLength == 0)
1597  {
1598  return this;
1599  }
1600 
1601  return lower(startPos, rangeLength);
1602 }
1603 
1604 
1616 {
1617  size_t startPos = optionalPositionArgument(_start, 1, ARG_ONE) - 1;
1618  size_t rangeLength = optionalLengthArgument(_length, getLength(), ARG_TWO);
1619 
1620  // if we're starting beyond the end bounds, return unchanged
1621  if (startPos >= getLength())
1622  {
1623  return this;
1624  }
1625 
1626  rangeLength = Numerics::minVal(rangeLength, getLength() - startPos);
1627 
1628  // a zero length value is also a non-change.
1629  if (rangeLength == 0)
1630  {
1631  return this;
1632  }
1633 
1634  return upper(startPos, rangeLength);
1635 }
1636 
1637 
1638 
1650 RexxString *RexxString::lower(size_t offset, size_t _length)
1651 {
1652  // get a copy of the string
1653  RexxString *newstring = extract(0, getLength());
1654 
1655  char *data = newstring->getWritableData() + offset;
1656  // now uppercase in place
1657  for (size_t i = 0; i < _length; i++)
1658  {
1659  *data = tolower(*data);
1660  data++;
1661  }
1662  return newstring;
1663 }
1664 
1665 
1666 
1679 RexxString *RexxString::upper(size_t offset, size_t _length)
1680 {
1681  // get a copy of the string
1682  RexxString *newstring = extract(0, getLength());
1683 
1684  char *data = newstring->getWritableData() + offset;
1685  // now uppercase in place
1686  for (size_t i = 0; i < _length; i++)
1687  {
1688  *data = toupper(*data);
1689  data++;
1690  }
1691  return newstring;
1692 }
1693 
1695  size_t digits) /* precision to use */
1696 /******************************************************************************/
1697 /* Function: Convert a string object to an integer. Returns .nil for */
1698 /* failures. */
1699 /******************************************************************************/
1700 {
1701  RexxNumberString *numberStr; /* string's numberstring version */
1702  RexxInteger *newInteger; /* returned integer string */
1703 
1704  /* Force String conversion through */
1705  /* NumberString */
1706  /* get the number string version */
1707  if ((numberStr = this->fastNumberString()) != OREF_NULL )
1708  {
1709  /* try for an integer */
1710  newInteger = numberStr->integerValue(digits);
1711  /* did it convert? */
1712  if (newInteger != TheNilObject && newInteger->getStringrep() == OREF_NULL)
1713  {
1714  newInteger->setString(this); /* connect the string value */
1715  }
1716  return newInteger; /* return the new integer */
1717  }
1718  else
1719  {
1720  return(RexxInteger *)TheNilObject;/* return .nil for failures */
1721  }
1722 }
1723 
1725 /******************************************************************************/
1726 /* Function: Set a number string value on to the string */
1727 /******************************************************************************/
1728 {
1729 
1730  OrefSet(this, this->NumberString, (RexxNumberString *)NumberRep);
1731 
1732  if (NumberRep != OREF_NULL) /* actually get one? */
1733  {
1734  this->setHasReferences(); /* Make sure we are sent Live... */
1735  }
1736  else
1737  {
1738  this->setHasNoReferences(); /* no more references */
1739  }
1740  return;
1741 }
1742 
1744  char between)
1745 /******************************************************************************/
1746 /* Function: Concatenate two strings with a single character between */
1747 /******************************************************************************/
1748 {
1749  size_t len1; /* length of first string */
1750  size_t len2; /* length of second string */
1751  RexxString *result; /* result string */
1752  char *data; /* character pointer */
1753 
1754  len1 = this->getLength(); /* get this length */
1755  len2 = other->getLength(); /* and the other length */
1756  /* create a new string */
1757  result = (RexxString *)raw_string(len1+len2+1);
1758  data = result->getWritableData(); /* point to the string data */
1759  if (len1 != 0)
1760  { /* have a first string? */
1761  /* copy the front part */
1762  memcpy(data, this->getStringData(), len1);
1763  data += len1; /* step past the length */
1764  }
1765  *data++ = between; /* stuff in the seperating char */
1766  if (len2 != 0) /* have a second string? */
1767  {
1768  /* and the second part */
1769  memcpy(data, other->getStringData(), len2);
1770  }
1771  return result;
1772 }
1773 
1775 /******************************************************************************/
1776 /* Function: Logical AND of a string with another logical value */
1777 /******************************************************************************/
1778 {
1779  RexxObject *otherTruth; /* truth value of the other object */
1780 
1781  requiredArgument(other, ARG_ONE); /* make sure the argument is there */
1782  /* validate the boolean */
1784  /* perform the operation */
1785  return(!this->truthValue(Error_Logical_value_method)) ? TheFalseObject : otherTruth;
1786 }
1787 
1789 /******************************************************************************/
1790 /* Function: Logical OR of a string with another logical value */
1791 /******************************************************************************/
1792 {
1793  RexxObject *otherTruth; /* truth value of the other object */
1794 
1795  requiredArgument(other, ARG_ONE); /* make sure the argument is there */
1796  /* validate the boolean */
1798  /* perform the operation */
1799  return(this->truthValue(Error_Logical_value_method)) ? TheTrueObject : otherTruth;
1800 }
1801 
1803 /******************************************************************************/
1804 /* Function: Logical XOR of a string with another logical value */
1805 /******************************************************************************/
1806 {
1807  requiredArgument(other, ARG_ONE); /* make sure the argument is there */
1808  /* get as a boolean */
1809  bool truth = other->truthValue(Error_Logical_value_method);
1810  /* first one false? */
1812  {
1813  /* value is always the second */
1814  return truth ? TheTrueObject : TheFalseObject;
1815  }
1816  else /* value is inverse of second */
1817  {
1818  return(truth) ? TheFalseObject : TheTrueObject;
1819  }
1820 }
1821 
1823 /******************************************************************************/
1824 /* Function: Split string into an array */
1825 /******************************************************************************/
1826 {
1827  return StringUtil::makearray(getStringData(), getLength(), div);
1828 }
1829 
1830 
1832 /******************************************************************************/
1833 /* Function: Logical NOT of a string */
1834 /******************************************************************************/
1835 {
1837 }
1838 
1840 /******************************************************************************/
1841 /* Function: Logical NOT of a string */
1842 /******************************************************************************/
1843 {
1845 }
1846 
1848 /******************************************************************************/
1849 /* Function: Test if this string is an integer value */
1850 /******************************************************************************/
1851 {
1852  const char *digitPtr;
1853  size_t digitsLeft;
1854 
1855  digitPtr = this->getStringData();
1856  digitsLeft = this->getLength();
1857 
1858  /* Skip all leading blanks */
1859  for (; digitsLeft && (*digitPtr == ch_BLANK || *digitPtr == ch_TAB); ++digitPtr, --digitsLeft) ;
1860 
1861  if (digitsLeft)
1862  { /* Still Digits left ? */
1863  if (*digitPtr == ch_PLUS || *digitPtr == ch_MINUS)
1864  {
1865  /* need to move past the sign and */
1866  /* remove any remaining blanks. */
1867  for (++digitPtr, --digitsLeft;
1868  digitsLeft && (*digitPtr == ch_BLANK || *digitPtr == ch_TAB);
1869  ++digitPtr, --digitsLeft) ;
1870  /* Yes, skip any blanks */
1871  if (!digitsLeft) /* Did we reach end of data ? */
1872  {
1873  /* Yes, not valid */
1874  return TheFalseObject;
1875  }
1876  }
1877  /* we are now ready to check for */
1878  /*digits */
1879  for (; digitsLeft && *digitPtr >= ch_ZERO && *digitPtr <= ch_NINE;
1880  ++digitPtr, --digitsLeft) ;
1881  /* found our first non-digit, or end */
1882  /* is it a decimal point? */
1883  if ( digitsLeft && *digitPtr == ch_PERIOD)
1884  {
1885  digitPtr++; /* Yes, see if remaining digits are 0*/
1886  digitsLeft--;
1887  for (; digitsLeft && *digitPtr == ch_ZERO; ++digitPtr, --digitsLeft) ;
1888  }
1889  /* if chars left make sure all are */
1890  /* blanks. */
1891  for (; digitsLeft && (*digitPtr == ch_BLANK || *digitPtr == ch_TAB); ++digitPtr, --digitsLeft) ;
1892  /* skipped all trailing blanks. */
1893  /* we better be at the end of the */
1894  /* string, otherwise its invalid. */
1895  if (!digitsLeft)
1896  {
1897  /* yes its the end, return true */
1898  return TheTrueObject;
1899  }
1900  }
1901 
1902  /* all other cases are invalid.... */
1903  return(RexxObject *) TheFalseObject;
1904 }
1905 
1907  RexxActivation *context, /* current activation context */
1908  RexxExpressionStack *stack ) /* evaluation stack */
1909 /******************************************************************************/
1910 /* Function: Polymorphic method that makes string a polymorphic expression */
1911 /* term for string literals. */
1912 /******************************************************************************/
1913 {
1914 
1915  stack->push((RexxObject *)this); /* place on the evaluation stack */
1916  /* trace if necessary */
1918  return this; /* also return the result */
1919 }
1920 
1921 
1929 {
1930  size_t result_length = getLength() + 1;
1931  if (r.strptr == NULL || r.strlength < result_length)
1932  {
1933  r.strptr = (char *)SystemInterpreter::allocateResultMemory(result_length);
1934  }
1935  // copy all of the data + the terminating null
1936  memcpy(r.strptr, getStringData(), result_length);
1937  // fill in the length too
1938  r.strlength = getLength();
1939 }
1940 
1941 
1943  RexxActivation *context) /* current activation context */
1944 /******************************************************************************/
1945 /* Function: Polymorphic get_value function used with expression terms */
1946 /******************************************************************************/
1947 {
1948  return (RexxObject *)this; /* just return this value */
1949 }
1950 
1951 
1953  RexxVariableDictionary *context) /* current activation context */
1954 /******************************************************************************/
1955 /* Function: Polymorphic get_value function used with expression terms */
1956 /******************************************************************************/
1957 {
1958  return (RexxObject *)this; /* just return this value */
1959 }
1960 
1961 
1963  RexxActivation *context) /* current activation context */
1964 /******************************************************************************/
1965 /* Function: Polymorphic get_value function used with expression terms */
1966 /******************************************************************************/
1967 {
1968  return (RexxObject *)this; /* just return this value */
1969 }
1970 
1971 
1973  RexxVariableDictionary *context) /* current activation context */
1974 /******************************************************************************/
1975 /* Function: Polymorphic get_value function used with expression terms */
1976 /******************************************************************************/
1977 {
1978  return (RexxObject *)this; /* just return this value */
1979 }
1980 
1981 
1982 RexxString *RexxString::newString(const char *string, size_t length)
1983 /******************************************************************************/
1984 /* Function: Allocate (and initialize) a string object */
1985 /******************************************************************************/
1986 {
1987  /* calculate the size */
1988  /* STRINGOBJ - excess chars (3) */
1989  /* + length. only sub 3 to allow */
1990  /* for terminating NULL */
1991  size_t size2 = sizeof(RexxString) - (sizeof(char) * 3) + length;
1992  /* allocate the new object */
1993  RexxString *newObj = (RexxString *)new_object(size2, T_String);
1994  /* clear the front part */
1995  newObj->setLength(length); /* save the length */
1996  newObj->hashValue = 0; // make sure the hash value is zeroed
1997  /* Null terminate, allows faster */
1998  /* conversion to ASCII-Z string */
1999  newObj->putChar(length, '\0');
2000  /* copy it over */
2001  newObj->put(0, string, length);
2002  /* by default, we don't need Live */
2003  newObj->setHasNoReferences(); /*sent */
2004  /* NOTE: That if we can set */
2005  /* this->NumebrString elsewhere */
2006  /*we need to mark ourselves as */
2007  return newObj; /*having OREFs */
2008 }
2009 
2011 /******************************************************************************/
2012 /* Function: Allocate (and initialize) an empty string object */
2013 /******************************************************************************/
2014 {
2015  /* calculate the size */
2016  /* STRINGOBJ - excess chars (3) */
2017  /* + length. only sub 3 to allow */
2018  /* for terminating NULL */
2019  size_t size2 = sizeof(RexxString) - (sizeof(char) * 3) + length;
2020  /* allocate the new object */
2021  RexxString *newObj = (RexxString *)new_object(size2, T_String);
2022  newObj->setLength(length); /* save the length */
2023  newObj->hashValue = 0; // make sure the hash value is zeroed
2024  /* Null terminate, allows faster */
2025  /* conversion to ASCII-Z string */
2026  newObj->putChar(length, '\0');
2027  /* by default, we don't need Live */
2028  newObj->setHasNoReferences(); /*sent */
2029  /* NOTE: That if we can set */
2030  /* this->NumebrString elsewhere */
2031  /*we need to mark ourselves as */
2032  return newObj; /*having OREFs */
2033 }
2034 
2035 
2048 {
2049  /* calculate the size */
2050  /* STRINGOBJ - excess chars (3) */
2051  /* + length. only sub 3 to allow */
2052  /* for terminating NULL */
2053  size_t size2 = sizeof(RexxString) - (sizeof(char) * 3) + length;
2054  /* allocate the new object */
2055  RexxString *newObj = (RexxString *)new_object(size2, T_String);
2056  newObj->length = length; /* save the length */
2057  newObj->hashValue = 0; // make sure the hash value is zeroed
2058  /* create a new string */
2059  /* point to output data */
2060  char *outdata = newObj->getWritableData();
2061  // set the input markers
2062  const char *indata = string;
2063  const char *endData = indata + length;
2064  while (indata < endData) /* loop through entire string */
2065  {
2066  *outdata = toupper(*indata); /* copy the uppercase character */
2067  indata++; /* step the position */
2068  outdata++; /* and the output position */
2069  }
2070  newObj->setUpperOnly(); /* flag the string as uppercased */
2071  /* Null terminate, allows faster */
2072  /* conversion to ASCII-Z string */
2073  newObj->putChar(length, '\0');
2074  /* by default, we don't need Live */
2075  newObj->setHasNoReferences(); /*sent */
2076  /* NOTE: That if we can set */
2077  /* this->NumebrString elsewhere */
2078  /*we need to mark ourselves as */
2079  return newObj; /*having OREFs */
2080 }
2081 
2083 /******************************************************************************/
2084 /* Function: Create a string from a double value */
2085 /******************************************************************************/
2086 {
2087  /* get double as a number string. */
2088  return new_numberstringFromDouble(number)->stringValue();
2089 }
2090 
2091 
2102 {
2103  if (number == 0) /* zero result? */
2104  {
2105  return new_string("0");
2106  }
2107  else
2108  {
2109  char buffer[64];
2110  // format as a string
2111  sprintf(buffer, "%.*g", (int)precision, number);
2112  size_t len = strlen(buffer);
2113  // if the last character is a decimal, we remove that
2114  if (buffer[len - 1] == '.')
2115  {
2116  len--;
2117  }
2118  return new_string(buffer, len);
2119  }
2120 }
2121 
2122 
2123 RexxString *RexxString::newProxy(const char *string)
2124 /******************************************************************************/
2125 /* Function: Create a proxy object from this string */
2126 /******************************************************************************/
2127 {
2128  RexxString *sref;
2129  /* The provided source string is null*/
2130  /* terminated so let class_new */
2131  /* compute the length. */
2132  /* get a new string object */
2133  sref = (RexxString *)new_string(string);
2134  /* here we need to identify this */
2135  /*string */
2136  sref->makeProxiedObject(); /* as being a proxy object */
2137 
2138  return sref;
2139 }
2140 
2141 RexxString *RexxString::newRexx(RexxObject **init_args, size_t argCount)
2142 /******************************************************************************/
2143 /* Arguments: Subclass init arguments */
2144 /* Function: Create a new string value (used primarily for subclasses) */
2145 /******************************************************************************/
2146 {
2147  RexxObject *stringObj; /* string value */
2148 
2149  /* break up the arguments */
2150  RexxClass::processNewArgs(init_args, argCount, &init_args, &argCount, 1, (RexxObject **)&stringObj, NULL);
2151  /* force argument to string value */
2152  RexxString *string = (RexxString *)stringArgument(stringObj, ARG_ONE);
2153  /* create a new string object */
2154  string = new_string(string->getStringData(), string->getLength());
2155  ProtectedObject p(string);
2156  string->setBehaviour(((RexxClass *)this)->getInstanceBehaviour());
2157  if (((RexxClass *)this)->hasUninitDefined())
2158  {
2159  string->hasUninit();
2160  }
2161  /* Initialize the new instance */
2162  string->sendMessage(OREF_INIT, init_args, argCount);
2163  return string; /* return the new string */
2164 }
2165 
2166 
2168 {
2169  NULL, /* first entry not used */
2186  /* Duplicate entry neccessary */
2195  /* Duplicate entry neccessary */
2199  (PCPPM)&RexxString::notEqual, /* Duplicate entry neccessary */
2204 };
2205 
2206 
ch_TAB
#define ch_TAB
Definition: NumberStringClass.hpp:59
RexxString::power
RexxObject * power(RexxObject *right)
Definition: StringClass.cpp:838
RexxString::abs
RexxObject * abs()
Definition: StringClass.cpp:854
RexxNumberString::ceiling
RexxObject * ceiling()
Definition: NumberStringClass.cpp:1616
RexxObject::copy
RexxObject * copy()
Definition: ObjectClass.cpp:518
StringUtil.hpp
RexxObject::sendMessage
void sendMessage(RexxString *, RexxArray *, ProtectedObject &)
Definition: ObjectClass.cpp:668
RexxString::caselessEquals
RexxInteger * caselessEquals(RexxString *other)
Definition: StringClass.cpp:1029
RexxString::floor
RexxObject * floor()
Definition: StringClass.cpp:941
RexxExpressionStack
Definition: ExpressionStack.hpp:53
logical_t
size_t logical_t
Definition: rexx.h:230
RexxString::ceiling
RexxObject * ceiling()
Definition: StringClass.cpp:959
RexxString::lowerRexx
RexxString * lowerRexx(RexxInteger *, RexxInteger *)
Definition: StringClass.cpp:1582
RexxNumberString::divide
RexxNumberString * divide(RexxObject *)
Definition: NumberStringClass.cpp:3150
TRACE_PREFIX_LITERAL
Definition: RexxActivity.hpp:86
RexxArray
Definition: ArrayClass.hpp:100
RexxString::trunc
RexxObject * trunc(RexxInteger *decimals)
Definition: StringClass.cpp:920
RexxString::upperRexx
RexxString * upperRexx(RexxInteger *, RexxInteger *)
Definition: StringClass.cpp:1615
RexxString::isLessThan
RexxInteger * isLessThan(RexxObject *)
Definition: StringClass.cpp:1088
RexxObject::truthValue
bool truthValue(int)
Definition: ObjectClass.cpp:468
TheFalseObject
#define TheFalseObject
Definition: RexxCore.h:184
RexxNumberString::power
RexxNumberString * power(RexxObject *)
Definition: NumberStringMath2.cpp:681
RexxString::isLessOrEqual
RexxInteger * isLessOrEqual(RexxObject *)
Definition: StringClass.cpp:1112
RexxString::createInstance
static void createInstance()
Definition: StringClass.cpp:67
RexxString::getObjectHashCode
HashCode getObjectHashCode()
Definition: StringClass.cpp:108
StringUtil::caselessCompare
static int caselessCompare(const char *, const char *, size_t)
Definition: StringUtil.cpp:571
new_integer
RexxInteger * new_integer(wholenumber_t v)
Definition: IntegerClass.hpp:198
RexxString::andOp
RexxObject * andOp(RexxObject *)
Definition: StringClass.cpp:1774
memory_mark_general
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:437
RexxString::format
RexxObject * format(RexxObject *Integers, RexxObject *Decimals, RexxObject *MathExp, RexxObject *ExpTrigger)
Definition: StringClass.cpp:990
RexxString::multiply
RexxObject * multiply(RexxObject *right)
Definition: StringClass.cpp:774
ch_MINUS
#define ch_MINUS
Definition: NumberStringClass.hpp:52
RexxActivation.hpp
OrefSet
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
RexxNumberString::Sign
RexxInteger * Sign()
Definition: NumberStringClass.cpp:3220
_RXSTRING::strlength
size_t strlength
Definition: rexx.h:157
RexxString::primitiveMakeString
RexxString * primitiveMakeString()
Definition: StringClass.cpp:236
optionalLengthArgument
size_t optionalLengthArgument(RexxObject *o, size_t d, size_t p)
Definition: RexxCore.h:336
RexxString::primitiveIsEqual
bool primitiveIsEqual(RexxObject *)
Definition: StringClass.cpp:511
RexxString::sign
RexxObject * sign()
Definition: StringClass.cpp:870
RexxString::compareToRexx
RexxInteger * compareToRexx(RexxString *other, RexxInteger *start_, RexxInteger *len_)
Definition: StringClassMisc.cpp:1061
RexxString::RexxString
RexxString()
Definition: StringClass.hpp:122
RexxString::notEqual
RexxInteger * notEqual(RexxObject *)
Definition: StringClass.cpp:1064
RexxInteger::setString
void setString(RexxString *string)
Definition: IntegerClass.cpp:348
SystemInterpreter::allocateResultMemory
static void * allocateResultMemory(size_t)
Definition: MemorySupport.cpp:63
RexxString::newString
static RexxString * newString(const char *, size_t)
Definition: StringClass.cpp:1982
RexxString::unflatten
RexxObject * unflatten(RexxEnvelope *)
Definition: StringClass.cpp:167
RexxString::newProxy
static RexxString * newProxy(const char *)
Definition: StringClass.cpp:2123
RexxString::isGreaterOrEqual
RexxInteger * isGreaterOrEqual(RexxObject *)
Definition: StringClass.cpp:1100
RexxString::hasLower
bool hasLower()
Definition: StringClass.hpp:341
RexxNumberString::formatRexx
RexxString * formatRexx(RexxObject *, RexxObject *, RexxObject *, RexxObject *)
Definition: NumberStringClass.cpp:1842
RexxObject::compareTo
virtual wholenumber_t compareTo(RexxObject *)
Definition: ObjectClass.cpp:186
RexxString::truthValue
bool truthValue(int)
Definition: StringClass.cpp:1344
RexxString::getLength
size_t getLength()
Definition: StringClass.hpp:330
requiredArgument
void requiredArgument(RexxObject *object, size_t position)
Definition: RexxCore.h:284
CHAR_SIGN
char CHAR_SIGN[]
_RXSTRING::strptr
char * strptr
Definition: rexx.h:158
RexxString::plus
RexxObject * plus(RexxObject *right)
Definition: StringClass.cpp:742
RexxString::copyIntoTail
void copyIntoTail(RexxCompoundTail *buffer)
Definition: StringClass.cpp:226
RexxInternalObject::isProxyObject
bool isProxyObject()
Definition: ObjectClass.hpp:257
ch_BLANK
#define ch_BLANK
Definition: NumberStringClass.hpp:51
RexxString::notOp
RexxObject * notOp()
Definition: StringClass.cpp:1831
RexxString::newUpperString
static RexxString * newUpperString(const char *, stringsize_t)
Definition: StringClass.cpp:2047
new_numberstring
RexxNumberString * new_numberstring(const char *s, stringsize_t l)
Definition: NumberStringClass.hpp:274
RexxNumberString::integerValue
RexxInteger * integerValue(size_t)
Definition: NumberStringClass.cpp:686
RexxString::setHasLower
void setHasLower()
Definition: StringClass.hpp:343
RexxNumberString::plus
RexxNumberString * plus(RexxObject *)
Definition: NumberStringClass.cpp:3069
StringUtil::makearray
static RexxArray * makearray(const char *start, size_t length, RexxString *separator)
Definition: StringUtil.cpp:491
RexxNumberString::comp
wholenumber_t comp(RexxObject *)
Definition: NumberStringClass.cpp:2766
ARG_TWO
const int ARG_TWO
Definition: RexxCore.h:81
RexxVariableDictionary
Definition: RexxVariableDictionary.hpp:55
RexxString::getValue
RexxObject * getValue(RexxActivation *)
Definition: StringClass.cpp:1942
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
RexxString::getWritableData
char * getWritableData()
Definition: StringClass.hpp:334
RexxActivation::traceIntermediate
void traceIntermediate(RexxObject *v, int p)
Definition: RexxActivation.hpp:373
RexxString::strictLessOrEqual
RexxInteger * strictLessOrEqual(RexxObject *)
Definition: StringClass.cpp:1160
RexxString::unsignedNumberValue
bool unsignedNumberValue(stringsize_t &result, size_t precision)
Definition: StringClass.cpp:287
RexxString::strictGreaterThan
RexxInteger * strictGreaterThan(RexxObject *)
Definition: StringClass.cpp:1124
RexxString::isEqual
bool isEqual(RexxObject *)
Definition: StringClass.cpp:482
TheTrueObject
#define TheTrueObject
Definition: RexxCore.h:185
RexxString::isInteger
RexxObject * isInteger()
Definition: StringClass.cpp:1847
RexxString::getStringData
const char * getStringData()
Definition: StringClass.hpp:333
RexxInternalObject::makeProxiedObject
void makeProxiedObject()
Definition: ObjectClass.hpp:256
RexxString::getChar
char getChar(size_t p)
Definition: StringClass.hpp:338
RexxString::newRexx
RexxString * newRexx(RexxObject **, size_t)
Definition: StringClass.cpp:2141
RexxString::makeArray
RexxArray * makeArray()
Definition: StringClass.cpp:219
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxNumberString::remainder
RexxNumberString * remainder(RexxObject *)
Definition: NumberStringClass.cpp:3187
RexxString::equal
RexxInteger * equal(RexxObject *)
Definition: StringClass.cpp:1052
RexxString::stringValue
RexxString * stringValue()
Definition: StringClass.cpp:184
isOfClass
#define isOfClass(t, r)
Definition: RexxCore.h:211
RexxNumberString::stringValue
RexxString * stringValue()
Definition: NumberStringClass.cpp:221
RexxObject::makeArrayRexx
RexxObject * makeArrayRexx()
Definition: ObjectClass.cpp:2477
ch_NINE
#define ch_NINE
Definition: NumberStringClass.hpp:58
RexxNumberString::unsignedNumberValue
bool unsignedNumberValue(stringsize_t &result, size_t precision)
Definition: NumberStringClass.cpp:594
RexxString::checkLower
bool checkLower()
Definition: StringClass.cpp:1417
RexxString::remainder
RexxObject * remainder(RexxObject *right)
Definition: StringClass.cpp:822
RexxString::strictEqual
RexxInteger * strictEqual(RexxObject *)
Definition: StringClass.cpp:1035
raw_string
RexxString * raw_string(stringsize_t l)
Definition: StringClass.hpp:529
CHAR_FORMAT
char CHAR_FORMAT[]
T_String
Definition: ClassTypeCodes.h:79
RexxString::nonNumeric
bool nonNumeric()
Definition: StringClass.hpp:344
RexxCompoundTail.hpp
optionalPositionArgument
size_t optionalPositionArgument(RexxObject *o, size_t d, size_t p)
Definition: RexxCore.h:344
RexxString::numberString
RexxNumberString * numberString()
Definition: StringClass.cpp:366
ch_PERIOD
Definition: Encodings.hpp:44
Error_Incorrect_method_nostring
#define Error_Incorrect_method_nostring
Definition: RexxErrorCodes.h:489
new_string
RexxString * new_string(const char *s, stringsize_t l)
Definition: StringClass.hpp:524
RexxString::setUpperOnly
void setUpperOnly()
Definition: StringClass.hpp:342
SystemInterpreter.hpp
RexxString::live
void live(size_t)
Definition: StringClass.cpp:136
RexxInternalObject::setHasReferences
void setHasReferences()
Definition: ObjectClass.hpp:239
RexxString::liveGeneral
void liveGeneral(int reason)
Definition: StringClass.cpp:145
RexxInteger::getValue
RexxObject * getValue(RexxActivation *)
Definition: IntegerClass.cpp:1162
HashCode
size_t HashCode
Definition: ObjectClass.hpp:77
ARG_ONE
const int ARG_ONE
Definition: RexxCore.h:80
RexxString::getStringHash
HashCode getStringHash()
Definition: StringClass.hpp:133
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
RexxString::xorOp
RexxObject * xorOp(RexxObject *)
Definition: StringClass.cpp:1802
_RXSTRING
Definition: rexx.h:156
RexxString::copyToRxstring
void copyToRxstring(RXSTRING &r)
Definition: StringClass.cpp:1928
RexxString::operatorNot
RexxObject * operatorNot(RexxObject *)
Definition: StringClass.cpp:1839
RexxString::equals
RexxInteger * equals(RexxString *other)
Definition: StringClass.cpp:1016
RexxClass
Definition: ClassClass.hpp:49
ProtectedObject.hpp
RexxNumberString::floor
RexxObject * floor()
Definition: NumberStringClass.cpp:1487
RexxNumberString::numberValue
bool numberValue(wholenumber_t &result, size_t precision)
Definition: NumberStringClass.cpp:521
RexxNumberString::abs
RexxNumberString * abs()
Definition: NumberStringClass.cpp:3206
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
RexxString::concatToCstring
RexxString * concatToCstring(const char *)
Definition: StringClass.cpp:1251
ProtectedObject
Definition: ProtectedObject.hpp:46
RexxString::getRealValue
RexxObject * getRealValue(RexxActivation *)
Definition: StringClass.cpp:1962
StringClass.hpp
RexxString::classInstance
static RexxClass * classInstance
Definition: StringClass.hpp:482
RexxVirtualBase::unflatten
virtual RexxObject * unflatten(RexxEnvelope *)
Definition: ObjectClass.hpp:177
CHAR_ABS
char CHAR_ABS[]
RexxNumberString::setString
void setString(RexxString *)
Definition: NumberStringClass.cpp:170
RexxString::compareTo
wholenumber_t compareTo(RexxObject *)
Definition: StringClass.cpp:570
RexxString::strictLessThan
RexxInteger * strictLessThan(RexxObject *)
Definition: StringClass.cpp:1136
RexxString::evaluate
RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: StringClass.cpp:1906
ch_PLUS
#define ch_PLUS
Definition: NumberStringClass.hpp:53
RexxString::minus
RexxObject * minus(RexxObject *right)
Definition: StringClass.cpp:758
PCPPM
RexxObject *(RexxObject::* PCPPM)()
Definition: ObjectClass.hpp:198
RexxString::concatWith
RexxString * concatWith(RexxString *, char)
Definition: StringClass.cpp:1743
Error_Incorrect_method_string_nonumber
#define Error_Incorrect_method_string_nonumber
Definition: RexxErrorCodes.h:493
RexxNumberString::Max
RexxNumberString * Max(RexxObject **, size_t)
Definition: NumberStringClass.cpp:3248
Error_Conversion_operator
#define Error_Conversion_operator
Definition: RexxErrorCodes.h:365
TheEnvironment
#define TheEnvironment
Definition: RexxCore.h:173
RexxString::lengthRexx
RexxObject * lengthRexx()
Definition: StringClass.cpp:473
IntegerOne
#define IntegerOne
Definition: RexxCore.h:189
RexxString::Min
RexxObject * Min(RexxObject **args, size_t argCount)
Definition: StringClass.cpp:903
CLASS_CREATE
#define CLASS_CREATE(name, id, className)
Definition: RexxMemory.hpp:445
RexxExpressionStack::push
void push(RexxObject *value)
Definition: ExpressionStack.hpp:77
RexxString::upperOnly
bool upperOnly()
Definition: StringClass.hpp:340
RexxString::extract
RexxString * extract(size_t offset, size_t sublength)
Definition: StringClass.hpp:229
RexxCompoundTail::append
void append(const char *newData, size_t stringLen)
Definition: RexxCompoundTail.hpp:117
CHAR_TRUNC
char CHAR_TRUNC[]
RexxString::hash
virtual HashCode hash()
Definition: StringClass.cpp:73
RexxString::setLength
void setLength(size_t l)
Definition: StringClass.hpp:331
Numerics::minVal
static wholenumber_t minVal(wholenumber_t n1, wholenumber_t n2)
Definition: Numerics.hpp:116
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
ch_SPACE
#define ch_SPACE
Definition: StringClass.hpp:88
RexxNumberString::multiply
RexxNumberString * multiply(RexxObject *)
Definition: NumberStringClass.cpp:3133
RexxString::hashValue
HashCode hashValue
Definition: StringClass.hpp:486
RexxString::createNumberString
RexxNumberString * createNumberString()
Definition: StringClass.cpp:412
new_numberstringFromDouble
RexxNumberString * new_numberstringFromDouble(double n)
Definition: NumberStringClass.hpp:299
REQUEST_STRING
RexxString * REQUEST_STRING(RexxObject *object)
Definition: RexxCore.h:276
RexxString::Max
RexxObject * Max(RexxObject **args, size_t argCount)
Definition: StringClass.cpp:886
RexxActivation
Definition: RexxActivation.hpp:156
RexxString::rawString
static RexxString * rawString(size_t)
Definition: StringClass.cpp:2010
RexxInternalObject::setHasNoReferences
void setHasNoReferences()
Definition: ObjectClass.hpp:240
RexxString::strCompare
bool strCompare(const char *s)
Definition: StringClass.hpp:346
RexxNumberString
Definition: NumberStringClass.hpp:93
RexxString::putChar
char putChar(size_t p, char c)
Definition: StringClass.hpp:339
RexxString::operatorMethods
static PCPPM operatorMethods[]
Definition: StringClass.hpp:479
RexxString::concatWithCstring
RexxString * concatWithCstring(const char *)
Definition: StringClass.cpp:1271
wholenumber_t
ssize_t wholenumber_t
Definition: rexx.h:229
RexxString::lower
RexxString * lower()
Definition: StringClass.cpp:1526
RexxString::flatten
void flatten(RexxEnvelope *envelope)
Definition: StringClass.cpp:154
stringsize_t
size_t stringsize_t
Definition: rexx.h:228
CHAR_ORXMAX
char CHAR_ORXMAX[]
RexxString::orOp
RexxObject * orOp(RexxObject *)
Definition: StringClass.cpp:1788
RexxString::numberValue
bool numberValue(wholenumber_t &result, size_t precision)
Definition: StringClass.cpp:244
RexxString::length
size_t length
Definition: StringClass.hpp:487
RexxString::setNumberString
void setNumberString(RexxObject *)
Definition: StringClass.cpp:1724
RexxString::makeString
RexxString * makeString()
Definition: StringClass.cpp:199
RexxString::concatBlank
RexxString * concatBlank(RexxObject *)
Definition: StringClass.cpp:1291
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
RexxString::divide
RexxObject * divide(RexxObject *right)
Definition: StringClass.cpp:790
RexxString::getHashValue
virtual HashCode getHashValue()
Definition: StringClass.cpp:95
TheNilObject
#define TheNilObject
Definition: RexxCore.h:180
RexxNumberString::integerDivide
RexxNumberString * integerDivide(RexxObject *)
Definition: NumberStringClass.cpp:3169
RexxNumberString::round
RexxObject * round()
Definition: NumberStringClass.cpp:1744
isString
bool isString(RexxObject *o)
Definition: RexxCore.h:264
Error_Logical_value_method
#define Error_Logical_value_method
Definition: RexxErrorCodes.h:273
RexxString::strictNotEqual
RexxInteger * strictNotEqual(RexxObject *)
Definition: StringClass.cpp:1044
RexxObject::numberString
RexxNumberString * numberString()
Definition: ObjectClass.cpp:1018
RexxActivity.hpp
RexxNumberString::minus
RexxNumberString * minus(RexxObject *)
Definition: NumberStringClass.cpp:3105
RexxString::strictGreaterOrEqual
RexxInteger * strictGreaterOrEqual(RexxObject *)
Definition: StringClass.cpp:1148
RexxString::doubleValue
bool doubleValue(double &result)
Definition: StringClass.cpp:330
RexxNumberString::Min
RexxNumberString * Min(RexxObject **, size_t)
Definition: NumberStringClass.cpp:3258
stringArgument
RexxString * stringArgument(RexxObject *object, size_t position)
Definition: RexxCore.h:296
RexxString::put
void put(size_t s, const void *b, size_t l)
Definition: StringClass.hpp:335
RexxString::integerValue
RexxInteger * integerValue(size_t)
Definition: StringClass.cpp:1694
RexxString::copyData
size_t copyData(size_t, char *, size_t)
Definition: StringClass.cpp:450
RexxClass::processNewArgs
static void processNewArgs(RexxObject **, size_t, RexxObject ***, size_t *, size_t, RexxObject **, RexxObject **)
Definition: ClassClass.cpp:1701
RexxString::strictComp
wholenumber_t strictComp(RexxObject *)
Definition: StringClass.cpp:700
RexxNumberString::trunc
RexxObject * trunc(RexxObject *)
Definition: NumberStringClass.cpp:1296
RexxString::primitiveCaselessIsEqual
bool primitiveCaselessIsEqual(RexxObject *)
Definition: StringClass.cpp:542
RexxCore.h
RexxString::comp
wholenumber_t comp(RexxObject *)
Definition: StringClass.cpp:583
DirectoryClass.hpp
RexxInternalObject::isBaseClass
bool isBaseClass()
Definition: ObjectClass.cpp:172
RexxString::fastNumberString
RexxNumberString * fastNumberString()
Definition: StringClass.hpp:358
RexxCompoundTail
Definition: RexxCompoundTail.hpp:52
new_object
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:422
ch_ZERO
#define ch_ZERO
Definition: NumberStringClass.hpp:55
RexxString::concatRexx
RexxString * concatRexx(RexxObject *)
Definition: StringClass.cpp:1207
RexxString::integerDivide
RexxObject * integerDivide(RexxObject *right)
Definition: StringClass.cpp:806
RexxInteger
Definition: IntegerClass.hpp:56
RexxString::upper
RexxString * upper()
Definition: StringClass.cpp:1442
RexxObject::requestString
RexxString * requestString()
Definition: ObjectClass.cpp:1124
RexxString::logicalValue
virtual bool logicalValue(logical_t &)
Definition: StringClass.cpp:1386
RexxString::isGreaterThan
RexxInteger * isGreaterThan(RexxObject *)
Definition: StringClass.cpp:1076
RexxString::concat
RexxString * concat(RexxString *)
Definition: StringClass.cpp:1172
RexxString::setNonNumeric
void setNonNumeric()
Definition: StringClass.hpp:345
RexxString::round
RexxObject * round()
Definition: StringClass.cpp:977
RexxObject
Definition: ObjectClass.hpp:311
RexxNumberString::doubleValue
bool doubleValue(double &result)
Definition: NumberStringClass.cpp:672
RexxString
Definition: StringClass.hpp:119
CHAR_ORXMIN
char CHAR_ORXMIN[]
RexxString::NumberString
RexxNumberString * NumberString
Definition: StringClass.hpp:488
RexxInteger::getStringrep
RexxString * getStringrep()
Definition: IntegerClass.hpp:146
RexxString::stringTrace
RexxString * stringTrace()
Definition: StringClass.cpp:1474