long xdl_atol(char const *str, char const **next) { long val, base; char const *top; for (top = str; XDL_ISDIGIT(*top); top++); if (next) *next = top; for (val = 0, base = 1, top--; top >= str; top--, base *= 10) val += base * (long)(*top - '0'); return val; }
static int xdl_load_hunk_info(char const *line, long size, hunkinfo_t *hki) { char const *next; if (memcmp(line, "@@ -", 4)) return -1; line += 4; size -= 4; for (; size && !XDL_ISDIGIT(*line); size--, line++); if (!size || !XDL_ISDIGIT(*line)) return -1; hki->s1 = xdl_atol(line, &next) - 1; size -= next - line; line = next; for (; size && !XDL_ISDIGIT(*line); size--, line++); if (!size || !XDL_ISDIGIT(*line)) return -1; hki->c1 = xdl_atol(line, &next); size -= next - line; line = next; for (; size && !XDL_ISDIGIT(*line); size--, line++); if (!size || !XDL_ISDIGIT(*line)) return -1; hki->s2 = xdl_atol(line, &next) - 1; size -= next - line; line = next; for (; size && !XDL_ISDIGIT(*line); size--, line++); if (!size || !XDL_ISDIGIT(*line)) return -1; hki->c2 = xdl_atol(line, &next); size -= next - line; line = next; return 0; }
static int xdl_load_hunk_info(char const *line, long size, hunkinfo_t *hki) { char const *next; /* * The diff header format should be: * * @@ -OP,OC +NP,NC @@ * * Unfortunately some software avoid to emit OP or/and NP in case * of not existing old or new file (it should be mitted as zero). * We need to handle both syntaxes. */ if (memcmp(line, "@@ -", 4)) return -1; line += 4; size -= 4; if (!size || !XDL_ISDIGIT(*line)) return -1; hki->s1 = xdl_atol(line, &next); size -= next - line; line = next; if (!size) return -1; if (*line == ',') { size--, line++; if (!size || !XDL_ISDIGIT(*line)) return -1; hki->c1 = xdl_atol(line, &next); size -= next - line; line = next; if (!size || *line != ' ') return -1; size--, line++; } else if (*line == ' ') { size--, line++; hki->c1 = hki->s1; hki->s1 = 0; } else return -1; if (!size || *line != '+') return -1; size--, line++; if (!size || !XDL_ISDIGIT(*line)) return -1; hki->s2 = xdl_atol(line, &next); size -= next - line; line = next; if (!size) return -1; if (*line == ',') { size--, line++; if (!size || !XDL_ISDIGIT(*line)) return -1; hki->c2 = xdl_atol(line, &next); size -= next - line; line = next; if (!size || *line != ' ') return -1; size--, line++; } else if (*line == ' ') { size--, line++; hki->c2 = hki->s2; hki->s2 = 0; } else return -1; if (size < 2 || memcmp(line, "@@", 2) != 0) return -1; /* * We start from zero, so decrement by one unless it's the special position * '0' inside the unified diff (new or deleted file). */ if (hki->s1 > 0 && hki->c1 > 0) hki->s1--; if (hki->s2 > 0 && hki->c2 > 0) hki->s2--; return 0; }