string.py

Go to the documentation of this file.
00001 # This file is Copyright 2009, 2010 Dean Hall.
00002 #
00003 # This file is part of the Python-on-a-Chip program.
00004 # Python-on-a-Chip is free software: you can redistribute it and/or modify
00005 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
00006 #
00007 # Python-on-a-Chip is distributed in the hope that it will be useful,
00008 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00009 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00010 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
00011 # is seen in the file COPYING in this directory.
00012 
00013 ## @file
00014 
00015 ## @package string
00016 #  @brief Provides PyMite's string module.
00017 #
00018 
00019 
00020 """__NATIVE__
00021 #include <stdlib.h>
00022 #include <string.h>
00023 """
00024 
00025 
00026 digits = "0123456789"
00027 hexdigits = "0123456789abcdefABCDEF"
00028 letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
00029 
00030 
00031 #
00032 # Returns the integer represented by the string a [in base b].
00033 # Optional int arg, b, may be 0 or 2 through 36; otherwise it is a ValueError.
00034 #
00035 def atoi(a, b):
00036     """__NATIVE__
00037     pPmObj_t pa;
00038     pPmObj_t pb;
00039     char const *pc;
00040     char *pend;
00041     long i;
00042     int8_t base;
00043     pPmObj_t pi;
00044     PmReturn_t retval = PM_RET_OK;
00045 
00046     /* Raise TypeError if it's not a string or wrong number of args, */
00047     pa = NATIVE_GET_LOCAL(0);
00048     if ((OBJ_GET_TYPE(pa) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() < 1)
00049         || (NATIVE_GET_NUM_ARGS() > 2))
00050     {
00051         PM_RAISE(retval, PM_RET_EX_TYPE);
00052         return retval;
00053     }
00054 
00055     /* Get the base, if it exists; otherwise assume 10 */
00056     base = 10;
00057     if (NATIVE_GET_NUM_ARGS() == 2)
00058     {
00059         pb = NATIVE_GET_LOCAL(1);
00060 
00061         /* Raise a TypeError if 2nd arg is not an int */
00062         if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT)
00063         {
00064             PM_RAISE(retval, PM_RET_EX_TYPE);
00065             return retval;
00066         }
00067 
00068         base = ((pPmInt_t)pb)->val;
00069 
00070         /* Raise ValueError if base is out of range */
00071         if ((base < 0) || (base == 1) || (base > 36))
00072         {
00073             PM_RAISE(retval, PM_RET_EX_VAL);
00074             return retval;
00075         }
00076     }
00077 
00078     /* Perform conversion */
00079     pend = C_NULL;
00080     pc = (char const *)&(((pPmString_t)pa)->val);
00081     i = strtol(pc, &pend, base);
00082 
00083     /* Raise ValueError if there was a conversion error */
00084     if (*pend != C_NULL)
00085     {
00086         PM_RAISE(retval, PM_RET_EX_VAL);
00087         return retval;
00088     }
00089 
00090     /* Create an int object to hold the result of the conversion */
00091     retval = int_new(i, &pi);
00092 
00093     NATIVE_SET_TOS(pi);
00094 
00095     return retval;
00096     """
00097     pass
00098 
00099 
00100 #
00101 # Returns the number of occurrences of substring s2 in string s1.
00102 # WARNING: Does not match Python's behavior if s1 contains a null character.
00103 #
00104 def count(s1, s2):
00105     """__NATIVE__
00106     pPmObj_t ps1;
00107     pPmObj_t ps2;
00108     uint8_t *pc1;
00109     uint8_t *pc2;
00110     uint8_t *pscan;
00111     uint8_t *pmatch;
00112     uint8_t pc2c0;
00113     uint16_t pc1len;
00114     uint16_t pc2len;
00115     uint16_t n;
00116     uint16_t remaining;
00117     uint16_t cmp;
00118     pPmObj_t pn;
00119     PmReturn_t retval = PM_RET_OK;
00120 
00121     /* Raise TypeError if it's not a string or wrong number of args, */
00122     ps1 = NATIVE_GET_LOCAL(0);
00123     ps2 = NATIVE_GET_LOCAL(1);
00124     if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
00125         || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
00126     {
00127         PM_RAISE(retval, PM_RET_EX_TYPE);
00128         return retval;
00129     }
00130 
00131     pc1 = ((pPmString_t)ps1)->val;
00132     pc2 = ((pPmString_t)ps2)->val;
00133     pc1len = ((pPmString_t)ps1)->length;
00134     pc2len = ((pPmString_t)ps2)->length;
00135     n = 0;
00136 
00137     /* Handle some quick special cases (order of if-clauses is important) */
00138     if (pc2len == 0)
00139     {
00140         n = pc1len + 1;
00141     }
00142     else if (pc1len == 0)
00143     {
00144         n = 0;
00145     }
00146 
00147     /* Count the number of matches */
00148     else
00149     {
00150         n = 0;
00151         remaining = pc1len;
00152         pscan = pc1;
00153         pc2c0 = pc2[0];
00154         while (pscan <= (pc1 + (pc1len - pc2len)))
00155         {
00156             /* Find the next possible start */
00157             pmatch = (uint8_t *)memchr(pscan, pc2c0, remaining);
00158             if (pmatch == C_NULL) break;
00159             remaining -= (pmatch - pscan);
00160             pscan = pmatch;
00161 
00162             /* If it matches, increase the count, else try the next char */
00163             cmp = memcmp(pscan, pc2, pc2len);
00164             if (cmp == 0)
00165             {
00166                 n++;
00167                 pscan += pc2len;
00168                 remaining -= pc2len;
00169             }
00170             else
00171             {
00172                 pscan++;
00173                 remaining--;
00174             }
00175         }
00176     }
00177 
00178     retval = int_new(n, &pn);
00179 
00180     NATIVE_SET_TOS(pn);
00181 
00182     return retval;
00183     """
00184     pass
00185 
00186 
00187 #
00188 # Returns the lowest index in s1 where substring s2 is found or -1 on failure.
00189 # WARNING: Does not accept optional start,end arguments.
00190 #
00191 def find(s1, s2):
00192     """__NATIVE__
00193     pPmObj_t ps1;
00194     pPmObj_t ps2;
00195     uint8_t *pc1;
00196     uint8_t *pc2;
00197     uint8_t *pmatch;
00198     uint8_t pc1len;
00199     uint8_t pc2len;
00200     int32_t n;
00201     pPmObj_t pn;
00202     PmReturn_t retval = PM_RET_OK;
00203 
00204     /* Raise TypeError if it's not a string or wrong number of args, */
00205     ps1 = NATIVE_GET_LOCAL(0);
00206     ps2 = NATIVE_GET_LOCAL(1);
00207     if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
00208         || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
00209     {
00210         PM_RAISE(retval, PM_RET_EX_TYPE);
00211         return retval;
00212     }
00213 
00214     pc1 = ((pPmString_t)ps1)->val;
00215     pc2 = ((pPmString_t)ps2)->val;
00216     pc1len = ((pPmString_t)ps1)->length;
00217     pc2len = ((pPmString_t)ps2)->length;
00218     n = -1;
00219 
00220     /* Handle a quick special case */
00221     if (pc2len == 0)
00222     {
00223         n = 0;
00224     }
00225 
00226     /* Try to find the index of the substring */
00227     else
00228     {
00229         /* Find the next possible start */
00230         pmatch = (uint8_t *)memchr(pc1, pc2[0], pc1len);
00231         if (pmatch != C_NULL)
00232         {
00233             /* If it matches, calculate the index */
00234             if (memcmp(pmatch, pc2, pc2len) == 0)
00235             {
00236                 n = pmatch - pc1;
00237             }
00238         }
00239     }
00240 
00241     retval = int_new(n, &pn);
00242 
00243     NATIVE_SET_TOS(pn);
00244 
00245     return retval;
00246     """
00247     pass
00248 
00249 
00250 def join(s, sep=' '):
00251     len_s = len(s)
00252     if len_s == 0:
00253         return ''
00254     rs = s[0]
00255     i = 1
00256     while i < len_s:
00257         rs = rs + sep + s[i]
00258         i += 1
00259     return rs
00260 
00261 
00262 # :mode=c:

Generated on Mon Oct 18 07:40:46 2010 for Python-on-a-chip by  doxygen 1.5.9