• R/O
  • SSH
  • HTTPS

yash: Commit


Commit MetaInfo

Revision4148 (tree)
Time2020-11-17 21:50:53
Authormagicant

Log Message

Faster numeric brace expansion

In the previous numeric brace expansion algorithm, search for a dot
might scan the entire remainder of the string if there was no dot, which
unnecessarily took time before the expansion fails.

After this commit, we avoid scanning and only check the character that
needs to be checked.

Change Summary

Incremental Difference

--- yash/trunk/expand.c (revision 4147)
+++ yash/trunk/expand.c (revision 4148)
@@ -1420,54 +1420,45 @@
14201420
14211421 /* parse the starting point */
14221422 const wchar_t *c = &e->word[ci];
1423- const wchar_t *dotp = wcschr(c, L'.');
1424- if (dotp == NULL || c == dotp || dotp[1] != L'.')
1425- return false;
1426- bool sign = false;
1427- int startlen = has_leading_zero(c, &sign) ? (dotp - c) : 0;
1423+ wchar_t *cp;
14281424 errno = 0;
1429- wchar_t *cp;
14301425 long start = wcstol(c, &cp, 10);
1431- if (errno != 0 || cp != dotp)
1426+ if (c == cp || errno != 0 || cp[0] != L'.' || cp[1] != L'.')
14321427 return false;
14331428
1434- c = dotp + 2;
1429+ bool sign = false;
1430+ int startlen = has_leading_zero(c, &sign) ? (cp - c) : 0;
14351431
14361432 /* parse the ending point */
1437- const wchar_t *dotbracep = wcspbrk(c, L".}");
1438- if (dotbracep == NULL || c == dotbracep ||
1439- (dotbracep[0] == L'.' && dotbracep[1] != L'.'))
1440- return false;
1441- int endlen = has_leading_zero(c, &sign) ? (dotbracep - c) : 0;
1433+ c = cp + 2;
14421434 errno = 0;
14431435 long end = wcstol(c, &cp, 10);
1444- if (errno != 0 || cp != dotbracep)
1436+ if (c == cp || errno != 0)
14451437 return false;
1438+ int endlen = has_leading_zero(c, &sign) ? (cp - c) : 0;
14461439
14471440 /* parse the delta */
14481441 long delta;
1449- const wchar_t *bracep;
1450- if (dotbracep[0] == L'.') {
1451- assert(dotbracep[1] == L'.');
1452- c = dotbracep + 2;
1453- bracep = wcschr(c, L'}');
1454- if (bracep == NULL || c == bracep)
1442+ if (cp[0] == L'.') {
1443+ if (cp[1] != L'.')
14551444 return false;
1445+
1446+ c = cp + 2;
14561447 errno = 0;
14571448 delta = wcstol(c, &cp, 10);
1458- if (delta == 0 || errno != 0 || cp != bracep)
1449+ if (delta == 0 || c == cp || errno != 0 || cp[0] != L'}')
14591450 return false;
1460- } else {
1461- assert(dotbracep[0] == L'}');
1462- bracep = dotbracep;
1451+ } else if (cp[0] == L'}') {
14631452 if (start <= end)
14641453 delta = 1;
14651454 else
14661455 delta = -1;
1456+ } else {
1457+ return false;
14671458 }
14681459
14691460 /* validate charcategory_T */
1470- size_t bracei = bracep - e->word;
1461+ size_t bracei = cp - e->word;
14711462 if (e->cc[bracei] != CC_LITERAL)
14721463 return false;
14731464 for (ci = starti; ci < bracei; ci++)
@@ -1477,7 +1468,7 @@
14771468 /* expand the sequence */
14781469 long value = start;
14791470 int len = (startlen > endlen) ? startlen : endlen;
1480- ci = bracep - e->word + 1;
1471+ ci = cp - e->word + 1;
14811472 do {
14821473 xwcsbuf_T valuebuf2;
14831474 xstrbuf_T ccbuf2;
Show on old repository browser