We know our mode entry in our tree objects should be 5 or 6 characters long. This change both enforces this fact and also unrolls the parsing of the information giving the compiler more room for optimization of the operations. Signed-off-by: Dan McGee <dpmcgee@xxxxxxxxx> --- tree-walk.c | 41 ++++++++++++++++++++++++++++++++++------- 1 files changed, 34 insertions(+), 7 deletions(-) diff --git a/tree-walk.c b/tree-walk.c index f386151..41383b0 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -9,16 +9,43 @@ static const char *get_mode(const char *str, unsigned int *modep) unsigned char c; unsigned int mode = 0; - if (*str == ' ') - return NULL; - - while ((c = *str++) != ' ') { - if (c < '0' || c > '7') - return NULL; + /* + * Unroll what looks like a loop since the bounds are + * well-known. There should be at least 5 and at most 6 + * characters available in any valid mode, as '40000' is the + * shortest while '160000' (S_IFGITLINK) is the longest. + */ + /* char 1 */ + c = *str++; + if (c < '0' || c > '7') return NULL; + mode = (mode << 3) + (c - '0'); + /* char 2 */ + c = *str++; + if (c < '0' || c > '7') return NULL; + mode = (mode << 3) + (c - '0'); + /* char 3 */ + c = *str++; + if (c < '0' || c > '7') return NULL; + mode = (mode << 3) + (c - '0'); + /* char 4 */ + c = *str++; + if (c < '0' || c > '7') return NULL; + mode = (mode << 3) + (c - '0'); + /* char 5 */ + c = *str++; + if (c < '0' || c > '7') return NULL; + mode = (mode << 3) + (c - '0'); + /* char 6, optional */ + if (*str != ' ') { + c = *str++; + if (c < '0' || c > '7') return NULL; mode = (mode << 3) + (c - '0'); } + + if (*str != ' ') return NULL; + *modep = mode; - return str; + return str + 1; } static void decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned long size) -- 1.7.4.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html