summaryrefslogtreecommitdiff
path: root/string/strcoll.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1991-01-30 10:25:34 +0000
committerRoland McGrath <roland@gnu.org>1991-01-30 10:25:34 +0000
commitc2547ce6a46f905a7f876f3e2c35e6e9e9b36527 (patch)
tree2b619afb1196c20c60ea0272412e589ad8a9039d /string/strcoll.c
parent1c078555037a905f1e9bb29951e5e16420d66992 (diff)
Initial revision
Diffstat (limited to 'string/strcoll.c')
-rw-r--r--string/strcoll.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/string/strcoll.c b/string/strcoll.c
new file mode 100644
index 0000000000..0146aee780
--- /dev/null
+++ b/string/strcoll.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the GNU C Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <ansidecl.h>
+#include <localeinfo.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Compare S1 and S2, returning less than, equal to or
+ greater than zero if the collated form of S1 is lexiographically
+ less than, equal to or greater than the collated form of S2. */
+int
+DEFUN(strcoll, (s1, s2), CONST char *s1 AND CONST char *s2)
+{
+ if (_collate_info == NULL || _collate_info->values == NULL)
+ return strcmp(s1, s2);
+ else
+ {
+ CONST unsigned char *CONST values = _collate_info->values;
+ CONST unsigned char *CONST offsets = _collate_info->offsets;
+
+ while (*s1 != '\0' && *s2 != '\0')
+ {
+ CONST unsigned char c1 = *s1++, c2 = *s2++;
+ CONST unsigned char v1 = values[c1], v2 = values[c2];
+ CONST unsigned char o1 = offsets[c1], o2 = offsets[c2];
+
+ if (v1 == UCHAR_MAX && o1 == 0)
+ /* This is a non-collating element. Skip it. */
+ --s2;
+ else if (v2 == UCHAR_MAX && o2 == 0)
+ --s1;
+ else if (v1 == UCHAR_MAX && o1 == CHAR_MAX)
+ {
+ /* This element collates lower than anything else. */
+ if (v2 != UCHAR_MAX || o2 != CHAR_MAX)
+ return -1;
+ }
+ else if (v2 == UCHAR_MAX && o2 == CHAR_MAX)
+ return 1;
+ else if (v1 != v2)
+ return v1 - v2;
+ else if (o1 != o2)
+ return o1 - o2;
+ }
+
+ if (*s1 == '\0')
+ return *s2 == '\0' ? 0 : -1;
+ else if (*s2 == '\0')
+ return 1;
+ return 0;
+ }
+}