Changeset f2b8cdc in mainline for uspace/lib/libc/generic/string.c


Ignore:
Timestamp:
2009-04-04T22:04:28Z (15 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b27eb71
Parents:
4527fb5
Message:

Copy printf with Unicode support to userspace.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/string.c

    r4527fb5 rf2b8cdc  
    4040#include <malloc.h>
    4141#include <errno.h>
     42#include <align.h>
    4243#include <string.h>
    4344
     
    193194}
    194195
     196/** Get size of string.
     197 *
     198 * Get the number of bytes which are used by the string @a str (excluding the
     199 * NULL-terminator).
     200 *
     201 * @param str String to consider.
     202 *
     203 * @return Number of bytes used by the string
     204 *
     205 */
     206size_t str_size(const char *str)
     207{
     208        size_t size = 0;
     209       
     210        while (*str++ != 0)
     211                size++;
     212       
     213        return size;
     214}
     215
     216/** Get size of wide string.
     217 *
     218 * Get the number of bytes which are used by the wide string @a str (excluding the
     219 * NULL-terminator).
     220 *
     221 * @param str Wide string to consider.
     222 *
     223 * @return Number of bytes used by the wide string
     224 *
     225 */
     226size_t wstr_size(const wchar_t *str)
     227{
     228        return (wstr_length(str) * sizeof(wchar_t));
     229}
     230
     231/** Get size of string with length limit.
     232 *
     233 * Get the number of bytes which are used by up to @a max_len first
     234 * characters in the string @a str. If @a max_len is greater than
     235 * the length of @a str, the entire string is measured (excluding the
     236 * NULL-terminator).
     237 *
     238 * @param str     String to consider.
     239 * @param max_len Maximum number of characters to measure.
     240 *
     241 * @return Number of bytes used by the characters.
     242 *
     243 */
     244size_t str_lsize(const char *str, count_t max_len)
     245{
     246        count_t len = 0;
     247        size_t offset = 0;
     248       
     249        while (len < max_len) {
     250                if (str_decode(str, &offset, STR_NO_LIMIT) == 0)
     251                        break;
     252               
     253                len++;
     254        }
     255       
     256        return offset;
     257}
     258
     259/** Get size of wide string with length limit.
     260 *
     261 * Get the number of bytes which are used by up to @a max_len first
     262 * wide characters in the wide string @a str. If @a max_len is greater than
     263 * the length of @a str, the entire wide string is measured (excluding the
     264 * NULL-terminator).
     265 *
     266 * @param str     Wide string to consider.
     267 * @param max_len Maximum number of wide characters to measure.
     268 *
     269 * @return Number of bytes used by the wide characters.
     270 *
     271 */
     272size_t wstr_lsize(const wchar_t *str, count_t max_len)
     273{
     274        return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
     275}
     276
     277/** Get number of characters in a string.
     278 *
     279 * @param str NULL-terminated string.
     280 *
     281 * @return Number of characters in string.
     282 *
     283 */
     284count_t str_length(const char *str)
     285{
     286        count_t len = 0;
     287        size_t offset = 0;
     288       
     289        while (str_decode(str, &offset, STR_NO_LIMIT) != 0)
     290                len++;
     291       
     292        return len;
     293}
     294
     295/** Get number of characters in a wide string.
     296 *
     297 * @param str NULL-terminated wide string.
     298 *
     299 * @return Number of characters in @a str.
     300 *
     301 */
     302count_t wstr_length(const wchar_t *wstr)
     303{
     304        count_t len = 0;
     305       
     306        while (*wstr++ != 0)
     307                len++;
     308       
     309        return len;
     310}
     311
     312/** Get number of characters in a string with size limit.
     313 *
     314 * @param str  NULL-terminated string.
     315 * @param size Maximum number of bytes to consider.
     316 *
     317 * @return Number of characters in string.
     318 *
     319 */
     320count_t str_nlength(const char *str, size_t size)
     321{
     322        count_t len = 0;
     323        size_t offset = 0;
     324       
     325        while (str_decode(str, &offset, size) != 0)
     326                len++;
     327       
     328        return len;
     329}
     330
     331/** Get number of characters in a string with size limit.
     332 *
     333 * @param str  NULL-terminated string.
     334 * @param size Maximum number of bytes to consider.
     335 *
     336 * @return Number of characters in string.
     337 *
     338 */
     339count_t wstr_nlength(const wchar_t *str, size_t size)
     340{
     341        count_t len = 0;
     342        count_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
     343        count_t offset = 0;
     344       
     345        while ((offset < limit) && (*str++ != 0)) {
     346                len++;
     347                offset += sizeof(wchar_t);
     348        }
     349       
     350        return len;
     351}
     352
     353/** Check whether character is plain ASCII.
     354 *
     355 * @return True if character is plain ASCII.
     356 *
     357 */
     358bool ascii_check(wchar_t ch)
     359{
     360        if ((ch >= 0) && (ch <= 127))
     361                return true;
     362       
     363        return false;
     364}
     365
    195366/** Check whether character is valid
    196367 *
     
    198369 *
    199370 */
    200 bool chr_check(const wchar_t ch)
     371bool chr_check(wchar_t ch)
    201372{
    202373        if ((ch >= 0) && (ch <= 1114111))
     
    204375       
    205376        return false;
     377}
     378
     379/** Compare two NULL terminated strings.
     380 *
     381 * Do a char-by-char comparison of two NULL-terminated strings.
     382 * The strings are considered equal iff they consist of the same
     383 * characters on the minimum of their lengths.
     384 *
     385 * @param s1 First string to compare.
     386 * @param s2 Second string to compare.
     387 *
     388 * @return 0 if the strings are equal, -1 if first is smaller,
     389 *         1 if second smaller.
     390 *
     391 */
     392int str_cmp(const char *s1, const char *s2)
     393{
     394        wchar_t c1 = 0;
     395        wchar_t c2 = 0;
     396       
     397        size_t off1 = 0;
     398        size_t off2 = 0;
     399
     400        while (true) {
     401                c1 = str_decode(s1, &off1, STR_NO_LIMIT);
     402                c2 = str_decode(s2, &off2, STR_NO_LIMIT);
     403
     404                if (c1 < c2)
     405                        return -1;
     406               
     407                if (c1 > c2)
     408                        return 1;
     409
     410                if (c1 == 0 || c2 == 0)
     411                        break;         
     412        }
     413
     414        return 0;
     415}
     416
     417/** Compare two NULL terminated strings with length limit.
     418 *
     419 * Do a char-by-char comparison of two NULL-terminated strings.
     420 * The strings are considered equal iff they consist of the same
     421 * characters on the minimum of their lengths and the length limit.
     422 *
     423 * @param s1      First string to compare.
     424 * @param s2      Second string to compare.
     425 * @param max_len Maximum number of characters to consider.
     426 *
     427 * @return 0 if the strings are equal, -1 if first is smaller,
     428 *         1 if second smaller.
     429 *
     430 */
     431int str_lcmp(const char *s1, const char *s2, count_t max_len)
     432{
     433        wchar_t c1 = 0;
     434        wchar_t c2 = 0;
     435       
     436        size_t off1 = 0;
     437        size_t off2 = 0;
     438       
     439        count_t len = 0;
     440
     441        while (true) {
     442                if (len >= max_len)
     443                        break;
     444
     445                c1 = str_decode(s1, &off1, STR_NO_LIMIT);
     446                c2 = str_decode(s2, &off2, STR_NO_LIMIT);
     447
     448                if (c1 < c2)
     449                        return -1;
     450
     451                if (c1 > c2)
     452                        return 1;
     453
     454                if (c1 == 0 || c2 == 0)
     455                        break;
     456
     457                ++len; 
     458        }
     459
     460        return 0;
     461
     462}
     463
     464/** Copy NULL-terminated string.
     465 *
     466 * Copy source string @a src to destination buffer @a dst.
     467 * No more than @a size bytes are written. NULL-terminator is always
     468 * written after the last succesfully copied character (i.e. if the
     469 * destination buffer is has at least 1 byte, it will be always
     470 * NULL-terminated).
     471 *
     472 * @param src   Source string.
     473 * @param dst   Destination buffer.
     474 * @param count Size of the destination buffer.
     475 *
     476 */
     477void str_ncpy(char *dst, const char *src, size_t size)
     478{
     479        /* No space for the NULL-terminator in the buffer */
     480        if (size == 0)
     481                return;
     482       
     483        wchar_t ch;
     484        size_t str_off = 0;
     485        size_t dst_off = 0;
     486       
     487        while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) {
     488                if (chr_encode(ch, dst, &dst_off, size) != EOK)
     489                        break;
     490        }
     491       
     492        if (dst_off >= size)
     493                dst[size - 1] = 0;
     494        else
     495                dst[dst_off] = 0;
     496}
     497
     498/** Copy NULL-terminated wide string to string
     499 *
     500 * Copy source wide string @a src to destination buffer @a dst.
     501 * No more than @a size bytes are written. NULL-terminator is always
     502 * written after the last succesfully copied character (i.e. if the
     503 * destination buffer is has at least 1 byte, it will be always
     504 * NULL-terminated).
     505 *
     506 * @param src   Source wide string.
     507 * @param dst   Destination buffer.
     508 * @param count Size of the destination buffer.
     509 *
     510 */
     511void wstr_nstr(char *dst, const wchar_t *src, size_t size)
     512{
     513        /* No space for the NULL-terminator in the buffer */
     514        if (size == 0)
     515                return;
     516       
     517        wchar_t ch;
     518        count_t src_idx = 0;
     519        size_t dst_off = 0;
     520       
     521        while ((ch = src[src_idx++]) != 0) {
     522                if (chr_encode(ch, dst, &dst_off, size) != EOK)
     523                        break;
     524        }
     525       
     526        if (dst_off >= size)
     527                dst[size - 1] = 0;
     528        else
     529                dst[dst_off] = 0;
     530}
     531
     532/** Find first occurence of character in string.
     533 *
     534 * @param str String to search.
     535 * @param ch  Character to look for.
     536 *
     537 * @return Pointer to character in @a str or NULL if not found.
     538 *
     539 */
     540const char *str_chr(const char *str, wchar_t ch)
     541{
     542        wchar_t acc;
     543        size_t off = 0;
     544       
     545        while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
     546                if (acc == ch)
     547                        return (str + off);
     548        }
     549       
     550        return NULL;
     551}
     552
     553/** Insert a wide character into a wide string.
     554 *
     555 * Insert a wide character into a wide string at position
     556 * @a pos. The characters after the position are shifted.
     557 *
     558 * @param str     String to insert to.
     559 * @param ch      Character to insert to.
     560 * @param pos     Character index where to insert.
     561 @ @param max_pos Characters in the buffer.
     562 *
     563 * @return True if the insertion was sucessful, false if the position
     564 *         is out of bounds.
     565 *
     566 */
     567bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos)
     568{
     569        count_t len = wstr_length(str);
     570       
     571        if ((pos > len) || (pos + 1 > max_pos))
     572                return false;
     573       
     574        count_t i;
     575        for (i = len; i + 1 > pos; i--)
     576                str[i + 1] = str[i];
     577       
     578        str[pos] = ch;
     579       
     580        return true;
     581}
     582
     583/** Remove a wide character from a wide string.
     584 *
     585 * Remove a wide character from a wide string at position
     586 * @a pos. The characters after the position are shifted.
     587 *
     588 * @param str String to remove from.
     589 * @param pos Character index to remove.
     590 *
     591 * @return True if the removal was sucessful, false if the position
     592 *         is out of bounds.
     593 *
     594 */
     595bool wstr_remove(wchar_t *str, count_t pos)
     596{
     597        count_t len = wstr_length(str);
     598       
     599        if (pos >= len)
     600                return false;
     601       
     602        count_t i;
     603        for (i = pos + 1; i <= len; i++)
     604                str[i - 1] = str[i];
     605       
     606        return true;
    206607}
    207608
Note: See TracChangeset for help on using the changeset viewer.