[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH] libc: wctomb()



Am Sonntag, 18. Januar 2009 19:02 schrieb Antoine Kaufmann:
> + libc: wctomb() zum Umwandeln eines wchars in einen Multibyte-String
> ---
>  src/include/stdlib.h       |   15 +++++++++++++-
>  src/lib/string/multibyte.c |   46
> +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57
> insertions(+), 4 deletions(-)
>
> diff --git a/src/include/stdlib.h b/src/include/stdlib.h
> index bbabf8a..a817765 100644
> --- a/src/include/stdlib.h
> +++ b/src/include/stdlib.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2006 The tyndur Project. All rights reserved.
> + * Copyright (c) 2006-2009 The tyndur Project. All rights reserved.
>   *
>   * This code is derived from software contributed to the tyndur Project
>   * by Antoine Kaufmann.
> @@ -107,6 +107,19 @@ int mblen(const char* s, size_t slen);
>   */
>  int mbtowc(wchar_t* wc, const char* s, size_t len);
>
> +/**
> + * Einen wchar in ein Multibyte-Zeichen umwandeln. Der Aufrufer muss
> + * garantieren dass in buf mindestens MB_CUR_MAX Bytes verfuegbar sind.
> + *
> + * @param buf Puffer in dem das Multibyte-Zeichen abgelegt wird. Dabei
> koennen + *            bis zu MB_CUR_MAX Bytes geschrieben werden.
> + * @param wc  Der umzuwandelnde wchar
> + *
> + * @return Bei Erfolg wir die Anzahl der in buf geschrieben Bytes
> + *         zurueckgegeben, im Fehlerfall -1.
> + */
> +int wctomb(char* buf, wchar_t wc);

Wenn du das so implementierst wie im Kommentar beschrieben, dann fehlt der 
Fall buf == NULL. Ansonsten fehlt der passende Kommentar. (Also genaugenommen 
fehlt in beiden Fällen ein Kommentar, die Frage ist nur, ob er mit FIXME 
anfängt)

>  /**
>   * Seed fuer Zufallszahlgenerator setzen
> diff --git a/src/lib/string/multibyte.c b/src/lib/string/multibyte.c
> index 6bd168e..f0bb4a0 100644
> --- a/src/lib/string/multibyte.c
> +++ b/src/lib/string/multibyte.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2008 The tyndur Project. All rights reserved.
> + * Copyright (c) 2008-2009 The tyndur Project. All rights reserved.
>   *
>   * This code is derived from software contributed to the tyndur Project
>   * by Antoine Kaufmann.
> @@ -60,7 +60,7 @@
>  #define VAL_3 (BIT(7) | BIT(6) | BIT(5))
>  #define VAL_4 (BIT(7) | BIT(6) | BIT(5) | BIT(6))
>
> -#define get_lower_bits(v, x) (v & (BIT(x + 1) - 1))
> +#define get_lower_bits(v, x) (v & (BIT(x) - 1))
>
>
>  /**
> @@ -138,7 +138,7 @@ int mbtowc(wchar_t* wc, const char* s, size_t slen)
>      }
>
>      // Erstes Zeichen wird separat behandelt
> -    bitpos = (len == 1 ? 7 : 7 - len);
> +    bitpos = (len == 1 ? 7 : 6 - len);
>      *wc = get_lower_bits(s[0], bitpos);

Diese zwei Hunks sind ein Bugfix und gehören eigentlich nicht hier rein, oder?

Davon abgesehen: Wäre bitpos = 7 - (len - 1); nicht lesbarer?

>      // Die anderen Zeichen sind alle gleich
> @@ -150,3 +150,43 @@ int mbtowc(wchar_t* wc, const char* s, size_t slen)
>      return len;
>  }
>
> +extern void puts(const char*);
> +extern void printf(const char*,...);
> +extern void* stdout;

*hust*

> +/**
> + * Einen wchar in ein Multibyte-Zeichen umwandeln. Der Aufrufer muss
> + * garantieren dass in buf mindestens MB_CUR_MAX Bytes verfuegbar sind.
> + *
> + * @param buf Puffer in dem das Multibyte-Zeichen abgelegt wird. Dabei
> koennen + *            bis zu MB_CUR_MAX Bytes geschrieben werden.
> + * @param wc  Der umzuwandelnde wchar
> + *
> + * @return Bei Erfolg wir die Anzahl der in buf geschrieben Bytes
> + *         zurueckgegeben, im Fehlerfall -1.
> + */
> +int wctomb(char* buf, wchar_t wc)
> +{
> +    if (buf == NULL) {
> +        return 0;
> +    }
> +
> +    if (get_lower_bits(wc, 7) == wc) {
> +        buf[0] = get_lower_bits(wc, 7) | VAL_1;
> +        return 1;
> +    } else if (get_lower_bits(wc, 11) == wc) {
> +        buf[0] = get_lower_bits((wc >> 6), 5) | VAL_2;
> +        buf[1] = get_lower_bits((wc >> 0), 6) | BIT(7);
> +        return 2;
> +    } else if (get_lower_bits(wc, 16) == wc) {
> +        buf[0] = get_lower_bits((wc >> 12), 4) | VAL_3;
> +        buf[1] = get_lower_bits((wc >>  6), 6) | BIT(7);
> +        buf[2] = get_lower_bits((wc >>  0), 6) | BIT(7);
> +        return 3;
> +    } else {
> +        buf[0] = get_lower_bits((wc >> 18), 3) | VAL_4;
> +        buf[1] = get_lower_bits((wc >> 12), 6) | BIT(7);
> +        buf[2] = get_lower_bits((wc >>  6), 6) | BIT(7);
> +        buf[3] = get_lower_bits((wc >>  0), 6) | BIT(7);
> +        return 4;
> +    }
> +}

Aber zumindest in der Umwandlung an sich sehe ich jetzt nicht auf Anhieb einen 
Fehler. ;-)