summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/common/strnatcmp.c179
-rw-r--r--firmware/include/strnatcmp.h30
3 files changed, 210 insertions, 0 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index de42ada0cc..0b6bb155b0 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -49,6 +49,7 @@ common/strcasestr.c
49common/strcat.c 49common/strcat.c
50common/strchr.c 50common/strchr.c
51common/strcmp.c 51common/strcmp.c
52common/strnatcmp.c
52common/strcpy.c 53common/strcpy.c
53common/strncmp.c 54common/strncmp.c
54common/strncpy.c 55common/strncpy.c
diff --git a/firmware/common/strnatcmp.c b/firmware/common/strnatcmp.c
new file mode 100644
index 0000000000..84e0d38362
--- /dev/null
+++ b/firmware/common/strnatcmp.c
@@ -0,0 +1,179 @@
1/* -*- mode: c; c-file-style: "k&r" -*-
2
3 strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
4 Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21*/
22
23
24/* partial change history:
25 *
26 * 2004-10-10 mbp: Lift out character type dependencies into macros.
27 *
28 * Eric Sosman pointed out that ctype functions take a parameter whose
29 * value must be that of an unsigned int, even on platforms that have
30 * negative chars in their default char type.
31 */
32
33#include <ctype.h>
34#include <string.h>
35#include <stdio.h>
36
37#include "strnatcmp.h"
38
39#define assert(x) /* nothing */
40
41
42/* These are defined as macros to make it easier to adapt this code to
43 * different characters types or comparison functions. */
44static inline int
45nat_isdigit(char a)
46{
47 return isdigit((unsigned char) a);
48}
49
50
51static inline int
52nat_isspace(char a)
53{
54 return a == '0' || isspace((unsigned char) a);
55}
56
57
58static inline char
59nat_toupper(char a)
60{
61 return toupper((unsigned char) a);
62}
63
64
65
66static int
67compare_right(char const *a, char const *b)
68{
69 int bias = 0;
70
71 /* The longest run of digits wins. That aside, the greatest
72 value wins, but we can't know that it will until we've scanned
73 both numbers to know that they have the same magnitude, so we
74 remember it in BIAS. */
75 for (;; a++, b++) {
76 if (!nat_isdigit(*a) && !nat_isdigit(*b))
77 return bias;
78 else if (!nat_isdigit(*a))
79 return -1;
80 else if (!nat_isdigit(*b))
81 return +1;
82 else if (*a < *b) {
83 if (!bias)
84 bias = -1;
85 } else if (*a > *b) {
86 if (!bias)
87 bias = +1;
88 } else if (!*a && !*b)
89 return bias;
90 }
91
92 return 0;
93}
94
95
96static int
97compare_left(char const *a, char const *b)
98{
99 /* Compare two left-aligned numbers: the first to have a
100 different value wins. */
101 for (;; a++, b++) {
102 if (!nat_isdigit(*a) && !nat_isdigit(*b))
103 return 0;
104 else if (!nat_isdigit(*a))
105 return -1;
106 else if (!nat_isdigit(*b))
107 return +1;
108 else if (*a < *b)
109 return -1;
110 else if (*a > *b)
111 return +1;
112 }
113
114 return 0;
115}
116
117
118static int strnatcmp0(char const *a, char const *b, int fold_case)
119{
120 int ai, bi;
121 char ca, cb;
122 int fractional, result;
123
124 assert(a && b);
125 ai = bi = 0;
126 while (1) {
127 ca = a[ai]; cb = b[bi];
128
129 /* skip over leading spaces or zeros */
130 while (nat_isspace(ca))
131 ca = a[++ai];
132
133 while (nat_isspace(cb))
134 cb = b[++bi];
135
136 /* process run of digits */
137 if (nat_isdigit(ca) && nat_isdigit(cb)) {
138 fractional = (ca == '0' || cb == '0');
139
140 if (fractional) {
141 if ((result = compare_left(a+ai, b+bi)) != 0)
142 return result;
143 } else {
144 if ((result = compare_right(a+ai, b+bi)) != 0)
145 return result;
146 }
147 }
148
149 if (!ca && !cb) {
150 /* The strings compare the same. Perhaps the caller
151 will want to call strcmp to break the tie. */
152 return 0;
153 }
154
155 if (fold_case) {
156 ca = nat_toupper(ca);
157 cb = nat_toupper(cb);
158 }
159
160 if (ca < cb)
161 return -1;
162 else if (ca > cb)
163 return +1;
164
165 ++ai; ++bi;
166 }
167}
168
169
170
171int strnatcmp(const char *a, const char *b) {
172 return strnatcmp0(a, b, 0);
173}
174
175
176/* Compare, recognizing numeric string and ignoring case. */
177int strnatcasecmp(const char *a, const char *b) {
178 return strnatcmp0(a, b, 1);
179}
diff --git a/firmware/include/strnatcmp.h b/firmware/include/strnatcmp.h
new file mode 100644
index 0000000000..50276554e6
--- /dev/null
+++ b/firmware/include/strnatcmp.h
@@ -0,0 +1,30 @@
1/* -*- mode: c; c-file-style: "k&r" -*-
2
3 strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
4 Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21*/
22
23
24/* CUSTOMIZATION SECTION
25 *
26 * You can change this typedef, but must then also change the inline
27 * functions in strnatcmp.c */
28
29int strnatcmp(const char *a, const char *b);
30int strnatcasecmp(const char *a, const char *b);