aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Albinus2014-08-24 17:40:07 +0200
committerMichael Albinus2014-08-24 17:40:07 +0200
commit07b47905d3b38ac77398213cdb76b2dca2217db7 (patch)
tree592f4ee93e3ee5892757b48ae470ce783aa1a9e4 /src
parentbf5b1e26c1a1c965aca2ddf4fe06bcce2ddce9d0 (diff)
downloademacs-07b47905d3b38ac77398213cdb76b2dca2217db7.tar.gz
emacs-07b47905d3b38ac77398213cdb76b2dca2217db7.zip
Add string collation.
* configure.ac: Check also for the uselocale function. * src/fns.c (Fstring_collate_lessp, Fstring_collate_equalp): New DEFUNs. * src/sysdep.c (str_collate): New function. (Bug#18051)
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog6
-rw-r--r--src/fns.c84
-rw-r--r--src/sysdep.c74
3 files changed, 163 insertions, 1 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 90c66eb4705..72d7d405f7a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
12014-08-24 Michael Albinus <michael.albinus@gmx.de>
2
3 * fns.c (Fstring_collate_lessp, Fstring_collate_equalp): New DEFUNs.
4
5 * sysdep.c (str_collate): New function. (Bug#18051)
6
12014-08-23 Karol Ostrovsky <karol.ostrovsky@gmail.com> (tiny change) 72014-08-23 Karol Ostrovsky <karol.ostrovsky@gmail.com> (tiny change)
2 8
3 * Makefile.in (emacs$(EXEEXT)): Retry deletion of bootstrap-emacs 9 * Makefile.in (emacs$(EXEEXT)): Retry deletion of bootstrap-emacs
diff --git a/src/fns.c b/src/fns.c
index 33c02598359..fbcec4e659e 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -40,7 +40,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40#include "xterm.h" 40#include "xterm.h"
41#endif 41#endif
42 42
43Lisp_Object Qstring_lessp; 43Lisp_Object Qstring_lessp, Qstring_collate_lessp, Qstring_collate_equalp;
44static Lisp_Object Qprovide, Qrequire; 44static Lisp_Object Qprovide, Qrequire;
45static Lisp_Object Qyes_or_no_p_history; 45static Lisp_Object Qyes_or_no_p_history;
46Lisp_Object Qcursor_in_echo_area; 46Lisp_Object Qcursor_in_echo_area;
@@ -343,6 +343,84 @@ Symbols are also allowed; their print names are used instead. */)
343 } 343 }
344 return i1 < SCHARS (s2) ? Qt : Qnil; 344 return i1 < SCHARS (s2) ? Qt : Qnil;
345} 345}
346
347#ifdef __STDC_ISO_10646__
348/* Defined in sysdep.c. */
349extern ptrdiff_t str_collate (Lisp_Object, Lisp_Object);
350#endif /* __STDC_ISO_10646__ */
351
352DEFUN ("string-collate-lessp", Fstring_collate_lessp, Sstring_collate_lessp, 2, 2, 0,
353 doc: /* Return t if first arg string is less than second in collation order.
354
355Case is significant. Symbols are also allowed; their print names are
356used instead.
357
358This function obeys the conventions for collation order in your
359locale settings. For example, punctuation and whitespace characters
360are considered less significant for sorting.
361
362\(sort '\("11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp)
363 => \("11" "1 1" "1.1" "12" "1 2" "1.2")
364
365If your system does not support a locale environment, this function
366behaves like `string-lessp'.
367
368If the environment variable \"LC_COLLATE\" is set in `process-environment',
369it overrides the setting of your current locale. */)
370 (Lisp_Object s1, Lisp_Object s2)
371{
372#ifdef __STDC_ISO_10646__
373 /* Check parameters. */
374 if (SYMBOLP (s1))
375 s1 = SYMBOL_NAME (s1);
376 if (SYMBOLP (s2))
377 s2 = SYMBOL_NAME (s2);
378 CHECK_STRING (s1);
379 CHECK_STRING (s2);
380
381 return (str_collate (s1, s2) < 0) ? Qt : Qnil;
382
383#else
384 return Fstring_lessp (s1, s2);
385#endif /* __STDC_ISO_10646__ */
386}
387
388DEFUN ("string-collate-equalp", Fstring_collate_equalp, Sstring_collate_equalp, 2, 2, 0,
389 doc: /* Return t if two strings have identical contents.
390
391Case is significant. Symbols are also allowed; their print names are
392used instead.
393
394This function obeys the conventions for collation order in your locale
395settings. For example, characters with different coding points but
396the same meaning are considered as equal, like different grave accent
397unicode characters.
398
399\(string-collate-equalp \(string ?\\uFF40) \(string ?\\u1FEF))
400 => t
401
402If your system does not support a locale environment, this function
403behaves like `string-equal'.
404
405If the environment variable \"LC_COLLATE\" is set in `process-environment',
406it overrides the setting of your current locale. */)
407 (Lisp_Object s1, Lisp_Object s2)
408{
409#ifdef __STDC_ISO_10646__
410 /* Check parameters. */
411 if (SYMBOLP (s1))
412 s1 = SYMBOL_NAME (s1);
413 if (SYMBOLP (s2))
414 s2 = SYMBOL_NAME (s2);
415 CHECK_STRING (s1);
416 CHECK_STRING (s2);
417
418 return (str_collate (s1, s2) == 0) ? Qt : Qnil;
419
420#else
421 return Fstring_equal (s1, s2);
422#endif /* __STDC_ISO_10646__ */
423}
346 424
347static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args, 425static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args,
348 enum Lisp_Type target_type, bool last_special); 426 enum Lisp_Type target_type, bool last_special);
@@ -4919,6 +4997,8 @@ syms_of_fns (void)
4919 defsubr (&Sdefine_hash_table_test); 4997 defsubr (&Sdefine_hash_table_test);
4920 4998
4921 DEFSYM (Qstring_lessp, "string-lessp"); 4999 DEFSYM (Qstring_lessp, "string-lessp");
5000 DEFSYM (Qstring_collate_lessp, "string-collate-lessp");
5001 DEFSYM (Qstring_collate_equalp, "string-collate-equalp");
4922 DEFSYM (Qprovide, "provide"); 5002 DEFSYM (Qprovide, "provide");
4923 DEFSYM (Qrequire, "require"); 5003 DEFSYM (Qrequire, "require");
4924 DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history"); 5004 DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history");
@@ -4972,6 +5052,8 @@ this variable. */);
4972 defsubr (&Sstring_equal); 5052 defsubr (&Sstring_equal);
4973 defsubr (&Scompare_strings); 5053 defsubr (&Scompare_strings);
4974 defsubr (&Sstring_lessp); 5054 defsubr (&Sstring_lessp);
5055 defsubr (&Sstring_collate_lessp);
5056 defsubr (&Sstring_collate_equalp);
4975 defsubr (&Sappend); 5057 defsubr (&Sappend);
4976 defsubr (&Sconcat); 5058 defsubr (&Sconcat);
4977 defsubr (&Svconcat); 5059 defsubr (&Svconcat);
diff --git a/src/sysdep.c b/src/sysdep.c
index d5cfd5b88cf..619361472e4 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3513,3 +3513,77 @@ system_process_attributes (Lisp_Object pid)
3513} 3513}
3514 3514
3515#endif /* !defined (WINDOWSNT) */ 3515#endif /* !defined (WINDOWSNT) */
3516
3517/* Wide character string collation. */
3518
3519#ifdef __STDC_ISO_10646__
3520#include <wchar.h>
3521
3522#if defined (HAVE_USELOCALE) || defined (HAVE_SETLOCALE)
3523#include <locale.h>
3524#endif /* HAVE_USELOCALE || HAVE_SETLOCALE */
3525
3526ptrdiff_t
3527str_collate (Lisp_Object s1, Lisp_Object s2)
3528{
3529 register ptrdiff_t res, len, i, i_byte;
3530 wchar_t *p1, *p2;
3531 Lisp_Object lc_collate;
3532#ifdef HAVE_USELOCALE
3533 locale_t loc = (locale_t) 0, oldloc = (locale_t) 0;
3534#elif defined (HAVE_SETLOCALE)
3535 char *oldloc = NULL;
3536#endif /* HAVE_USELOCALE */
3537
3538 USE_SAFE_ALLOCA;
3539
3540 /* Convert byte stream to code points. */
3541 len = SCHARS (s1); i = i_byte = 0;
3542 p1 = (wchar_t *) SAFE_ALLOCA ((len+1) * (sizeof *p1));
3543 while (i < len)
3544 FETCH_STRING_CHAR_ADVANCE (*(p1+i-1), s1, i, i_byte);
3545 *(p1+len) = 0;
3546
3547 len = SCHARS (s2); i = i_byte = 0;
3548 p2 = (wchar_t *) SAFE_ALLOCA ((len+1) * (sizeof *p2));
3549 while (i < len)
3550 FETCH_STRING_CHAR_ADVANCE (*(p2+i-1), s2, i, i_byte);
3551 *(p2+len) = 0;
3552
3553#if defined (HAVE_USELOCALE) || defined (HAVE_SETLOCALE)
3554 /* Create a new locale object, and set it. */
3555 lc_collate =
3556 Fgetenv_internal (build_string ("LC_COLLATE"), Vprocess_environment);
3557
3558#ifdef HAVE_USELOCALE
3559 if (STRINGP (lc_collate)
3560 && (loc = newlocale (LC_COLLATE_MASK, SSDATA (lc_collate), (locale_t) 0)))
3561 oldloc = uselocale (loc);
3562#elif defined (HAVE_SETLOCALE)
3563 if (STRINGP (lc_collate))
3564 {
3565 oldloc = xstrdup (setlocale (LC_COLLATE, NULL));
3566 setlocale (LC_COLLATE, SSDATA (lc_collate));
3567 }
3568#endif /* HAVE_USELOCALE */
3569#endif /* HAVE_USELOCALE || HAVE_SETLOCALE */
3570
3571 res = wcscoll (p1, p2);
3572
3573#ifdef HAVE_USELOCALE
3574 /* Free the locale object, and reset. */
3575 if (loc)
3576 freelocale (loc);
3577 if (oldloc)
3578 uselocale (oldloc);
3579#elif defined (HAVE_SETLOCALE)
3580 /* Restore the original locale. */
3581 if (oldloc)
3582 setlocale (LC_COLLATE, oldloc);
3583#endif /* HAVE_USELOCALE */
3584
3585 /* Return result. */
3586 SAFE_FREE ();
3587 return res;
3588}
3589#endif /* __STDC_ISO_10646__ */