From 8f991575ea44e073698f45290fa469c781fe8146 Mon Sep 17 00:00:00 2001 From: g Date: Mon, 1 Sep 2003 23:04:59 +0000 Subject: [PATCH] Use the "magic" version that does not assume that the string is in ASCII. git-svn-id: file:///srv/svn/gliv/trunk@72 dbf4865f-1ec6-0310-8412-f61adeb1ccb1 committer: g --- src/str_utils.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/str_utils.c b/src/str_utils.c index 1692664..9becb79 100644 --- a/src/str_utils.c +++ b/src/str_utils.c @@ -78,7 +78,14 @@ const gchar *add_mnemonic(const gchar * str) return *result; } -static void init_magic(gulong * himagic, gulong * lomagic) +/* + * The magic to find a '\0' in a long int is taken from the glibc. + * See sysdeps/generic/strlen.c in the glibc sources to have the + * explanation. + * Actually it also finds 0x80, that's why we double check when + * HAS_ZERO() finds something. + */ +static void init_magic(gulong * himagic, gulong * lomagic, gulong * magic_bits) { *himagic = 0x80808080L; *lomagic = 0x01010101L; @@ -86,9 +93,13 @@ static void init_magic(gulong * himagic, gulong * lomagic) /* 64-bit */ *himagic = ((*himagic << 16) << 16) | *himagic; *lomagic = ((*lomagic << 16) << 16) | *lomagic; - } + *magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; + } else + *magic_bits = 0x7efefeffL; } +#define HAS_ZERO(longint) ((((longint) + magic_bits) ^ ~longint) & ~magic_bits) + #define CHECK_BYTE(ptr) \ do { \ if (*ptr == '\0') \ @@ -100,14 +111,9 @@ static void init_magic(gulong * himagic, gulong * lomagic) ptr++; \ } while (0) -/* - * The magic to find a '\0' in a long int is taken from the glibc. - * See sysdeps/generic/strlen.c in the glibc sources to have the - * explanation. - */ static gboolean str_is_ascii(const gchar * str) { - gulong himagic, lomagic; + gulong himagic, lomagic, magic_bits; gulong *long_ptr, long_int; gulong mask; @@ -126,7 +132,7 @@ static gboolean str_is_ascii(const gchar * str) } long_ptr = (gulong *) str; - init_magic(&himagic, &lomagic); + init_magic(&himagic, &lomagic, &magic_bits); mask = 0x80808080; if (sizeof(gulong) > 4) /* 64-bit */ @@ -134,7 +140,7 @@ static gboolean str_is_ascii(const gchar * str) for (;;) { long_int = *long_ptr; - if ((long_int - lomagic) & himagic) { + if (HAS_ZERO(long_int)) { /* A '\0' has been detected. */ const gchar *char_ptr = (const gchar *) long_ptr; CHECK_BYTE(char_ptr); @@ -219,7 +225,7 @@ const gchar *filename_to_utf8(const gchar * str) gint count_underscores(const gchar * str) { gint nb_underscores = 0; - gulong himagic, lomagic; + gulong himagic, lomagic, magic_bits; gulong *long_ptr, long_int; gulong mask; @@ -238,7 +244,7 @@ gint count_underscores(const gchar * str) } long_ptr = (gulong *) str; - init_magic(&himagic, &lomagic); + init_magic(&himagic, &lomagic, &magic_bits); /* '_' == 0x5F */ mask = 0x5F5F5F5F; @@ -248,7 +254,7 @@ gint count_underscores(const gchar * str) for (;;) { long_int = *long_ptr; - if ((long_int - lomagic) & himagic) { + if (HAS_ZERO(long_int)) { /* A '\0' has been detected. */ const gchar *char_ptr = (const gchar *) long_ptr; CHECK_UNDERSCORE(char_ptr); @@ -266,7 +272,7 @@ gint count_underscores(const gchar * str) gulong masked; masked = long_int ^ mask; - if ((masked - lomagic) & himagic) { + if (HAS_ZERO(masked)) { /* A '_' has been detected. */ gchar *char_ptr = (gchar *) & mask; nb_underscores += (*char_ptr++ == 0); -- 2.11.4.GIT