aboutsummaryrefslogtreecommitdiff
path: root/libbb/appletlib.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-02-05 11:24:06 +0000
committerRon Yorston <rmy@pobox.com>2021-02-05 11:24:06 +0000
commit32e19e7ae8b0d76d69871ba234e8f0af31baff4e (patch)
tree6fdc833a444e0dd6fd359b21a8d463856917a387 /libbb/appletlib.c
parent4fb71406b884c6ac0a9a4d2acf7a32b544611f70 (diff)
parentcad3fc743aa7c7744e4fcf044371f0fda50fa51f (diff)
downloadbusybox-w32-32e19e7ae8b0d76d69871ba234e8f0af31baff4e.tar.gz
busybox-w32-32e19e7ae8b0d76d69871ba234e8f0af31baff4e.tar.bz2
busybox-w32-32e19e7ae8b0d76d69871ba234e8f0af31baff4e.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r--libbb/appletlib.c96
1 files changed, 17 insertions, 79 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index ecee45ae2..320cb5b13 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -191,7 +191,7 @@ void FAST_FUNC bb_show_usage(void)
191 191
192int FAST_FUNC find_applet_by_name(const char *name) 192int FAST_FUNC find_applet_by_name(const char *name)
193{ 193{
194 unsigned i, max; 194 unsigned i;
195 int j; 195 int j;
196 const char *p; 196 const char *p;
197 197
@@ -215,105 +215,43 @@ int FAST_FUNC find_applet_by_name(const char *name)
215#endif 215#endif
216 216
217 p = applet_names; 217 p = applet_names;
218 i = 0;
219#if KNOWN_APPNAME_OFFSETS <= 0 218#if KNOWN_APPNAME_OFFSETS <= 0
220 max = NUM_APPLETS; 219 i = 0;
221#else 220#else
222 max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS; 221 i = NUM_APPLETS * (KNOWN_APPNAME_OFFSETS - 1);
223 for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) { 222 for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) {
224 const char *pp = applet_names + applet_nameofs[j]; 223 const char *pp = applet_names + applet_nameofs[j];
225 if (strcmp(name, pp) >= 0) { 224 if (strcmp(name, pp) >= 0) {
226 //bb_error_msg("name:'%s' >= pp:'%s'", name, pp); 225 //bb_error_msg("name:'%s' >= pp:'%s'", name, pp);
227 p = pp; 226 p = pp;
228 i = max - NUM_APPLETS;
229 break; 227 break;
230 } 228 }
231 max -= NUM_APPLETS; 229 i -= NUM_APPLETS;
232 } 230 }
233 max /= (unsigned)KNOWN_APPNAME_OFFSETS;
234 i /= (unsigned)KNOWN_APPNAME_OFFSETS; 231 i /= (unsigned)KNOWN_APPNAME_OFFSETS;
235 //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max); 232 //bb_error_msg("name:'%s' starting from:'%s' i:%u", name, p, i);
236#endif 233#endif
237 234
238 /* Open-coded linear search without strcmp/strlen calls for speed */ 235 /* Open-coded linear search without strcmp/strlen calls for speed */
239 236 while (*p) {
240#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ 237 /* Do we see "name\0" at current position in applet_names? */
241 /* skip "[\0" name, it's surely not it */ 238 for (j = 0; *p == name[j]; ++j) {
242 if (ENABLE_TEST && LONE_CHAR(p, '[')) 239 if (*p++ == '\0') {
243 i++, p += 2;
244 /* All remaining applet names in p[] are at least 2 chars long */
245 /* name[] is also at least 2 chars long */
246
247 n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16);
248 while (i < max) {
249 uint32_t p32;
250 char ch;
251
252 /* Quickly check match of the first 3 bytes */
253 move_from_unaligned32(p32, p);
254 p += 3;
255 if ((p32 & 0x00ffffff) != n32) {
256 /* Most likely case: 3 first bytes do not match */
257 i++;
258 if ((p32 & 0x00ff0000) == '\0')
259 continue; // p[2] was NUL
260 p++;
261 if ((p32 & 0xff000000) == '\0')
262 continue; // p[3] was NUL
263 /* p[0..3] aren't matching and none is NUL, check the rest */
264 while (*p++ != '\0')
265 continue;
266 continue;
267 }
268
269 /* Unlikely branch: first 3 bytes ([0..2]) match */
270 if ((p32 & 0x00ff0000) == '\0') {
271 /* name is 2-byte long, it is full match */
272 //bb_error_msg("found:'%s' i:%u", name, i);
273 return i;
274 }
275 /* Check remaining bytes [3..NUL] */
276 ch = (p32 >> 24);
277 j = 3;
278 while (ch == name[j]) {
279 if (ch == '\0') {
280 //bb_error_msg("found:'%s' i:%u", name, i);
281 return i;
282 }
283 ch = *++p;
284 j++;
285 }
286 /* Not a match. Skip it, including NUL */
287 while (ch != '\0')
288 ch = *++p;
289 p++;
290 i++;
291 }
292 return -1;
293#else
294 while (i < max) {
295 char ch;
296 j = 0;
297 /* Do we see "name\0" in applet_names[p] position? */
298 while ((ch = *p) == name[j]) {
299 if (ch == '\0') {
300 //bb_error_msg("found:'%s' i:%u", name, i); 240 //bb_error_msg("found:'%s' i:%u", name, i);
301 return i; /* yes */ 241 return i; /* yes */
302 } 242 }
303 p++;
304 j++;
305 } 243 }
306 /* No. 244 /* No. Have we gone too far, alphabetically? */
307 * p => 1st non-matching char in applet_names[], 245 if (*p > name[j]) {
308 * skip to and including NUL. 246 //bb_error_msg("break:'%s' i:%u", name, i);
309 */ 247 break;
310 while (ch != '\0') 248 }
311 ch = *++p; 249 /* No. Move to the start of the next applet name. */
312 p++; 250 while (*p++ != '\0')
251 continue;
313 i++; 252 i++;
314 } 253 }
315 return -1; 254 return -1;
316#endif
317} 255}
318 256
319 257