python-on-a-chip online compiler

Dependencies:   mbed TSI

/media/uploads/va009039/p14p-f446re.png

more info: python-on-a-chip

Committer:
va009039
Date:
Thu Apr 14 22:32:57 2016 +0000
Revision:
15:94ca5c8003e5
Parent:
0:65f1469d6bfb
update Nucleo-F401RE.

Who changed what in which revision?

UserRevisionLine numberNew 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 */