identifier: Make lex_id_get_length() handle Unicode.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 6 Jan 2013 23:20:32 +0000 (15:20 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 12 Jan 2013 17:50:40 +0000 (09:50 -0800)
This function's only caller is documented only to handle ASCII, so this
commit does not fix any bug, but it seems better to generalize our code.

src/data/identifier.c

index 6191f0db9028257e7facbddc566c5ba2e0ef08cb..db20010464cab1e3f3a1f42cc1e7a4c012bf8c1b 100644 (file)
 #include "data/identifier.h"
 
 #include <string.h>
+#include <unistr.h>
 #include <unictype.h>
 
 #include "libpspp/assertion.h"
+#include "libpspp/cast.h"
 
 #include "gl/c-ctype.h"
 
@@ -232,15 +234,21 @@ lex_uc_is_space (ucs4_t uc)
 size_t
 lex_id_get_length (struct substring string)
 {
-  size_t length = 0;
-  if (!ss_is_empty (string) && lex_is_id1 (ss_first (string)))
+  const uint8_t *s = CHAR_CAST (const uint8_t *, string.string);
+  size_t len = string.length;
+  size_t ofs;
+  int mblen;
+
+  for (ofs = 0; ofs < string.length; ofs += mblen)
     {
-      length = 1;
-      while (length < ss_length (string)
-             && lex_is_idn (ss_at (string, length)))
-        length++;
+      ucs4_t uc;
+
+      mblen = u8_mbtouc (&uc, s + ofs, len - ofs);
+      if (!(ofs == 0 ? lex_uc_is_id1 (uc) : lex_uc_is_idn (uc)))
+        break;
     }
-  return length;
+
+  return ofs;
 }
 \f
 /* Comparing identifiers. */