StringClass.hpp
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.hpp */
40 /* */
41 /* Primitive String Class Definition */
42 /* */
43 /******************************************************************************/
44 #ifndef Included_RexxString
45 #define Included_RexxString
46 
47 #include "NumberStringClass.hpp"
48 #include "IntegerClass.hpp"
49 #include "StringUtil.hpp"
50 #include "Utilities.hpp"
51 
52  /* return values from the is_symbol */
53  /* validation method */
54 #define STRING_BAD_VARIABLE 0
55 #define STRING_STEM 1
56 #define STRING_COMPOUND_NAME 2
57 #define STRING_LITERAL 3
58 #define STRING_LITERAL_DOT 4
59 #define STRING_NUMERIC 5
60 #define STRING_NAME 6
61 
62 #define STRING_HASLOWER 0x01 /* string does contain lowercase */
63 #define STRING_NOLOWER 0x02 /* string does not contain lowercase */
64 #define STRING_NONNUMERIC 0x04 /* string is non-numeric */
65 #define STRING_ISASCII_CHECKED 0x08 /* string is ASCII only checked */
66 #define STRING_ISASCII 0x10 /* string is ASCII only */
67 #define STRING_EVAL_AS_TEXT 0x20 /* string evaluation returns text */
68 
69 #define INITIAL_NAME_SIZE 10 /* first name table allocation */
70 #define EXTENDED_NAME_SIZE 10 /* amount to extend table by */
71  /* Strip function options */
72 #define STRIP_BOTH 'B'
73 #define STRIP_LEADING 'L'
74 #define STRIP_TRAILING 'T'
75  /* Datatype function options */
76 #define DATATYPE_ALPHANUMERIC 'A'
77 #define DATATYPE_BINARY 'B'
78 #define DATATYPE_LOWERCASE 'L'
79 #define DATATYPE_MIXEDCASE 'M'
80 #define DATATYPE_NUMBER 'N'
81 #define DATATYPE_SYMBOL 'S'
82 #define DATATYPE_VARIABLE 'V'
83 #define DATATYPE_UPPERCASE 'U'
84 #define DATATYPE_WHOLE_NUMBER 'W'
85 #define DATATYPE_HEX 'X'
86 #define DATATYPE_9DIGITS '9'
87 #define DATATYPE_LOGICAL 'O' // lOgical.
88  /* Verify function options */
89 #define VERIFY_MATCH 'M'
90 #define VERIFY_NOMATCH 'N'
91 
92 #define ch_SPACE ' '
93 
94  /* character validation sets for the */
95  /* datatype function */
96 #define HEX_CHAR_STR "0123456789ABCDEFabcdef"
97 #define ALPHANUM \
98 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
99 #define BINARI "01"
100 #define LOWER_ALPHA "abcdefghijklmnopqrstuvwxyz"
101 #define MIXED_ALPHA \
102 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
103 #define UPPER_ALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
104 
105 
106 /*********************************************************************/
107 /* */
108 /* Name: IntToHexdigit */
109 /* */
110 /* Descriptive name: convert int to hexadecimal digit */
111 /* */
112 /* Returns: A hexadecimal digit representing n. */
113 /* */
114 /*********************************************************************/
115 
116  /* convert the number */
117 inline char IntToHexDigit(int n)
118 {
119  return "0123456789ABCDEF"[n];
120 }
121 
122  class RexxString : public RexxObject {
123  public:
124  inline void *operator new(size_t size, void *ptr){return ptr;};
125  // inline RexxString() {;} ;
126  RexxString();
127  // inline RexxString(RESTORETYPE restoreType) { ; };
128  RexxString(RESTORETYPE restoreType);
129  void checkTE(const char *method);
130  void checkTE(RESTORETYPE restoreType);
131 
132  void live(size_t);
133  void liveGeneral(int reason);
134  void flatten(RexxEnvelope *envelope);
136 
137  virtual HashCode hash();
138  virtual HashCode getHashValue();
139 
141  {
142  if (hashValue == 0) // if we've never generated this, the code is zero
143  {
144  stringsize_t len = this->getLength();
145 
146  HashCode h = 0;
147  // the hash code is generated from all of the string characters.
148  // we do this in a lazy fashion, since most string objects never need to
149  // calculate a hash code, particularly the long ones.
150  // This hashing algorithm is very similar to that used for Java strings.
151  for (stringsize_t i = 0; i < len; i++)
152  {
153  h = 31 * h + this->stringData[i];
154  }
155  this->hashValue = h;
156  }
157  return hashValue;
158  }
160 
161  virtual RexxObject *dynamicTarget(RexxObject **arguments, size_t count, size_t named_count);
162 
163  bool numberValue(wholenumber_t &result, size_t precision);
164  bool numberValue(wholenumber_t &result);
165  bool unsignedNumberValue(uwholenumber_t &result, size_t precision);
166  bool unsignedNumberValue(uwholenumber_t &result);
167  bool doubleValue(double &result);
169  RexxInteger *integerValue(size_t precision);
171  RexxArray *makeArray();
173  void copyIntoTail(RexxCompoundTail *buffer);
175  bool truthValue(int);
176  virtual bool logicalValue(logical_t &);
177 
178  bool isEqual(RexxObject *); // in behaviour
181  wholenumber_t strictComp(RexxObject *, RexxString *alternativeOperator=NULL, RexxInteger **alternativeOperatorResultPtr=NULL);
182  wholenumber_t comp(RexxObject *, RexxString *alternativeOperator=OREF_NULL, RexxInteger **alternativeOperatorResultPtr=NULL);
185  RexxInteger *strictEqual(RexxObject *); // in behaviour
186  RexxInteger *notEqual(RexxObject *); // in behaviour
187  RexxInteger *strictNotEqual(RexxObject *); // in behaviour
188  RexxInteger *isGreaterThan(RexxObject *); // in behaviour
189  RexxInteger *isLessThan(RexxObject *); // in behaviour
190  RexxInteger *isGreaterOrEqual(RexxObject *); // in behaviour
191  RexxInteger *isLessOrEqual(RexxObject *); // in behaviour
192  RexxInteger *strictGreaterThan(RexxObject *); // in behaviour
193  RexxInteger *strictLessThan(RexxObject *); // in behaviour
194  RexxInteger *strictGreaterOrEqual(RexxObject *); // in behaviour
195  RexxInteger *strictLessOrEqual(RexxObject *); // in behaviour
196 
197  size_t copyData(size_t, char *, size_t);
198  RexxObject *lengthRexx(); // in behaviour
199  RexxString *concatRexx(RexxObject *); // in behaviour
201  RexxString *concatToCstring(const char *);
202  RexxString *concatWithCstring(const char *);
203  RexxString *concatBlank(RexxObject *); // in behaviour
204  bool checkLower();
205  bool checkIsASCII();
207  RexxString *upper();
208  RexxString *upper(size_t, size_t);
209  RexxString *upperRexx(RexxInteger *, RexxInteger *); // in behaviour
210  RexxString *lower();
211  RexxString *lower(size_t, size_t);
212  RexxString *lowerRexx(RexxInteger *, RexxInteger *); // in behaviour
214  void setNumberString(RexxObject *);
215  RexxString *concatWith(RexxString *, char);
216 
217  RexxObject *plus(RexxObject *right); // in behaviour
218  RexxObject *minus(RexxObject *right); // in behaviour
219  RexxObject *multiply(RexxObject *right); // in behaviour
220  RexxObject *divide(RexxObject *right); // in behaviour
221  RexxObject *integerDivide(RexxObject *right); // in behaviour
222  RexxObject *remainder(RexxObject *right); // in behaviour
223  RexxObject *power(RexxObject *right); // in beahviour
224  RexxObject *abs(); // in behaviour
225  RexxObject *sign(); // in behaviour
226  RexxObject *notOp(); // in beahviour
228  RexxObject *andOp(RexxObject *); // in behaviour
229  RexxObject *orOp(RexxObject *); // in behaviour
230  RexxObject *xorOp(RexxObject *); // in behaviour
231  RexxObject *Max(RexxObject **args, size_t argCount, size_t named_argCount); // in behaviour
232  RexxObject *Min(RexxObject **args, size_t argCount, size_t named_argCount); // in behaviour
233  RexxObject *trunc(RexxInteger *decimals); // in behaviour
234  RexxObject *floor();
235  RexxObject *ceiling();
236  RexxObject *round();
237  RexxObject *format(RexxObject *Integers, RexxObject *Decimals, RexxObject *MathExp, RexxObject *ExpTrigger); // in behaviour
240  RexxString *extract(size_t offset, size_t sublength) { return newString(getStringData() + offset, sublength); }
246  /* the following methods are in */
247  /* OKBSUBS */
248  RexxString *center(RexxInteger *, RexxString *); // in behaviour
249  RexxString *delstr(RexxInteger *, RexxInteger *); // in behaviour
250  RexxString *insert(RexxString *, RexxInteger *, RexxInteger *, RexxString *); // in behaviour
251  RexxString *left(RexxInteger *, RexxString *); // in behaviour
252  RexxString *overlay(RexxString *, RexxInteger *, RexxInteger *, RexxString *); // in behaviour
253  RexxString *replaceAt(RexxString *, RexxInteger *, RexxInteger *, RexxString *); // in behaviour
254  RexxString *reverse(); // in behaviour
255  RexxString *right(RexxInteger *, RexxString *); // in behaviour
256  RexxString *strip(RexxString *, RexxString *); // in behaviour
257  RexxString *substr(RexxInteger *, RexxInteger *, RexxString *); // in behaviour
258  RexxString *subchar(RexxInteger *); // in behaviour
259  RexxString *delWord(RexxInteger *, RexxInteger *); // in behaviour
260  RexxString *space(RexxInteger *, RexxString *); // in behaviour
261  RexxString *subWord(RexxInteger *, RexxInteger *); // in behaviour
262  RexxArray *subWords(RexxInteger *, RexxInteger *); // in behaviour
263  RexxString *word(RexxInteger *); // in behaviour
264  RexxInteger *wordIndex(RexxInteger *); // in behaviour
265  RexxInteger *wordLength(RexxInteger *); // in behaviour
266  RexxInteger *wordPos(RexxString *, RexxInteger *); // in behaviour
267  RexxInteger *caselessWordPos(RexxString *, RexxInteger *); // in behaviour
268  RexxInteger *words(); // in behaviour
269  /* the following methods are in */
270  /* OKBMISC */
271  RexxString *changeStr(RexxString *, RexxString *, RexxInteger *); // in behaviour
273  RexxInteger *abbrev(RexxString *, RexxInteger *); // in behaviour
274  RexxInteger *caselessAbbrev(RexxString *, RexxInteger *); // in behaviour
275  RexxInteger *compare(RexxString *, RexxString *); // in behaviour
276  RexxInteger *caselessCompare(RexxString *, RexxString *); // in behaviour
277  RexxString *copies(RexxInteger *); // in behaviour
278  RexxObject *dataType(RexxString *); // in behaviour
279 
280  RexxInteger *lastPosRexx(RexxString *, RexxInteger *, RexxInteger *); // in behaviour
282  size_t lastPos(RexxString *needle, size_t start);
283  size_t caselessLastPos(RexxString *needle, size_t start);
284  const char * caselessLastPos(const char *needle, size_t needleLen, const char *haystack, size_t haystackLen);
285 
286  RexxInteger *posRexx(RexxString *, RexxInteger *, RexxInteger *); // in behaviour
288  size_t pos(RexxString *, size_t);
289  size_t caselessPos(RexxString *, size_t);
290 
292  RexxInteger *verify(RexxString *, RexxString *, RexxInteger *, RexxInteger *); // in behaviour
293  RexxInteger *countStrRexx(RexxString *); // in behaviour
294  RexxInteger *caselessCountStrRexx(RexxString *); // in behaviour
296  /* the following methods are in */
297  /* OKBBITS */
298  RexxString *bitAnd(RexxString *, RexxString *); // in behaviour
299  RexxString *bitOr(RexxString *, RexxString *); // in behaviour
300  RexxString *bitXor(RexxString *, RexxString *); // in behaviour
301  /* the following methods are in */
302  /* OKBCONV */
303  RexxString *b2x(); // in behaviour
304  RexxString *c2d(RexxInteger *); // in behaviour
305  RexxString *c2x(); // in behaviour
306  RexxString *encodeBase64(); // in behaviour
307  RexxString *decodeBase64(); // in behaviour
308  RexxString *d2c(RexxInteger *); // in behaviour
309  RexxString *d2x(RexxInteger *); // in behaviour
310  RexxString *x2b(); // in behaviour
311  RexxString *x2c(); // in behaviour
312  RexxString *x2d(RexxInteger *); // in behaviour
313  RexxString *x2dC2d(RexxInteger *, bool);
314 
315  RexxInteger *match(RexxInteger *start_, RexxString *other, RexxInteger *offset_, RexxInteger *len_); // in behaviour
316  RexxInteger *caselessMatch(RexxInteger *start_, RexxString *other, RexxInteger *offset_, RexxInteger *len_); // in behaviour
319  RexxInteger *matchChar(RexxInteger *position_, RexxString *matchSet); // in behaviour
320  RexxInteger *caselessMatchChar(RexxInteger *position_, RexxString *matchSet); // in behaviour
321 
322  RexxInteger *compareToRexx(RexxString *other, RexxInteger *start_, RexxInteger *len_); // in behaviour
323  RexxInteger *caselessCompareToRexx(RexxString *other, RexxInteger *start_, RexxInteger *len_); // in behaviour
326 
327  RexxInteger *equals(RexxString *other); // in behaviour
328  RexxInteger *caselessEquals(RexxString *other); // in behaviour
329 
330  RexxArray *makeArrayRexx(RexxString *); // in behaviour
331 
332 /****************************************************************************/
333 /* */
334 /* RexxString Methods in OKBMISC.C */
335 /* */
336 /****************************************************************************/
337  int isSymbol();
338 
339 /* Inline_functions */
340 
341  inline size_t getLength() { return this->length; };
342  inline void setLength(size_t l) { this->length = l; };
343  inline void finish(stringsize_t l) { this->length = l; }
344  inline const char *getStringData() { return this->stringData; };
345  inline char *getWritableData() { return &this->stringData[0]; };
346  inline void put(size_t s, const void *b, size_t l) { memcpy(getWritableData() + s, b, l); };
347  inline void put(size_t s, RexxString *o) { put(s, o->getStringData(), o->getLength()); };
348  inline void set(size_t s,int c, size_t l) { memset((this->stringData + s), c, l); };
349  inline char getChar(size_t p) { return *(this->stringData+p); };
350  inline char putChar(size_t p,char c) { return *(this->stringData+p) = c; };
351 
352  inline RexxObject *getText() { return this->text; }
353  inline void setText(RexxObject *t)
354  {
355  OrefSet(this, this->text, t);
356  if (t != OREF_NULL) this->setHasReferences();
357  }
359  {
360  RexxObject *previousText = this->getText();
361  this->setText(t);
362  return previousText;
363  }
364 
365  inline RexxObject *getEncoding() { return this->encoding; }
366  inline void setEncoding(RexxObject *e)
367  {
368  OrefSet(this, this->encoding, e);
369  if (e != OREF_NULL) this->setHasReferences();
370  }
372  {
373  RexxObject *previousEncoding = this->getEncoding();
374  this->setEncoding(e);
375  return previousEncoding;
376  }
377 
378  inline bool upperOnly() {return (this->Attributes&STRING_NOLOWER) != 0;};
379  inline bool hasLower() {return (this->Attributes&STRING_HASLOWER) != 0;};
380  inline void setUpperOnly() { this->Attributes |= STRING_NOLOWER;};
381  inline void setHasLower() { this->Attributes |= STRING_HASLOWER;};
382  inline bool nonNumeric() {return (this->Attributes&STRING_NONNUMERIC) != 0;};
383  inline void setNonNumeric() { this->Attributes |= STRING_NONNUMERIC;};
384 
385  inline bool isASCIIChecked() {return (this->Attributes & STRING_ISASCII_CHECKED) != 0;};
386  inline void setIsASCIIChecked(bool value=true)
387  {
388  if (value) this->Attributes |= STRING_ISASCII_CHECKED;
389  else
390  {
392  this->setIsASCII(false); // isASCII() can be true only when isASCIIChecked() is true
393  }
394  }
395  // if isASCII() is true then it's really ASCII
396  // if isASCII() is false then it's really not ASCII only when isASCIIChecked() is true, otherwise can't tell
397  inline bool isASCII() {return (this->Attributes & STRING_ISASCII) != 0;};
398  inline void setIsASCII(bool value=true)
399  {
400  if (value) this->Attributes |= STRING_ISASCII;
401  else this->Attributes &= ~STRING_ISASCII;
402  }
403 
404  inline bool evaluateAsText() {return (this->Attributes & STRING_EVAL_AS_TEXT) != 0;};
406 
407  inline bool strCompare(const char * s) {return this->memCompare((s), strlen(s));};
408  inline bool strCaselessCompare(const char * s) { return this->length == strlen(s) && Utilities::strCaselessCompare(s, this->stringData) == 0;}
409  inline bool memCompare(const char * s, size_t l) { return l == this->length && memcmp(s, this->stringData, l) == 0; }
410  inline bool memCompare(RexxString *other)
411  {
412  return other->length == this->length &&
413  memcmp(other->stringData, this->stringData, length) == 0;
414  }
415  inline void memCopy(char * s) { memcpy(s, stringData, length); }
417  inline void toRxstring(RXSTRING &r) { r.strptr = getWritableData(); r.strlength = getLength(); }
418  void copyToRxstring(RXSTRING &r);
419  inline bool endsWith(codepoint_t c) { return getLength() > 0 && this->getChar(this->getLength() - 1) == c; }
420 
422 
424  if (this->nonNumeric()) /* Did we already try and convert to */
425  /* to a numberstring and fail? */
426  return OREF_NULL; /* Yes, no need to try agian. */
427 
428  if (this->NumberString != OREF_NULL) /* see if we have already converted */
429  return this->NumberString; /* return the numberString Object. */
430  return createNumberString(); /* go build the number string version */
431  }
432 
433  inline int sortCompare(RexxString *other) {
434  size_t compareLength = length;
435  if (compareLength > other->length) {
436  compareLength = other->length;
437  }
438  int result = memcmp(stringData, other->stringData, compareLength);
439  if (result == 0) {
440  if (length > other->length) {
441  result = 1;
442  }
443  else if (length < other->length) {
444  result = -1;
445  }
446  }
447  return result;
448  }
449 
450  inline int sortCaselessCompare(RexxString *other) {
451  size_t compareLength = length;
452  if (compareLength > other->length) {
453  compareLength = other->length;
454  }
455  int result = StringUtil::caselessCompare(stringData, other->stringData, compareLength);
456  if (result == 0) {
457  if (length > other->length) {
458  result = 1;
459  }
460  else if (length < other->length) {
461  result = -1;
462  }
463  }
464  return result;
465  }
466 
467  inline int sortCompare(RexxString *other, size_t startCol, size_t colLength) {
468  int result = 0;
469  if ((startCol < length ) && (startCol < other->length)) {
470  size_t stringLength = length;
471  if (stringLength > other->length) {
472  stringLength = other->length;
473  }
474  stringLength = stringLength - startCol + 1;
475  size_t compareLength = colLength;
476  if (compareLength > stringLength) {
477  compareLength = stringLength;
478  }
479 
480  result = memcmp(stringData + startCol, other->stringData + startCol, compareLength);
481  if (result == 0 && stringLength < colLength) {
482  if (length > other->length) {
483  result = 1;
484  }
485  else if (length < other->length) {
486  result = -1;
487  }
488  }
489  }
490  else {
491  if (length == other->length) {
492  result = 0;
493  }
494  else {
495  result = length < other->length ? -1 : 1;
496  }
497  }
498  return result;
499  }
500 
501  inline int sortCaselessCompare(RexxString *other, size_t startCol, size_t colLength) {
502  int result = 0;
503  if ((startCol < length ) && (startCol < other->length)) {
504  size_t stringLength = length;
505  if (stringLength > other->length) {
506  stringLength = other->length;
507  }
508  stringLength = stringLength - startCol + 1;
509  size_t compareLength = colLength;
510  if (compareLength > stringLength) {
511  compareLength = stringLength;
512  }
513 
514  result = StringUtil::caselessCompare(stringData + startCol, other->stringData + startCol, compareLength);
515  if (result == 0 && stringLength < colLength) {
516  if (length > other->length) {
517  result = 1;
518  }
519  else if (length < other->length) {
520  result = -1;
521  }
522  }
523  }
524  else {
525  if (length == other->length) {
526  result = 0;
527  }
528  else {
529  result = length < other->length ? -1 : 1;
530  }
531  }
532  return result;
533  }
534 
535 
536  static RexxString *newString(const char *, size_t l);
537  static RexxString *rawString(size_t l);
538  static RexxString *newUpperString(const char *, stringsize_t l);
539  static RexxString *newString(double d);
540  static RexxString *newString(double d, size_t precision);
541  static RexxString *newProxy(const char *);
542  // NB: newRexx() cannot be static and exported as an ooRexx method.
543  RexxString *newRexx(RexxObject **, size_t, size_t); // in behaviour
545 
546  static void createInstance();
548 
549  protected:
550 
551  HashCode hashValue; // stored has value
552  size_t length; /* string length in bytes */
553  RexxNumberString *NumberString; /* lookaside information */
554  RexxObject *text; // The text counterpart or OREF_NULL
555  RexxObject *encoding; // string encoding or OREF_NULL
556  size_t Attributes; /* string attributes */
557  char stringData[4]; /* Start of the string data part */
558  };
559 
560 
561 // some handy functions for doing cstring/RexxString manipulations
562 
563  inline void * rmemcpy(void *t, RexxString *s, size_t blen)
564  {
565  return memcpy(t, s->getStringData(), blen);
566  }
567 
568  inline int rmemcmp(const void *t, RexxString *s, size_t blen)
569  {
570  return memcmp(t, s->getStringData(), blen);
571  }
572 
573  inline char * rstrcpy(char *t, RexxString *s)
574  {
575  return strcpy(t, s->getStringData());
576  }
577 
578  inline char * rstrcat(char *t, RexxString *s)
579  {
580  return strcat(t, s->getStringData());
581  }
582 
583  inline int rstrcmp(const char *t, RexxString *s)
584  {
585  return strcmp(t, s->getStringData());
586  }
587 
588  inline int rsnprintf(RexxString *s, const char *format, ...)
589  {
590  va_list args;
591  va_start(args, format);
592  int n = Utilities::vsnprintf(s->getWritableData(), s->getLength(), format, args);
593  va_end(args);
594  s->finish(n >= 0 ? n : 0);
595  return n;
596  }
597 
598 // String creation inline functions
599 
600 inline RexxString *new_string(const char *s, stringsize_t l)
601 {
602  return RexxString::newString(s, l);
603 }
604 
606 {
607  return RexxString::rawString(l);
608 }
609 
610 inline RexxString *new_string(double d)
611 {
612  return RexxString::newString(d);
613 }
614 
615 inline RexxString *new_string(double d, size_t p)
616 {
617  return RexxString::newString(d, p);
618 }
619 
620 
621 inline RexxString *new_string(const char *string)
622 {
623  return new_string(string, strlen(string));
624 }
625 
626 inline RexxString *new_string(char cc)
627 {
628  return new_string(&cc, 1);
629 }
630 
632 {
633  return new_string(r.strptr, r.strlength);
634 }
635 
637 {
638  return new_string(r.strptr, r.strlength);
639 }
640 
641 inline RexxString *new_proxy(const char *name)
642 {
643  return RexxString::newProxy(name);
644 }
645 
646 inline RexxString *new_upper_string(const char *s, stringsize_t l)
647 {
648  return RexxString::newUpperString(s, l);
649 }
650 
651 inline RexxString *new_upper_string(const char *string)
652 {
653  return new_upper_string(string, strlen(string));
654 }
655 
656 inline bool isStem(const char *cstring)
657 {
658  // More strict than RexxVariable::isStem which tests only if the last character is a period.
659  // Redundant with RexxString->isSymbol() == STRING_STEM, but isSymbol wants a RexxString*
660  // Here, I pass a const char *
661  // Returns true if cstrings ends with '.' and contains only one '.'
662  const char *firstPeriod = strchr(cstring, '.');
663  return (firstPeriod != NULL && *(firstPeriod + 1) == '\0');
664 }
665 
666 #endif
RESTORETYPE
Definition: ObjectClass.hpp:82
RexxObject *(RexxObject::* PCPPM)()
size_t HashCode
Definition: ObjectClass.hpp:79
#define OREF_NULL
Definition: RexxCore.h:61
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
#define STRING_NOLOWER
Definition: StringClass.hpp:63
void * rmemcpy(void *t, RexxString *s, size_t blen)
char * rstrcat(char *t, RexxString *s)
#define STRING_ISASCII
Definition: StringClass.hpp:66
RexxString * raw_string(stringsize_t l)
RexxString * new_string(const char *s, stringsize_t l)
bool isStem(const char *cstring)
#define STRING_NONNUMERIC
Definition: StringClass.hpp:64
char * rstrcpy(char *t, RexxString *s)
#define STRING_HASLOWER
Definition: StringClass.hpp:62
#define STRING_ISASCII_CHECKED
Definition: StringClass.hpp:65
RexxString * new_proxy(const char *name)
char IntToHexDigit(int n)
RexxString * new_upper_string(const char *s, stringsize_t l)
int rmemcmp(const void *t, RexxString *s, size_t blen)
int rstrcmp(const char *t, RexxString *s)
#define STRING_EVAL_AS_TEXT
Definition: StringClass.hpp:67
int rsnprintf(RexxString *s, const char *format,...)
RexxMessage * start(RexxObject **, size_t, size_t)
RexxObject * makeArrayRexx()
RexxString * stringValue()
bool numberValue(wholenumber_t &result, size_t precision)
RexxInteger * isLessOrEqual(RexxObject *)
bool truthValue(int)
RexxArray * subWords(RexxInteger *, RexxInteger *)
size_t lastPos(RexxString *needle, size_t start)
RexxInteger * isLessThan(RexxObject *)
RexxString * concatRexx(RexxObject *)
static void createInstance()
Definition: StringClass.cpp:71
const char * caselessLastPos(const char *needle, size_t needleLen, const char *haystack, size_t haystackLen)
RexxInteger * strictEqual(RexxObject *)
RexxString * c2x()
RexxInteger * caselessEquals(RexxString *other)
static RexxString * newProxy(const char *)
void checkTE(const char *method)
Definition: StringClass.cpp:77
RexxObject * trunc(RexxInteger *decimals)
bool hasLower()
RexxString * changeStr(RexxString *, RexxString *, RexxInteger *)
RexxInteger * caselessLastPosRexx(RexxString *, RexxInteger *, RexxInteger *)
void toRxstring(CONSTRXSTRING &r)
RexxObject * xorOp(RexxObject *)
RexxString * translate(RexxString *, RexxString *, RexxString *, RexxInteger *, RexxInteger *)
size_t getLength()
RexxObject * operatorNot(RexxObject *)
RexxObject * Min(RexxObject **args, size_t argCount, size_t named_argCount)
RexxString * bitOr(RexxString *, RexxString *)
bool primitiveMatch(stringsize_t start, RexxString *other, stringsize_t offset, stringsize_t len)
bool primitiveCaselessIsEqual(RexxObject *)
RexxObject * getEncoding()
char stringData[4]
int sortCaselessCompare(RexxString *other, size_t startCol, size_t colLength)
bool strCaselessCompare(const char *s)
RexxInteger * strictGreaterThan(RexxObject *)
RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
RexxString * delstr(RexxInteger *, RexxInteger *)
RexxString * upperRexx(RexxInteger *, RexxInteger *)
bool upperOnly()
HashCode getObjectHashCode()
bool checkIsASCII()
RexxString * bitAnd(RexxString *, RexxString *)
RexxInteger * wordIndex(RexxInteger *)
RexxObject * getText()
size_t caselessPos(RexxString *, size_t)
RexxInteger * notEqual(RexxObject *)
RexxInteger * strictLessOrEqual(RexxObject *)
void setevaluateAsText()
bool evaluateAsText()
RexxNumberString * createNumberString()
RexxString * overlay(RexxString *, RexxInteger *, RexxInteger *, RexxString *)
bool isASCII()
size_t pos(RexxString *, size_t)
RexxObject * lengthRexx()
RexxInteger * abbrev(RexxString *, RexxInteger *)
RexxNumberString * fastNumberString()
RexxObject * format(RexxObject *Integers, RexxObject *Decimals, RexxObject *MathExp, RexxObject *ExpTrigger)
bool doubleValue(double &result)
void toRxstring(RXSTRING &r)
void liveGeneral(int reason)
RexxString * b2x()
RexxInteger * caselessMatchChar(RexxInteger *position_, RexxString *matchSet)
RexxString * makeString()
RexxString * subWord(RexxInteger *, RexxInteger *)
RexxObject * logicalOperation(RexxObject *, RexxObject *, unsigned int)
const char * getStringData()
RexxInteger * verify(RexxString *, RexxString *, RexxInteger *, RexxInteger *)
RexxInteger * caselessMatch(RexxInteger *start_, RexxString *other, RexxInteger *offset_, RexxInteger *len_)
RexxString * caselessChangeStr(RexxString *, RexxString *, RexxInteger *)
void setHasLower()
RexxString * space(RexxInteger *, RexxString *)
RexxString * encodeBase64()
RexxInteger * caselessPosRexx(RexxString *, RexxInteger *, RexxInteger *)
RexxObject * integerDivide(RexxObject *right)
void setNumberString(RexxObject *)
RexxObject * remainder(RexxObject *right)
RexxString * d2x(RexxInteger *)
RexxObject * Max(RexxObject **args, size_t argCount, size_t named_argCount)
RexxInteger * integerValue(size_t precision)
RexxObject * ceiling()
RexxInteger * match(RexxInteger *start_, RexxString *other, RexxInteger *offset_, RexxInteger *len_)
RexxString * concatBlank(RexxObject *)
RexxInteger * caselessCountStrRexx(RexxString *)
RexxNumberString * numberString()
void setEncoding(RexxObject *e)
size_t Attributes
RexxString * d2c(RexxInteger *)
RexxInteger * lastPosRexx(RexxString *, RexxInteger *, RexxInteger *)
bool isASCIIChecked()
void set(size_t s, int c, size_t l)
static RexxString * newString(const char *, size_t l)
RexxObject * setTextRexx(RexxObject *t)
RexxString * x2dC2d(RexxInteger *, bool)
RexxInteger * compareToRexx(RexxString *other, RexxInteger *start_, RexxInteger *len_)
void setIsASCIIChecked(bool value=true)
RexxObject * getRealValue(RexxActivation *)
RexxInteger * compare(RexxString *, RexxString *)
bool primitiveIsEqual(RexxObject *)
RexxObject * plus(RexxObject *right)
int sortCaselessCompare(RexxString *other)
RexxInteger * caselessCompare(RexxString *, RexxString *)
RexxInteger * strictLessThan(RexxObject *)
RexxInteger * strictGreaterOrEqual(RexxObject *)
bool memCompare(RexxString *other)
void setIsASCII(bool value=true)
RexxString * extract(size_t offset, size_t sublength)
RexxString * bitXor(RexxString *, RexxString *)
char * getWritableData()
RexxString * lower()
RexxString * word(RexxInteger *)
void flatten(RexxEnvelope *envelope)
size_t copyData(size_t, char *, size_t)
RexxString * x2d(RexxInteger *)
RexxString * left(RexxInteger *, RexxString *)
RexxInteger * words()
RexxInteger * matchChar(RexxInteger *position_, RexxString *matchSet)
bool memCompare(const char *s, size_t l)
RexxObject * notOp()
void memCopy(char *s)
RexxInteger * equal(RexxObject *)
RexxObject * encoding
virtual HashCode hash()
RexxObject * multiply(RexxObject *right)
RexxString * subchar(RexxInteger *)
RexxString * substr(RexxInteger *, RexxInteger *, RexxString *)
RexxString * replaceAt(RexxString *, RexxInteger *, RexxInteger *, RexxString *)
RexxString * concatWithCstring(const char *)
RexxObject * dataType(RexxString *)
static RexxClass * classInstance
size_t caselessLastPos(RexxString *needle, size_t start)
virtual bool logicalValue(logical_t &)
RexxObject * setEncodingRexx(RexxObject *e)
RexxObject * andOp(RexxObject *)
size_t caselessCountStr(RexxString *)
bool isEqual(RexxObject *)
wholenumber_t comp(RexxObject *, RexxString *alternativeOperator=OREF_NULL, RexxInteger **alternativeOperatorResultPtr=NULL)
virtual HashCode getHashValue()
RexxInteger * caselessWordPos(RexxString *, RexxInteger *)
RexxString * concat(RexxString *)
RexxString * concatWith(RexxString *, char)
bool checkLower()
RexxString * c2d(RexxInteger *)
char putChar(size_t p, char c)
void setText(RexxObject *t)
RexxObject * getValue(RexxActivation *)
RexxInteger * caselessCompareToRexx(RexxString *other, RexxInteger *start_, RexxInteger *len_)
bool endsWith(codepoint_t c)
RexxObject * round()
RexxInteger * posRexx(RexxString *, RexxInteger *, RexxInteger *)
RexxString * stringTrace()
RexxInteger * wordLength(RexxInteger *)
void setLength(size_t l)
RexxString * concatToCstring(const char *)
wholenumber_t compareTo(RexxObject *)
RexxNumberString * NumberString
RexxString * copies(RexxInteger *)
RexxString * right(RexxInteger *, RexxString *)
bool strCompare(const char *s)
RexxInteger * primitiveCompareTo(RexxString *other, stringsize_t start, stringsize_t len)
HashCode getStringHash()
RexxString * x2b()
void copyToRxstring(RXSTRING &r)
int sortCompare(RexxString *other, size_t startCol, size_t colLength)
void setNonNumeric()
RexxString * x2c()
RexxString * reverse()
RexxObject * isInteger()
RexxInteger * isASCIIRexx()
RexxInteger * countStrRexx(RexxString *)
bool nonNumeric()
RexxString * upper()
void live(size_t)
RexxInteger * wordPos(RexxString *, RexxInteger *)
RexxObject * floor()
RexxInteger * caselessAbbrev(RexxString *, RexxInteger *)
RexxInteger * isGreaterOrEqual(RexxObject *)
RexxObject * orOp(RexxObject *)
RexxString * newRexx(RexxObject **, size_t, size_t)
HashCode hashValue
RexxObject * divide(RexxObject *right)
int sortCompare(RexxString *other)
RexxObject * unflatten(RexxEnvelope *)
RexxString * insert(RexxString *, RexxInteger *, RexxInteger *, RexxString *)
RexxString * strip(RexxString *, RexxString *)
RexxArray * makeArray()
RexxString * delWord(RexxInteger *, RexxInteger *)
static RexxString * rawString(size_t l)
RexxInteger * equals(RexxString *other)
void put(size_t s, RexxString *o)
void put(size_t s, const void *b, size_t l)
RexxObject * abs()
RexxInteger * primitiveCaselessCompareTo(RexxString *other, stringsize_t start, stringsize_t len)
void setUpperOnly()
size_t length
void finish(stringsize_t l)
RexxInteger * isGreaterThan(RexxObject *)
char getChar(size_t p)
bool primitiveCaselessMatch(stringsize_t start, RexxString *other, stringsize_t offset, stringsize_t len)
wholenumber_t strictComp(RexxObject *, RexxString *alternativeOperator=NULL, RexxInteger **alternativeOperatorResultPtr=NULL)
RexxObject * power(RexxObject *right)
RexxObject * text
RexxString * decodeBase64()
RexxString * lowerRexx(RexxInteger *, RexxInteger *)
bool unsignedNumberValue(uwholenumber_t &result, size_t precision)
static PCPPM operatorMethods[]
RexxString * primitiveMakeString()
virtual RexxObject * dynamicTarget(RexxObject **arguments, size_t count, size_t named_count)
RexxInteger * strictNotEqual(RexxObject *)
RexxString * center(RexxInteger *, RexxString *)
static RexxString * newUpperString(const char *, stringsize_t l)
RexxObject * sign()
RexxObject * minus(RexxObject *right)
void copyIntoTail(RexxCompoundTail *buffer)
static int caselessCompare(const char *, const char *, size_t)
Definition: StringUtil.cpp:580
static int strCaselessCompare(const char *opt1, const char *opt2)
Definition: Utilities.cpp:102
static int vsnprintf(char *buffer, size_t count, const char *format, va_list args)
size_t logical_t
Definition: rexx.h:231
ssize_t codepoint_t
Definition: rexx.h:232
ssize_t wholenumber_t
Definition: rexx.h:230
size_t stringsize_t
Definition: rexx.h:228
size_t uwholenumber_t
Definition: rexx.h:229
const char * strptr
Definition: rexx.h:163
size_t strlength
Definition: rexx.h:162
size_t strlength
Definition: rexx.h:157
char * strptr
Definition: rexx.h:158