Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
- http://pymbed.appspot.com/
- https://code.google.com/p/python-on-a-chip/
- http://www.youtube.com/watch?v=Oyqc2bFRW9I
- https://bitbucket.org/va009039/pymbed/
more info: python-on-a-chip
vm/strobj.c@0:65f1469d6bfb, 2013-03-02 (annotated)
- Committer:
- va009039
- Date:
- Sat Mar 02 11:54:20 2013 +0000
- Revision:
- 0:65f1469d6bfb
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:65f1469d6bfb | 1 | /* |
va009039 | 0:65f1469d6bfb | 2 | # This file is Copyright 2002 Dean Hall. |
va009039 | 0:65f1469d6bfb | 3 | # This file is part of the PyMite VM. |
va009039 | 0:65f1469d6bfb | 4 | # This file is licensed under the MIT License. |
va009039 | 0:65f1469d6bfb | 5 | # See the LICENSE file for details. |
va009039 | 0:65f1469d6bfb | 6 | */ |
va009039 | 0:65f1469d6bfb | 7 | |
va009039 | 0:65f1469d6bfb | 8 | |
va009039 | 0:65f1469d6bfb | 9 | #undef __FILE_ID__ |
va009039 | 0:65f1469d6bfb | 10 | #define __FILE_ID__ 0x12 |
va009039 | 0:65f1469d6bfb | 11 | |
va009039 | 0:65f1469d6bfb | 12 | |
va009039 | 0:65f1469d6bfb | 13 | /** |
va009039 | 0:65f1469d6bfb | 14 | * \file |
va009039 | 0:65f1469d6bfb | 15 | * \brief String Object Type |
va009039 | 0:65f1469d6bfb | 16 | * |
va009039 | 0:65f1469d6bfb | 17 | * String object type opeartions. |
va009039 | 0:65f1469d6bfb | 18 | */ |
va009039 | 0:65f1469d6bfb | 19 | |
va009039 | 0:65f1469d6bfb | 20 | #include "pm.h" |
va009039 | 0:65f1469d6bfb | 21 | |
va009039 | 0:65f1469d6bfb | 22 | |
va009039 | 0:65f1469d6bfb | 23 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 24 | /** String obj cachche: a list of all string objects. */ |
va009039 | 0:65f1469d6bfb | 25 | static pPmString_t pstrcache = C_NULL; |
va009039 | 0:65f1469d6bfb | 26 | #endif /* USE_STRING_CACHE */ |
va009039 | 0:65f1469d6bfb | 27 | |
va009039 | 0:65f1469d6bfb | 28 | |
va009039 | 0:65f1469d6bfb | 29 | /* The following 2 ascii values are used to escape printing to ipm */ |
va009039 | 0:65f1469d6bfb | 30 | #define REPLY_TERMINATOR 0x04 |
va009039 | 0:65f1469d6bfb | 31 | #define ESCAPE_CHAR 0x1B |
va009039 | 0:65f1469d6bfb | 32 | |
va009039 | 0:65f1469d6bfb | 33 | |
va009039 | 0:65f1469d6bfb | 34 | /* |
va009039 | 0:65f1469d6bfb | 35 | * If USE_STRING_CACHE is defined nonzero, the string cache |
va009039 | 0:65f1469d6bfb | 36 | * will be searched for an existing String object. |
va009039 | 0:65f1469d6bfb | 37 | * If not found, a new object is created and inserted |
va009039 | 0:65f1469d6bfb | 38 | * into the cache. |
va009039 | 0:65f1469d6bfb | 39 | */ |
va009039 | 0:65f1469d6bfb | 40 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 41 | string_create(PmMemSpace_t memspace, uint8_t const **paddr, int16_t len, |
va009039 | 0:65f1469d6bfb | 42 | int16_t n, pPmObj_t *r_pstring) |
va009039 | 0:65f1469d6bfb | 43 | { |
va009039 | 0:65f1469d6bfb | 44 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 45 | pPmString_t pstr = C_NULL; |
va009039 | 0:65f1469d6bfb | 46 | uint8_t *pdst = C_NULL; |
va009039 | 0:65f1469d6bfb | 47 | uint8_t const *psrc = C_NULL; |
va009039 | 0:65f1469d6bfb | 48 | |
va009039 | 0:65f1469d6bfb | 49 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 50 | pPmString_t pcacheentry = C_NULL; |
va009039 | 0:65f1469d6bfb | 51 | #endif /* USE_STRING_CACHE */ |
va009039 | 0:65f1469d6bfb | 52 | uint8_t *pchunk; |
va009039 | 0:65f1469d6bfb | 53 | |
va009039 | 0:65f1469d6bfb | 54 | /* If loading from an image, get length from the image */ |
va009039 | 0:65f1469d6bfb | 55 | if (len < 0) |
va009039 | 0:65f1469d6bfb | 56 | { |
va009039 | 0:65f1469d6bfb | 57 | len = mem_getWord(memspace, paddr); |
va009039 | 0:65f1469d6bfb | 58 | } |
va009039 | 0:65f1469d6bfb | 59 | |
va009039 | 0:65f1469d6bfb | 60 | /* If loading from a C string, get its strlen (first null) */ |
va009039 | 0:65f1469d6bfb | 61 | else if (len == 0) |
va009039 | 0:65f1469d6bfb | 62 | { |
va009039 | 0:65f1469d6bfb | 63 | len = sli_strlen((char const *)*paddr); |
va009039 | 0:65f1469d6bfb | 64 | } |
va009039 | 0:65f1469d6bfb | 65 | |
va009039 | 0:65f1469d6bfb | 66 | /* Get space for String obj */ |
va009039 | 0:65f1469d6bfb | 67 | retval = heap_getChunk(sizeof(PmString_t) + len * n, &pchunk); |
va009039 | 0:65f1469d6bfb | 68 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 69 | pstr = (pPmString_t)pchunk; |
va009039 | 0:65f1469d6bfb | 70 | |
va009039 | 0:65f1469d6bfb | 71 | /* Fill the string obj */ |
va009039 | 0:65f1469d6bfb | 72 | OBJ_SET_TYPE(pstr, OBJ_TYPE_STR); |
va009039 | 0:65f1469d6bfb | 73 | pstr->length = len * n; |
va009039 | 0:65f1469d6bfb | 74 | |
va009039 | 0:65f1469d6bfb | 75 | /* Copy C-string into String obj */ |
va009039 | 0:65f1469d6bfb | 76 | pdst = (uint8_t *)&(pstr->val); |
va009039 | 0:65f1469d6bfb | 77 | while (--n >= 0) |
va009039 | 0:65f1469d6bfb | 78 | { |
va009039 | 0:65f1469d6bfb | 79 | psrc = *paddr; |
va009039 | 0:65f1469d6bfb | 80 | mem_copy(memspace, &pdst, &psrc, len); |
va009039 | 0:65f1469d6bfb | 81 | } |
va009039 | 0:65f1469d6bfb | 82 | |
va009039 | 0:65f1469d6bfb | 83 | /* Be sure paddr points to one byte past the end of the source string */ |
va009039 | 0:65f1469d6bfb | 84 | *paddr = psrc; |
va009039 | 0:65f1469d6bfb | 85 | |
va009039 | 0:65f1469d6bfb | 86 | /* Zero-pad end of string */ |
va009039 | 0:65f1469d6bfb | 87 | for (; pdst < (uint8_t *)pstr + PM_OBJ_GET_SIZE(pstr); pdst++) |
va009039 | 0:65f1469d6bfb | 88 | { |
va009039 | 0:65f1469d6bfb | 89 | *pdst = 0; |
va009039 | 0:65f1469d6bfb | 90 | } |
va009039 | 0:65f1469d6bfb | 91 | |
va009039 | 0:65f1469d6bfb | 92 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 93 | /* Check for twin string in cache */ |
va009039 | 0:65f1469d6bfb | 94 | for (pcacheentry = pstrcache; |
va009039 | 0:65f1469d6bfb | 95 | pcacheentry != C_NULL; pcacheentry = pcacheentry->next) |
va009039 | 0:65f1469d6bfb | 96 | { |
va009039 | 0:65f1469d6bfb | 97 | /* If string already exists */ |
va009039 | 0:65f1469d6bfb | 98 | if (string_compare(pcacheentry, pstr) == C_SAME) |
va009039 | 0:65f1469d6bfb | 99 | { |
va009039 | 0:65f1469d6bfb | 100 | /* Free the string */ |
va009039 | 0:65f1469d6bfb | 101 | retval = heap_freeChunk((pPmObj_t)pstr); |
va009039 | 0:65f1469d6bfb | 102 | |
va009039 | 0:65f1469d6bfb | 103 | /* Return ptr to old */ |
va009039 | 0:65f1469d6bfb | 104 | *r_pstring = (pPmObj_t)pcacheentry; |
va009039 | 0:65f1469d6bfb | 105 | return retval; |
va009039 | 0:65f1469d6bfb | 106 | } |
va009039 | 0:65f1469d6bfb | 107 | } |
va009039 | 0:65f1469d6bfb | 108 | |
va009039 | 0:65f1469d6bfb | 109 | /* Insert string obj into cache */ |
va009039 | 0:65f1469d6bfb | 110 | pstr->next = pstrcache; |
va009039 | 0:65f1469d6bfb | 111 | pstrcache = pstr; |
va009039 | 0:65f1469d6bfb | 112 | |
va009039 | 0:65f1469d6bfb | 113 | #endif /* USE_STRING_CACHE */ |
va009039 | 0:65f1469d6bfb | 114 | |
va009039 | 0:65f1469d6bfb | 115 | *r_pstring = (pPmObj_t)pstr; |
va009039 | 0:65f1469d6bfb | 116 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 117 | } |
va009039 | 0:65f1469d6bfb | 118 | |
va009039 | 0:65f1469d6bfb | 119 | |
va009039 | 0:65f1469d6bfb | 120 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 121 | string_newFromChar(uint8_t const c, pPmObj_t *r_pstring) |
va009039 | 0:65f1469d6bfb | 122 | { |
va009039 | 0:65f1469d6bfb | 123 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 124 | uint8_t cstr[2]; |
va009039 | 0:65f1469d6bfb | 125 | uint8_t const *pcstr; |
va009039 | 0:65f1469d6bfb | 126 | |
va009039 | 0:65f1469d6bfb | 127 | cstr[0] = c; |
va009039 | 0:65f1469d6bfb | 128 | cstr[1] = '\0'; |
va009039 | 0:65f1469d6bfb | 129 | pcstr = cstr; |
va009039 | 0:65f1469d6bfb | 130 | |
va009039 | 0:65f1469d6bfb | 131 | retval = string_new(&pcstr, r_pstring); |
va009039 | 0:65f1469d6bfb | 132 | |
va009039 | 0:65f1469d6bfb | 133 | /* If c was a null character, force the length to 1 */ |
va009039 | 0:65f1469d6bfb | 134 | if (c == '\0') |
va009039 | 0:65f1469d6bfb | 135 | { |
va009039 | 0:65f1469d6bfb | 136 | ((pPmString_t)*r_pstring)->length = 1; |
va009039 | 0:65f1469d6bfb | 137 | } |
va009039 | 0:65f1469d6bfb | 138 | |
va009039 | 0:65f1469d6bfb | 139 | return retval; |
va009039 | 0:65f1469d6bfb | 140 | } |
va009039 | 0:65f1469d6bfb | 141 | |
va009039 | 0:65f1469d6bfb | 142 | |
va009039 | 0:65f1469d6bfb | 143 | int8_t |
va009039 | 0:65f1469d6bfb | 144 | string_compare(pPmString_t pstr1, pPmString_t pstr2) |
va009039 | 0:65f1469d6bfb | 145 | { |
va009039 | 0:65f1469d6bfb | 146 | /* Return false if lengths are not equal */ |
va009039 | 0:65f1469d6bfb | 147 | if (pstr1->length != pstr2->length) |
va009039 | 0:65f1469d6bfb | 148 | { |
va009039 | 0:65f1469d6bfb | 149 | return C_DIFFER; |
va009039 | 0:65f1469d6bfb | 150 | } |
va009039 | 0:65f1469d6bfb | 151 | |
va009039 | 0:65f1469d6bfb | 152 | /* Compare the strings' contents */ |
va009039 | 0:65f1469d6bfb | 153 | return sli_strncmp((char const *)&(pstr1->val), |
va009039 | 0:65f1469d6bfb | 154 | (char const *)&(pstr2->val), |
va009039 | 0:65f1469d6bfb | 155 | pstr1->length) == 0 ? C_SAME : C_DIFFER; |
va009039 | 0:65f1469d6bfb | 156 | } |
va009039 | 0:65f1469d6bfb | 157 | |
va009039 | 0:65f1469d6bfb | 158 | |
va009039 | 0:65f1469d6bfb | 159 | #ifdef HAVE_PRINT |
va009039 | 0:65f1469d6bfb | 160 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 161 | string_printFormattedBytes(uint8_t *pb, uint8_t is_escaped, uint16_t n) |
va009039 | 0:65f1469d6bfb | 162 | { |
va009039 | 0:65f1469d6bfb | 163 | uint16_t i; |
va009039 | 0:65f1469d6bfb | 164 | uint8_t ch; |
va009039 | 0:65f1469d6bfb | 165 | uint8_t nibble; |
va009039 | 0:65f1469d6bfb | 166 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 167 | |
va009039 | 0:65f1469d6bfb | 168 | if (is_escaped) |
va009039 | 0:65f1469d6bfb | 169 | { |
va009039 | 0:65f1469d6bfb | 170 | retval = plat_putByte('\''); |
va009039 | 0:65f1469d6bfb | 171 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 172 | } |
va009039 | 0:65f1469d6bfb | 173 | |
va009039 | 0:65f1469d6bfb | 174 | for (i = 0; i < n; i++) |
va009039 | 0:65f1469d6bfb | 175 | { |
va009039 | 0:65f1469d6bfb | 176 | ch = pb[i]; |
va009039 | 0:65f1469d6bfb | 177 | if (is_escaped && (ch == '\\')) |
va009039 | 0:65f1469d6bfb | 178 | { |
va009039 | 0:65f1469d6bfb | 179 | /* Output an additional backslash to escape it. */ |
va009039 | 0:65f1469d6bfb | 180 | retval = plat_putByte('\\'); |
va009039 | 0:65f1469d6bfb | 181 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 182 | } |
va009039 | 0:65f1469d6bfb | 183 | |
va009039 | 0:65f1469d6bfb | 184 | /* Print the hex escape code of non-printable characters */ |
va009039 | 0:65f1469d6bfb | 185 | if (is_escaped |
va009039 | 0:65f1469d6bfb | 186 | && ((ch < (uint8_t)32) || (ch >= (uint8_t)128) || (ch == '\''))) |
va009039 | 0:65f1469d6bfb | 187 | { |
va009039 | 0:65f1469d6bfb | 188 | plat_putByte('\\'); |
va009039 | 0:65f1469d6bfb | 189 | plat_putByte('x'); |
va009039 | 0:65f1469d6bfb | 190 | |
va009039 | 0:65f1469d6bfb | 191 | nibble = (ch >> (uint8_t)4) + '0'; |
va009039 | 0:65f1469d6bfb | 192 | if (nibble > '9') |
va009039 | 0:65f1469d6bfb | 193 | nibble += ('a' - '0' - (uint8_t)10); |
va009039 | 0:65f1469d6bfb | 194 | plat_putByte(nibble); |
va009039 | 0:65f1469d6bfb | 195 | |
va009039 | 0:65f1469d6bfb | 196 | nibble = (ch & (uint8_t)0x0F) + '0'; |
va009039 | 0:65f1469d6bfb | 197 | if (nibble > '9') |
va009039 | 0:65f1469d6bfb | 198 | nibble += ('a' - '0' - (uint8_t)10); |
va009039 | 0:65f1469d6bfb | 199 | plat_putByte(nibble); |
va009039 | 0:65f1469d6bfb | 200 | } |
va009039 | 0:65f1469d6bfb | 201 | else |
va009039 | 0:65f1469d6bfb | 202 | { |
va009039 | 0:65f1469d6bfb | 203 | /* Escape the escape and reply terminator chars */ |
va009039 | 0:65f1469d6bfb | 204 | if ((ch == ESCAPE_CHAR) || (ch == REPLY_TERMINATOR)) |
va009039 | 0:65f1469d6bfb | 205 | { |
va009039 | 0:65f1469d6bfb | 206 | plat_putByte(ESCAPE_CHAR); |
va009039 | 0:65f1469d6bfb | 207 | } |
va009039 | 0:65f1469d6bfb | 208 | |
va009039 | 0:65f1469d6bfb | 209 | /* Output character */ |
va009039 | 0:65f1469d6bfb | 210 | retval = plat_putByte(ch); |
va009039 | 0:65f1469d6bfb | 211 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 212 | } |
va009039 | 0:65f1469d6bfb | 213 | } |
va009039 | 0:65f1469d6bfb | 214 | if (is_escaped) |
va009039 | 0:65f1469d6bfb | 215 | { |
va009039 | 0:65f1469d6bfb | 216 | retval = plat_putByte('\''); |
va009039 | 0:65f1469d6bfb | 217 | } |
va009039 | 0:65f1469d6bfb | 218 | |
va009039 | 0:65f1469d6bfb | 219 | return retval; |
va009039 | 0:65f1469d6bfb | 220 | } |
va009039 | 0:65f1469d6bfb | 221 | |
va009039 | 0:65f1469d6bfb | 222 | |
va009039 | 0:65f1469d6bfb | 223 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 224 | string_print(pPmObj_t pstr, uint8_t is_escaped) |
va009039 | 0:65f1469d6bfb | 225 | { |
va009039 | 0:65f1469d6bfb | 226 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 227 | |
va009039 | 0:65f1469d6bfb | 228 | C_ASSERT(pstr != C_NULL); |
va009039 | 0:65f1469d6bfb | 229 | |
va009039 | 0:65f1469d6bfb | 230 | /* Ensure string obj */ |
va009039 | 0:65f1469d6bfb | 231 | if (OBJ_GET_TYPE(pstr) != OBJ_TYPE_STR) |
va009039 | 0:65f1469d6bfb | 232 | { |
va009039 | 0:65f1469d6bfb | 233 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 234 | return retval; |
va009039 | 0:65f1469d6bfb | 235 | } |
va009039 | 0:65f1469d6bfb | 236 | |
va009039 | 0:65f1469d6bfb | 237 | retval = string_printFormattedBytes(&(((pPmString_t)pstr)->val[0]), |
va009039 | 0:65f1469d6bfb | 238 | is_escaped, |
va009039 | 0:65f1469d6bfb | 239 | ((pPmString_t)pstr)->length); |
va009039 | 0:65f1469d6bfb | 240 | |
va009039 | 0:65f1469d6bfb | 241 | return retval; |
va009039 | 0:65f1469d6bfb | 242 | } |
va009039 | 0:65f1469d6bfb | 243 | #endif /* HAVE_PRINT */ |
va009039 | 0:65f1469d6bfb | 244 | |
va009039 | 0:65f1469d6bfb | 245 | |
va009039 | 0:65f1469d6bfb | 246 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 247 | string_cacheInit(void) |
va009039 | 0:65f1469d6bfb | 248 | { |
va009039 | 0:65f1469d6bfb | 249 | pstrcache = C_NULL; |
va009039 | 0:65f1469d6bfb | 250 | |
va009039 | 0:65f1469d6bfb | 251 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 252 | } |
va009039 | 0:65f1469d6bfb | 253 | |
va009039 | 0:65f1469d6bfb | 254 | |
va009039 | 0:65f1469d6bfb | 255 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 256 | string_getCache(pPmString_t **r_ppstrcache) |
va009039 | 0:65f1469d6bfb | 257 | { |
va009039 | 0:65f1469d6bfb | 258 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 259 | *r_ppstrcache = &pstrcache; |
va009039 | 0:65f1469d6bfb | 260 | #else |
va009039 | 0:65f1469d6bfb | 261 | *r_ppstrcache = C_NULL; |
va009039 | 0:65f1469d6bfb | 262 | #endif |
va009039 | 0:65f1469d6bfb | 263 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 264 | } |
va009039 | 0:65f1469d6bfb | 265 | |
va009039 | 0:65f1469d6bfb | 266 | |
va009039 | 0:65f1469d6bfb | 267 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 268 | string_concat(pPmString_t pstr1, pPmString_t pstr2, pPmObj_t *r_pstring) |
va009039 | 0:65f1469d6bfb | 269 | { |
va009039 | 0:65f1469d6bfb | 270 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 271 | pPmString_t pstr = C_NULL; |
va009039 | 0:65f1469d6bfb | 272 | uint8_t *pdst = C_NULL; |
va009039 | 0:65f1469d6bfb | 273 | uint8_t const *psrc = C_NULL; |
va009039 | 0:65f1469d6bfb | 274 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 275 | pPmString_t pcacheentry = C_NULL; |
va009039 | 0:65f1469d6bfb | 276 | #endif /* USE_STRING_CACHE */ |
va009039 | 0:65f1469d6bfb | 277 | uint8_t *pchunk; |
va009039 | 0:65f1469d6bfb | 278 | uint16_t len; |
va009039 | 0:65f1469d6bfb | 279 | |
va009039 | 0:65f1469d6bfb | 280 | /* Create the String obj */ |
va009039 | 0:65f1469d6bfb | 281 | len = pstr1->length + pstr2->length; |
va009039 | 0:65f1469d6bfb | 282 | retval = heap_getChunk(sizeof(PmString_t) + len, &pchunk); |
va009039 | 0:65f1469d6bfb | 283 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 284 | pstr = (pPmString_t)pchunk; |
va009039 | 0:65f1469d6bfb | 285 | OBJ_SET_TYPE(pstr, OBJ_TYPE_STR); |
va009039 | 0:65f1469d6bfb | 286 | pstr->length = len; |
va009039 | 0:65f1469d6bfb | 287 | |
va009039 | 0:65f1469d6bfb | 288 | /* Concatenate C-strings into String obj and apply null terminator */ |
va009039 | 0:65f1469d6bfb | 289 | pdst = (uint8_t *)&(pstr->val); |
va009039 | 0:65f1469d6bfb | 290 | psrc = (uint8_t const *)&(pstr1->val); |
va009039 | 0:65f1469d6bfb | 291 | mem_copy(MEMSPACE_RAM, &pdst, &psrc, pstr1->length); |
va009039 | 0:65f1469d6bfb | 292 | psrc = (uint8_t const *)&(pstr2->val); |
va009039 | 0:65f1469d6bfb | 293 | mem_copy(MEMSPACE_RAM, &pdst, &psrc, pstr2->length); |
va009039 | 0:65f1469d6bfb | 294 | *pdst = '\0'; |
va009039 | 0:65f1469d6bfb | 295 | |
va009039 | 0:65f1469d6bfb | 296 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 297 | /* Check for twin string in cache */ |
va009039 | 0:65f1469d6bfb | 298 | for (pcacheentry = pstrcache; |
va009039 | 0:65f1469d6bfb | 299 | pcacheentry != C_NULL; pcacheentry = pcacheentry->next) |
va009039 | 0:65f1469d6bfb | 300 | { |
va009039 | 0:65f1469d6bfb | 301 | /* If string already exists */ |
va009039 | 0:65f1469d6bfb | 302 | if (string_compare(pcacheentry, pstr) == C_SAME) |
va009039 | 0:65f1469d6bfb | 303 | { |
va009039 | 0:65f1469d6bfb | 304 | /* Free the string */ |
va009039 | 0:65f1469d6bfb | 305 | retval = heap_freeChunk((pPmObj_t)pstr); |
va009039 | 0:65f1469d6bfb | 306 | |
va009039 | 0:65f1469d6bfb | 307 | /* Return ptr to old */ |
va009039 | 0:65f1469d6bfb | 308 | *r_pstring = (pPmObj_t)pcacheentry; |
va009039 | 0:65f1469d6bfb | 309 | return retval; |
va009039 | 0:65f1469d6bfb | 310 | } |
va009039 | 0:65f1469d6bfb | 311 | } |
va009039 | 0:65f1469d6bfb | 312 | |
va009039 | 0:65f1469d6bfb | 313 | /* Insert string obj into cache */ |
va009039 | 0:65f1469d6bfb | 314 | pstr->next = pstrcache; |
va009039 | 0:65f1469d6bfb | 315 | pstrcache = pstr; |
va009039 | 0:65f1469d6bfb | 316 | #endif /* USE_STRING_CACHE */ |
va009039 | 0:65f1469d6bfb | 317 | |
va009039 | 0:65f1469d6bfb | 318 | *r_pstring = (pPmObj_t)pstr; |
va009039 | 0:65f1469d6bfb | 319 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 320 | } |
va009039 | 0:65f1469d6bfb | 321 | |
va009039 | 0:65f1469d6bfb | 322 | |
va009039 | 0:65f1469d6bfb | 323 | #ifdef HAVE_STRING_FORMAT |
va009039 | 0:65f1469d6bfb | 324 | |
va009039 | 0:65f1469d6bfb | 325 | #define SIZEOF_FMTDBUF 42 |
va009039 | 0:65f1469d6bfb | 326 | #define SIZEOF_SMALLFMT 8 |
va009039 | 0:65f1469d6bfb | 327 | |
va009039 | 0:65f1469d6bfb | 328 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 329 | string_format(pPmString_t pstr, pPmObj_t parg, pPmObj_t *r_pstring) |
va009039 | 0:65f1469d6bfb | 330 | { |
va009039 | 0:65f1469d6bfb | 331 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 332 | uint16_t strsize = 0; |
va009039 | 0:65f1469d6bfb | 333 | uint16_t strindex; |
va009039 | 0:65f1469d6bfb | 334 | uint8_t *fmtcstr; |
va009039 | 0:65f1469d6bfb | 335 | uint8_t smallfmtcstr[SIZEOF_SMALLFMT]; |
va009039 | 0:65f1469d6bfb | 336 | uint8_t fmtdbuf[SIZEOF_FMTDBUF]; |
va009039 | 0:65f1469d6bfb | 337 | uint8_t i; |
va009039 | 0:65f1469d6bfb | 338 | uint8_t j; |
va009039 | 0:65f1469d6bfb | 339 | uint8_t argtupleindex = 0; |
va009039 | 0:65f1469d6bfb | 340 | pPmObj_t pobj; |
va009039 | 0:65f1469d6bfb | 341 | int fmtretval; |
va009039 | 0:65f1469d6bfb | 342 | uint8_t expectedargcount = 0; |
va009039 | 0:65f1469d6bfb | 343 | pPmString_t pnewstr; |
va009039 | 0:65f1469d6bfb | 344 | uint8_t *pchunk; |
va009039 | 0:65f1469d6bfb | 345 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 346 | pPmString_t pcacheentry = C_NULL; |
va009039 | 0:65f1469d6bfb | 347 | #endif /* USE_STRING_CACHE */ |
va009039 | 0:65f1469d6bfb | 348 | |
va009039 | 0:65f1469d6bfb | 349 | /* Get the first arg */ |
va009039 | 0:65f1469d6bfb | 350 | pobj = parg; |
va009039 | 0:65f1469d6bfb | 351 | |
va009039 | 0:65f1469d6bfb | 352 | /* Calculate the size of the resulting string */ |
va009039 | 0:65f1469d6bfb | 353 | fmtcstr = pstr->val; |
va009039 | 0:65f1469d6bfb | 354 | for (i = 0; i < pstr->length; i++) |
va009039 | 0:65f1469d6bfb | 355 | { |
va009039 | 0:65f1469d6bfb | 356 | /* Count non-format chars */ |
va009039 | 0:65f1469d6bfb | 357 | if (fmtcstr[i] != '%') { strsize++; continue; } |
va009039 | 0:65f1469d6bfb | 358 | |
va009039 | 0:65f1469d6bfb | 359 | /* If double percents, count one percent */ |
va009039 | 0:65f1469d6bfb | 360 | if (fmtcstr[++i] == '%') { strsize++; continue; } |
va009039 | 0:65f1469d6bfb | 361 | |
va009039 | 0:65f1469d6bfb | 362 | /* Get arg from the tuple */ |
va009039 | 0:65f1469d6bfb | 363 | if (OBJ_GET_TYPE(parg) == OBJ_TYPE_TUP) |
va009039 | 0:65f1469d6bfb | 364 | { |
va009039 | 0:65f1469d6bfb | 365 | pobj = ((pPmTuple_t)parg)->val[argtupleindex++]; |
va009039 | 0:65f1469d6bfb | 366 | } |
va009039 | 0:65f1469d6bfb | 367 | |
va009039 | 0:65f1469d6bfb | 368 | fmtretval = -1; |
va009039 | 0:65f1469d6bfb | 369 | |
va009039 | 0:65f1469d6bfb | 370 | /* Format one arg to get its length */ |
va009039 | 0:65f1469d6bfb | 371 | smallfmtcstr[0] = '%'; |
va009039 | 0:65f1469d6bfb | 372 | for(j = 1; (i < pstr->length) && (j < SIZEOF_SMALLFMT); i++) |
va009039 | 0:65f1469d6bfb | 373 | { |
va009039 | 0:65f1469d6bfb | 374 | smallfmtcstr[j] = fmtcstr[i]; |
va009039 | 0:65f1469d6bfb | 375 | j++; |
va009039 | 0:65f1469d6bfb | 376 | |
va009039 | 0:65f1469d6bfb | 377 | if ((fmtcstr[i] == 'd') |
va009039 | 0:65f1469d6bfb | 378 | || (fmtcstr[i] == 'x') |
va009039 | 0:65f1469d6bfb | 379 | || (fmtcstr[i] == 'X')) |
va009039 | 0:65f1469d6bfb | 380 | { |
va009039 | 0:65f1469d6bfb | 381 | if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 382 | { |
va009039 | 0:65f1469d6bfb | 383 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 384 | return retval; |
va009039 | 0:65f1469d6bfb | 385 | } |
va009039 | 0:65f1469d6bfb | 386 | smallfmtcstr[j] = '\0'; |
va009039 | 0:65f1469d6bfb | 387 | #ifdef HAVE_SNPRINTF_FORMAT |
va009039 | 0:65f1469d6bfb | 388 | fmtretval = snprintf((char *)fmtdbuf, SIZEOF_FMTDBUF, |
va009039 | 0:65f1469d6bfb | 389 | (char *)smallfmtcstr, ((pPmInt_t)pobj)->val); |
va009039 | 0:65f1469d6bfb | 390 | #else |
va009039 | 0:65f1469d6bfb | 391 | if (fmtcstr[i] == 'd') |
va009039 | 0:65f1469d6bfb | 392 | { |
va009039 | 0:65f1469d6bfb | 393 | retval = sli_ltoa10(((pPmInt_t)pobj)->val, |
va009039 | 0:65f1469d6bfb | 394 | fmtdbuf, |
va009039 | 0:65f1469d6bfb | 395 | sizeof(fmtdbuf)); |
va009039 | 0:65f1469d6bfb | 396 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 397 | } |
va009039 | 0:65f1469d6bfb | 398 | else |
va009039 | 0:65f1469d6bfb | 399 | { |
va009039 | 0:65f1469d6bfb | 400 | sli_ltoa16(((pPmInt_t)pobj)->val, |
va009039 | 0:65f1469d6bfb | 401 | fmtdbuf, |
va009039 | 0:65f1469d6bfb | 402 | sizeof(fmtdbuf), |
va009039 | 0:65f1469d6bfb | 403 | fmtcstr[i] == 'X'); |
va009039 | 0:65f1469d6bfb | 404 | } |
va009039 | 0:65f1469d6bfb | 405 | fmtretval = sli_strlen((char *)fmtdbuf); |
va009039 | 0:65f1469d6bfb | 406 | #endif /* HAVE_SNPRINTF_FORMAT */ |
va009039 | 0:65f1469d6bfb | 407 | break; |
va009039 | 0:65f1469d6bfb | 408 | } |
va009039 | 0:65f1469d6bfb | 409 | |
va009039 | 0:65f1469d6bfb | 410 | #ifdef HAVE_FLOAT |
va009039 | 0:65f1469d6bfb | 411 | else if ((fmtcstr[i] == 'f') || (fmtcstr[i] == 'F')) |
va009039 | 0:65f1469d6bfb | 412 | { |
va009039 | 0:65f1469d6bfb | 413 | if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_FLT) |
va009039 | 0:65f1469d6bfb | 414 | { |
va009039 | 0:65f1469d6bfb | 415 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 416 | return retval; |
va009039 | 0:65f1469d6bfb | 417 | } |
va009039 | 0:65f1469d6bfb | 418 | #ifdef HAVE_SNPRINTF_FORMAT |
va009039 | 0:65f1469d6bfb | 419 | smallfmtcstr[j] = '\0'; |
va009039 | 0:65f1469d6bfb | 420 | fmtretval = snprintf((char *)fmtdbuf, SIZEOF_FMTDBUF, |
va009039 | 0:65f1469d6bfb | 421 | (char *)smallfmtcstr, ((pPmFloat_t)pobj)->val); |
va009039 | 0:65f1469d6bfb | 422 | #else |
va009039 | 0:65f1469d6bfb | 423 | sli_ftoa(((pPmFloat_t)pobj)->val, fmtdbuf, SIZEOF_FMTDBUF); |
va009039 | 0:65f1469d6bfb | 424 | fmtretval = sli_strlen((char *)fmtdbuf); |
va009039 | 0:65f1469d6bfb | 425 | #endif /* HAVE_SNPRINTF_FORMAT */ |
va009039 | 0:65f1469d6bfb | 426 | break; |
va009039 | 0:65f1469d6bfb | 427 | } |
va009039 | 0:65f1469d6bfb | 428 | #endif /* HAVE_FLOAT */ |
va009039 | 0:65f1469d6bfb | 429 | |
va009039 | 0:65f1469d6bfb | 430 | else if (fmtcstr[i] == 's') |
va009039 | 0:65f1469d6bfb | 431 | { |
va009039 | 0:65f1469d6bfb | 432 | if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_STR) |
va009039 | 0:65f1469d6bfb | 433 | { |
va009039 | 0:65f1469d6bfb | 434 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 435 | return retval; |
va009039 | 0:65f1469d6bfb | 436 | } |
va009039 | 0:65f1469d6bfb | 437 | |
va009039 | 0:65f1469d6bfb | 438 | /* Skip using snprintf(), just use length of string arg */ |
va009039 | 0:65f1469d6bfb | 439 | fmtretval = ((pPmString_t)pobj)->length; |
va009039 | 0:65f1469d6bfb | 440 | break; |
va009039 | 0:65f1469d6bfb | 441 | } |
va009039 | 0:65f1469d6bfb | 442 | } |
va009039 | 0:65f1469d6bfb | 443 | |
va009039 | 0:65f1469d6bfb | 444 | /* Raise ValueError if the format string was bad */ |
va009039 | 0:65f1469d6bfb | 445 | if (fmtretval < 0) |
va009039 | 0:65f1469d6bfb | 446 | { |
va009039 | 0:65f1469d6bfb | 447 | PM_RAISE(retval, PM_RET_EX_VAL); |
va009039 | 0:65f1469d6bfb | 448 | return retval; |
va009039 | 0:65f1469d6bfb | 449 | } |
va009039 | 0:65f1469d6bfb | 450 | |
va009039 | 0:65f1469d6bfb | 451 | expectedargcount++; |
va009039 | 0:65f1469d6bfb | 452 | strsize += fmtretval; |
va009039 | 0:65f1469d6bfb | 453 | } |
va009039 | 0:65f1469d6bfb | 454 | |
va009039 | 0:65f1469d6bfb | 455 | /* TypeError wrong number args */ |
va009039 | 0:65f1469d6bfb | 456 | if (((OBJ_GET_TYPE(parg) != OBJ_TYPE_TUP) && (expectedargcount != 1)) |
va009039 | 0:65f1469d6bfb | 457 | || ((OBJ_GET_TYPE(parg) == OBJ_TYPE_TUP) |
va009039 | 0:65f1469d6bfb | 458 | && (expectedargcount != ((pPmTuple_t)parg)->length))) |
va009039 | 0:65f1469d6bfb | 459 | { |
va009039 | 0:65f1469d6bfb | 460 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 461 | return retval; |
va009039 | 0:65f1469d6bfb | 462 | } |
va009039 | 0:65f1469d6bfb | 463 | |
va009039 | 0:65f1469d6bfb | 464 | /* Allocate and initialize String obj */ |
va009039 | 0:65f1469d6bfb | 465 | retval = heap_getChunk(sizeof(PmString_t) + strsize, &pchunk); |
va009039 | 0:65f1469d6bfb | 466 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 467 | pnewstr = (pPmString_t)pchunk; |
va009039 | 0:65f1469d6bfb | 468 | OBJ_SET_TYPE(pnewstr, OBJ_TYPE_STR); |
va009039 | 0:65f1469d6bfb | 469 | pnewstr->length = strsize; |
va009039 | 0:65f1469d6bfb | 470 | |
va009039 | 0:65f1469d6bfb | 471 | /* Fill contents of String obj */ |
va009039 | 0:65f1469d6bfb | 472 | strindex = 0; |
va009039 | 0:65f1469d6bfb | 473 | argtupleindex = 0; |
va009039 | 0:65f1469d6bfb | 474 | pobj = parg; |
va009039 | 0:65f1469d6bfb | 475 | |
va009039 | 0:65f1469d6bfb | 476 | for (i = 0; i < pstr->length; i++) |
va009039 | 0:65f1469d6bfb | 477 | { |
va009039 | 0:65f1469d6bfb | 478 | /* Copy non-format chars */ |
va009039 | 0:65f1469d6bfb | 479 | if (fmtcstr[i] != '%') |
va009039 | 0:65f1469d6bfb | 480 | { |
va009039 | 0:65f1469d6bfb | 481 | pnewstr->val[strindex++] = fmtcstr[i]; |
va009039 | 0:65f1469d6bfb | 482 | continue; |
va009039 | 0:65f1469d6bfb | 483 | } |
va009039 | 0:65f1469d6bfb | 484 | |
va009039 | 0:65f1469d6bfb | 485 | /* If double percents, copy one percent */ |
va009039 | 0:65f1469d6bfb | 486 | if (fmtcstr[++i] == '%') |
va009039 | 0:65f1469d6bfb | 487 | { |
va009039 | 0:65f1469d6bfb | 488 | pnewstr->val[strindex++] = '%'; |
va009039 | 0:65f1469d6bfb | 489 | continue; |
va009039 | 0:65f1469d6bfb | 490 | } |
va009039 | 0:65f1469d6bfb | 491 | |
va009039 | 0:65f1469d6bfb | 492 | /* Get arg from the tuple */ |
va009039 | 0:65f1469d6bfb | 493 | if (OBJ_GET_TYPE(parg) == OBJ_TYPE_TUP) |
va009039 | 0:65f1469d6bfb | 494 | { |
va009039 | 0:65f1469d6bfb | 495 | pobj = ((pPmTuple_t)parg)->val[argtupleindex++]; |
va009039 | 0:65f1469d6bfb | 496 | } |
va009039 | 0:65f1469d6bfb | 497 | |
va009039 | 0:65f1469d6bfb | 498 | fmtretval = -1; |
va009039 | 0:65f1469d6bfb | 499 | |
va009039 | 0:65f1469d6bfb | 500 | /* Format one arg to get its length */ |
va009039 | 0:65f1469d6bfb | 501 | smallfmtcstr[0] = '%'; |
va009039 | 0:65f1469d6bfb | 502 | for(j = 1; (i < pstr->length) && (j < SIZEOF_SMALLFMT); i++) |
va009039 | 0:65f1469d6bfb | 503 | { |
va009039 | 0:65f1469d6bfb | 504 | smallfmtcstr[j] = fmtcstr[i]; |
va009039 | 0:65f1469d6bfb | 505 | j++; |
va009039 | 0:65f1469d6bfb | 506 | |
va009039 | 0:65f1469d6bfb | 507 | if ((fmtcstr[i] == 'd') |
va009039 | 0:65f1469d6bfb | 508 | || (fmtcstr[i] == 'x') |
va009039 | 0:65f1469d6bfb | 509 | || (fmtcstr[i] == 'X')) |
va009039 | 0:65f1469d6bfb | 510 | { |
va009039 | 0:65f1469d6bfb | 511 | smallfmtcstr[j] = '\0'; |
va009039 | 0:65f1469d6bfb | 512 | #ifdef HAVE_SNPRINTF_FORMAT |
va009039 | 0:65f1469d6bfb | 513 | fmtretval = snprintf((char *)fmtdbuf, SIZEOF_FMTDBUF, |
va009039 | 0:65f1469d6bfb | 514 | (char *)smallfmtcstr, ((pPmInt_t)pobj)->val); |
va009039 | 0:65f1469d6bfb | 515 | #else |
va009039 | 0:65f1469d6bfb | 516 | if (fmtcstr[i] == 'd') |
va009039 | 0:65f1469d6bfb | 517 | { |
va009039 | 0:65f1469d6bfb | 518 | retval = sli_ltoa10(((pPmInt_t)pobj)->val, |
va009039 | 0:65f1469d6bfb | 519 | fmtdbuf, |
va009039 | 0:65f1469d6bfb | 520 | sizeof(fmtdbuf)); |
va009039 | 0:65f1469d6bfb | 521 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 522 | } |
va009039 | 0:65f1469d6bfb | 523 | else |
va009039 | 0:65f1469d6bfb | 524 | { |
va009039 | 0:65f1469d6bfb | 525 | sli_ltoa16(((pPmInt_t)pobj)->val, |
va009039 | 0:65f1469d6bfb | 526 | fmtdbuf, |
va009039 | 0:65f1469d6bfb | 527 | sizeof(fmtdbuf), |
va009039 | 0:65f1469d6bfb | 528 | fmtcstr[i] == 'X'); |
va009039 | 0:65f1469d6bfb | 529 | } |
va009039 | 0:65f1469d6bfb | 530 | fmtretval = sli_strlen((char *)fmtdbuf); |
va009039 | 0:65f1469d6bfb | 531 | #endif /* HAVE_SNPRINTF_FORMAT */ |
va009039 | 0:65f1469d6bfb | 532 | break; |
va009039 | 0:65f1469d6bfb | 533 | } |
va009039 | 0:65f1469d6bfb | 534 | |
va009039 | 0:65f1469d6bfb | 535 | #ifdef HAVE_FLOAT |
va009039 | 0:65f1469d6bfb | 536 | else if ((fmtcstr[i] == 'f') || (fmtcstr[i] == 'F')) |
va009039 | 0:65f1469d6bfb | 537 | { |
va009039 | 0:65f1469d6bfb | 538 | #ifdef HAVE_SNPRINTF_FORMAT |
va009039 | 0:65f1469d6bfb | 539 | smallfmtcstr[j] = '\0'; |
va009039 | 0:65f1469d6bfb | 540 | fmtretval = snprintf((char *)fmtdbuf, SIZEOF_FMTDBUF, |
va009039 | 0:65f1469d6bfb | 541 | (char *)smallfmtcstr, ((pPmFloat_t)pobj)->val); |
va009039 | 0:65f1469d6bfb | 542 | #else |
va009039 | 0:65f1469d6bfb | 543 | sli_ftoa(((pPmFloat_t)pobj)->val, fmtdbuf, SIZEOF_FMTDBUF); |
va009039 | 0:65f1469d6bfb | 544 | fmtretval = sli_strlen((char *)fmtdbuf); |
va009039 | 0:65f1469d6bfb | 545 | #endif /* HAVE_SNPRINTF_FORMAT */ |
va009039 | 0:65f1469d6bfb | 546 | break; |
va009039 | 0:65f1469d6bfb | 547 | } |
va009039 | 0:65f1469d6bfb | 548 | #endif /* HAVE_FLOAT */ |
va009039 | 0:65f1469d6bfb | 549 | |
va009039 | 0:65f1469d6bfb | 550 | else if (fmtcstr[i] == 's') |
va009039 | 0:65f1469d6bfb | 551 | { |
va009039 | 0:65f1469d6bfb | 552 | #ifdef HAVE_SNPRINTF_FORMAT |
va009039 | 0:65f1469d6bfb | 553 | smallfmtcstr[j] = '\0'; |
va009039 | 0:65f1469d6bfb | 554 | fmtretval = snprintf((char *)fmtdbuf, SIZEOF_FMTDBUF, |
va009039 | 0:65f1469d6bfb | 555 | (char *)smallfmtcstr, ((pPmString_t)pobj)->val); |
va009039 | 0:65f1469d6bfb | 556 | #else |
va009039 | 0:65f1469d6bfb | 557 | sli_memcpy(fmtdbuf, ((pPmString_t)pobj)->val, |
va009039 | 0:65f1469d6bfb | 558 | ((pPmString_t)pobj)->length); |
va009039 | 0:65f1469d6bfb | 559 | fmtretval = ((pPmString_t)pobj)->length; |
va009039 | 0:65f1469d6bfb | 560 | #endif /* HAVE_SNPRINTF_FORMAT */ |
va009039 | 0:65f1469d6bfb | 561 | break; |
va009039 | 0:65f1469d6bfb | 562 | } |
va009039 | 0:65f1469d6bfb | 563 | } |
va009039 | 0:65f1469d6bfb | 564 | |
va009039 | 0:65f1469d6bfb | 565 | /* Copy formatted C string into new string object */ |
va009039 | 0:65f1469d6bfb | 566 | for (j = 0; j < fmtretval; j++) |
va009039 | 0:65f1469d6bfb | 567 | { |
va009039 | 0:65f1469d6bfb | 568 | pnewstr->val[strindex++] = fmtdbuf[j]; |
va009039 | 0:65f1469d6bfb | 569 | } |
va009039 | 0:65f1469d6bfb | 570 | } |
va009039 | 0:65f1469d6bfb | 571 | pnewstr->val[strindex] = '\0'; |
va009039 | 0:65f1469d6bfb | 572 | |
va009039 | 0:65f1469d6bfb | 573 | #if USE_STRING_CACHE |
va009039 | 0:65f1469d6bfb | 574 | /* Check for twin string in cache */ |
va009039 | 0:65f1469d6bfb | 575 | for (pcacheentry = pstrcache; |
va009039 | 0:65f1469d6bfb | 576 | pcacheentry != C_NULL; pcacheentry = pcacheentry->next) |
va009039 | 0:65f1469d6bfb | 577 | { |
va009039 | 0:65f1469d6bfb | 578 | /* If string already exists */ |
va009039 | 0:65f1469d6bfb | 579 | if (string_compare(pcacheentry, pnewstr) == C_SAME) |
va009039 | 0:65f1469d6bfb | 580 | { |
va009039 | 0:65f1469d6bfb | 581 | /* Free the string */ |
va009039 | 0:65f1469d6bfb | 582 | retval = heap_freeChunk((pPmObj_t)pnewstr); |
va009039 | 0:65f1469d6bfb | 583 | |
va009039 | 0:65f1469d6bfb | 584 | /* Return ptr to old */ |
va009039 | 0:65f1469d6bfb | 585 | *r_pstring = (pPmObj_t)pcacheentry; |
va009039 | 0:65f1469d6bfb | 586 | return retval; |
va009039 | 0:65f1469d6bfb | 587 | } |
va009039 | 0:65f1469d6bfb | 588 | } |
va009039 | 0:65f1469d6bfb | 589 | |
va009039 | 0:65f1469d6bfb | 590 | /* Insert string obj into cache */ |
va009039 | 0:65f1469d6bfb | 591 | pnewstr->next = pstrcache; |
va009039 | 0:65f1469d6bfb | 592 | pstrcache = pnewstr; |
va009039 | 0:65f1469d6bfb | 593 | |
va009039 | 0:65f1469d6bfb | 594 | #endif /* USE_STRING_CACHE */ |
va009039 | 0:65f1469d6bfb | 595 | |
va009039 | 0:65f1469d6bfb | 596 | *r_pstring = (pPmObj_t)pnewstr; |
va009039 | 0:65f1469d6bfb | 597 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 598 | } |
va009039 | 0:65f1469d6bfb | 599 | #endif /* HAVE_STRING_FORMAT */ |