Changeset efdfebc in mainline for uspace/lib/c/generic/str.c


Ignore:
Timestamp:
2012-11-06T21:03:44Z (11 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
338810f
Parents:
de73242 (diff), 94795812 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/str.c

    rde73242 refdfebc  
    136136}
    137137
     138/** Decode a single character from a string to the left.
     139 *
     140 * Decode a single character from a string of size @a size. Decoding starts
     141 * at @a offset and this offset is moved to the beginning of the previous
     142 * character. In case of decoding error, offset generally decreases at least
     143 * by one. However, offset is never moved before 0.
     144 *
     145 * @param str    String (not necessarily NULL-terminated).
     146 * @param offset Byte offset in string where to start decoding.
     147 * @param size   Size of the string (in bytes).
     148 *
     149 * @return Value of decoded character, U_SPECIAL on decoding error or
     150 *         NULL if attempt to decode beyond @a start of str.
     151 *
     152 */
     153wchar_t str_decode_reverse(const char *str, size_t *offset, size_t size)
     154{
     155        if (*offset == 0)
     156                return 0;
     157       
     158        size_t processed = 0;
     159        /* Continue while continuation bytes found */
     160        while (*offset > 0 && processed < 4) {
     161                uint8_t b = (uint8_t) str[--(*offset)];
     162               
     163                if (processed == 0 && (b & 0x80) == 0) {
     164                        /* 0xxxxxxx (Plain ASCII) */
     165                        return b & 0x7f;
     166                }
     167                else if ((b & 0xe0) == 0xc0 || (b & 0xf0) == 0xe0 ||
     168                    (b & 0xf8) == 0xf0) {
     169                        /* Start byte */
     170                        size_t start_offset = *offset;
     171                        return str_decode(str, &start_offset, size);
     172                }
     173                else if ((b & 0xc0) != 0x80) {
     174                        /* Not a continuation byte */
     175                        return U_SPECIAL;
     176                }
     177                processed++;
     178        }
     179        /* Too many continuation bytes */
     180        return U_SPECIAL;
     181}
     182
    138183/** Encode a single character to string representation.
    139184 *
     
    399444}
    400445
     446/** Get character display width on a character cell display.
     447 *
     448 * @param ch    Character
     449 * @return      Width of character in cells.
     450 */
     451size_t chr_width(wchar_t ch)
     452{
     453        return 1;
     454}
     455
     456/** Get string display width on a character cell display.
     457 *
     458 * @param str   String
     459 * @return      Width of string in cells.
     460 */
     461size_t str_width(const char *str)
     462{
     463        size_t width = 0;
     464        size_t offset = 0;
     465        wchar_t ch;
     466       
     467        while ((ch = str_decode(str, &offset, STR_NO_LIMIT)) != 0)
     468                width += chr_width(ch);
     469       
     470        return width;
     471}
     472
    401473/** Check whether character is plain ASCII.
    402474 *
     
    428500 *
    429501 * Do a char-by-char comparison of two NULL-terminated strings.
    430  * The strings are considered equal iff they consist of the same
    431  * characters on the minimum of their lengths.
     502 * The strings are considered equal iff their length is equal
     503 * and both strings consist of the same sequence of characters.
     504 *
     505 * A string S1 is less than another string S2 if it has a character with
     506 * lower value at the first character position where the strings differ.
     507 * If the strings differ in length, the shorter one is treated as if
     508 * padded by characters with a value of zero.
    432509 *
    433510 * @param s1 First string to compare.
    434511 * @param s2 Second string to compare.
    435512 *
    436  * @return 0 if the strings are equal, -1 if first is smaller,
    437  *         1 if second smaller.
     513 * @return 0 if the strings are equal, -1 if the first is less than the second,
     514 *         1 if the second is less than the first.
    438515 *
    439516 */
     
    466543 *
    467544 * Do a char-by-char comparison of two NULL-terminated strings.
    468  * The strings are considered equal iff they consist of the same
    469  * characters on the minimum of their lengths and the length limit.
     545 * The strings are considered equal iff
     546 * min(str_length(s1), max_len) == min(str_length(s2), max_len)
     547 * and both strings consist of the same sequence of characters,
     548 * up to max_len characters.
     549 *
     550 * A string S1 is less than another string S2 if it has a character with
     551 * lower value at the first character position where the strings differ.
     552 * If the strings differ in length, the shorter one is treated as if
     553 * padded by characters with a value of zero. Only the first max_len
     554 * characters are considered.
    470555 *
    471556 * @param s1      First string to compare.
     
    473558 * @param max_len Maximum number of characters to consider.
    474559 *
    475  * @return 0 if the strings are equal, -1 if first is smaller,
    476  *         1 if second smaller.
     560 * @return 0 if the strings are equal, -1 if the first is less than the second,
     561 *         1 if the second is less than the first.
    477562 *
    478563 */
     
    508593        return 0;
    509594
     595}
     596
     597/** Test whether p is a prefix of s.
     598 *
     599 * Do a char-by-char comparison of two NULL-terminated strings
     600 * and determine if p is a prefix of s.
     601 *
     602 * @param s The string in which to look
     603 * @param p The string to check if it is a prefix of s
     604 *
     605 * @return true iff p is prefix of s else false
     606 *
     607 */
     608bool str_test_prefix(const char *s, const char *p)
     609{
     610        wchar_t c1 = 0;
     611        wchar_t c2 = 0;
     612       
     613        size_t off1 = 0;
     614        size_t off2 = 0;
     615
     616        while (true) {
     617                c1 = str_decode(s, &off1, STR_NO_LIMIT);
     618                c2 = str_decode(p, &off2, STR_NO_LIMIT);
     619               
     620                if (c2 == 0)
     621                        return true;
     622
     623                if (c1 != c2)
     624                        return false;
     625               
     626                if (c1 == 0)
     627                        break;
     628        }
     629
     630        return false;
    510631}
    511632
     
    10851206                c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 :
    10861207                    (c <= '9' ? c - '0' : 0xff)));
    1087                 if (c > base) {
     1208                if (c >= base) {
    10881209                        break;
    10891210                }
Note: See TracChangeset for help on using the changeset viewer.