1 # This file is Copyright 2009, 2010 Dean Hall.
3 # This file is part of the Python-on-a-Chip program.
4 # Python-on-a-Chip is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
7 # Python-on-a-Chip is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
11 # is seen in the file COPYING in this directory.
16 # @brief Provides PyMite's string module.
27 hexdigits
= "0123456789abcdefABCDEF"
28 letters
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
32 # Returns the integer represented by the string a [in base b].
33 # Optional int arg, b, may be 0 or 2 through 36; otherwise it is a ValueError.
44 PmReturn_t retval = PM_RET_OK;
46 /* Raise TypeError if it's not a string or wrong number of args, */
47 pa = NATIVE_GET_LOCAL(0);
48 if ((OBJ_GET_TYPE(pa) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() < 1)
49 || (NATIVE_GET_NUM_ARGS() > 2))
51 PM_RAISE(retval, PM_RET_EX_TYPE);
55 /* Get the base, if it exists; otherwise assume 10 */
57 if (NATIVE_GET_NUM_ARGS() == 2)
59 pb = NATIVE_GET_LOCAL(1);
61 /* Raise a TypeError if 2nd arg is not an int */
62 if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT)
64 PM_RAISE(retval, PM_RET_EX_TYPE);
68 base = ((pPmInt_t)pb)->val;
70 /* Raise ValueError if base is out of range */
71 if ((base < 0) || (base == 1) || (base > 36))
73 PM_RAISE(retval, PM_RET_EX_VAL);
78 /* Perform conversion */
80 pc = (char const *)&(((pPmString_t)pa)->val);
81 i = strtol(pc, &pend, base);
83 /* Raise ValueError if there was a conversion error */
86 PM_RAISE(retval, PM_RET_EX_VAL);
90 /* Create an int object to hold the result of the conversion */
91 retval = int_new(i, &pi);
101 # Returns the number of occurrences of substring s2 in string s1.
102 # WARNING: Does not match Python's behavior if s1 contains a null character.
119 PmReturn_t retval = PM_RET_OK;
121 /* Raise TypeError if it's not a string or wrong number of args, */
122 ps1 = NATIVE_GET_LOCAL(0);
123 ps2 = NATIVE_GET_LOCAL(1);
124 if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
125 || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
127 PM_RAISE(retval, PM_RET_EX_TYPE);
131 pc1 = ((pPmString_t)ps1)->val;
132 pc2 = ((pPmString_t)ps2)->val;
133 pc1len = ((pPmString_t)ps1)->length;
134 pc2len = ((pPmString_t)ps2)->length;
137 /* Handle some quick special cases (order of if-clauses is important) */
142 else if (pc1len == 0)
147 /* Count the number of matches */
154 while (pscan <= (pc1 + (pc1len - pc2len)))
156 /* Find the next possible start */
157 pmatch = (uint8_t *)memchr(pscan, pc2c0, remaining);
158 if (pmatch == C_NULL) break;
159 remaining -= (pmatch - pscan);
162 /* If it matches, increase the count, else try the next char */
163 cmp = memcmp(pscan, pc2, pc2len);
178 retval = int_new(n, &pn);
188 # Returns the lowest index in s1 where substring s2 is found or -1 on failure.
189 # WARNING: Does not accept optional start,end arguments.
202 PmReturn_t retval = PM_RET_OK;
204 /* Raise TypeError if it's not a string or wrong number of args, */
205 ps1 = NATIVE_GET_LOCAL(0);
206 ps2 = NATIVE_GET_LOCAL(1);
207 if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
208 || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
210 PM_RAISE(retval, PM_RET_EX_TYPE);
214 pc1 = ((pPmString_t)ps1)->val;
215 pc2 = ((pPmString_t)ps2)->val;
216 pc1len = ((pPmString_t)ps1)->length;
217 pc2len = ((pPmString_t)ps2)->length;
220 /* Handle a quick special case */
226 /* Try to find the index of the substring */
229 /* Find the next possible start */
230 pmatch = (uint8_t *)memchr(pc1, pc2[0], pc1len);
231 if (pmatch != C_NULL)
233 /* If it matches, calculate the index */
234 if (memcmp(pmatch, pc2, pc2len) == 0)
241 retval = int_new(n, &pn);
250 def join(s
, sep
=' '):