diff -Naur patchtool-0.3/cmd_list.c patchtool-0.4/cmd_list.c --- patchtool-0.3/cmd_list.c 2005-03-28 19:06:54.000000000 +0000 +++ patchtool-0.4/cmd_list.c 2005-04-12 00:17:38.000000000 +0000 @@ -31,37 +31,45 @@ : 'E'; } -static void process_part(struct part *part, int strip_level, int detail_level) +static char *mk_string_strip(char *str, int strip_level) { char *ptr; - char c; - int i, ret, stats[3]; - - ptr = part->filename[1]; - for (i = 0; i < strip_level; i++) { + int i; + + for (i = 0, ptr = str; i < strip_level; i++) { char *ptr2 = strchr(ptr, '/'); if (ptr2) { ptr = ptr2; ptr++; } } - + return ptr; +} + +static void process_part(struct part *part, int strip_level, int detail_level) +{ + char *ptr; + char c; + int ret, stats[3]; + + ret = part_status(part, NULL); + ptr = (ret == PART_DEL) + ? mk_string_strip(part->filename[0], strip_level) + : mk_string_strip(part->filename[1], strip_level); + switch (detail_level) { case 0: printf("%s\n", ptr); break; case 1: - ret = part_status(part, NULL); c = status_get_char(ret); printf("%c\t%s\n", c, ptr); break; case 2: - ret = part_status(part, NULL); c = status_get_char(ret); printf("%c\t%d\t%s\n", c, part->nb_hunks, ptr); break; default: - ret = part_status(part, stats); c = status_get_char(ret); printf("%c\t%d\t-%d\t+%d\t%s\n", c, part->nb_hunks, stats[LINE_DEL], stats[LINE_ADD], ptr); diff -Naur patchtool-0.3/parse.c patchtool-0.4/parse.c --- patchtool-0.3/parse.c 2005-03-31 22:11:23.000000000 +0000 +++ patchtool-0.4/parse.c 2005-04-12 00:12:09.000000000 +0000 @@ -18,6 +18,16 @@ #include #include "patch.h" +static inline char *parser_next_line(char *tmp) +{ + if (tmp && *tmp) { + tmp = strchr(tmp, '\n'); + if (tmp) + tmp++; + } + return tmp; +} + static char *part_get_filename(char *tmp) { char *str, *new; @@ -36,36 +46,65 @@ } /* processing part */ -static char *parse_hunk(struct patch *p, struct part *part, char *tmp) +static char *parse_hunk_header(struct patch *p, struct part *part, + struct hunk *hunk, char *tmp) { - struct hunk *hunk; int ret; - int line_del, line_add, line_space; - if (!tmp || !*tmp) - return NULL; if (strncmp(tmp, "@@ ", 2) != 0) { fprintf(stderr, "error: hunk problem\n"); - return tmp + 1; + return parser_next_line(tmp); } - - hunk = hunk_alloc(); - if (!hunk) - return tmp; - - hunk->start = tmp; + //printf("header: \"%.20s\"\n", tmp); ret = sscanf(tmp, "@@ -%d,%d +%d,%d @@", &hunk->off[0], &hunk->line[0], &hunk->off[1], &hunk->line[1]); if (ret != 4) { - fprintf(stderr, "error: not enough arg in hunk: \"\"%.30s\"\"\n", tmp); - return tmp + 1; + hunk->off[1] = 0; + ret = sscanf(tmp, "@@ -%d,%d +%d @@", &hunk->off[0], &hunk->line[0], + &hunk->line[1]); + if (ret != 3) { + ret = sscanf(tmp, "@@ -%d +%d,%d @@", &hunk->off[0], + &hunk->off[1], &hunk->line[1]); + if (ret != 3) { + fprintf(stderr, "error: not enough arg in hunk: \"\"%.30s\"\"\n", tmp); + return parser_next_line(tmp); + } + hunk->off[0] = hunk->line[0] = -1; + return parser_next_line(tmp); + } } - - tmp = strchr(tmp, '\n'); - tmp++; - hunk->data = tmp; + return parser_next_line(tmp); +} + +static char *parse_hunk_unvalid(struct patch *p, struct part *part, + struct hunk *hunk, char *tmp) +{ + int line_del, line_add, line_space; + + line_del = line_add = line_space = 0; + while (tmp && *tmp) { + if (strncmp(tmp, "@@ ", 3) == 0) + break; + + switch (*tmp) { + case '-': line_del++; break; + case '+': line_add++; break; + case ' ': line_space++; break; + } + tmp = parser_next_line(tmp); + } + hunk->tlines[LINE_UNM] = line_space; + hunk->tlines[LINE_ADD] = line_add; + hunk->tlines[LINE_DEL] = line_del; + return tmp; +} + +static char *parse_hunk_valid(struct patch *p, struct part *part, + struct hunk *hunk, char *tmp) +{ + int line_del, line_add, line_space; line_del = line_add = line_space = 0; @@ -82,17 +121,37 @@ case '-': line_del++; break; case '+': line_add++; break; case ' ': line_space++; break; - default: fprintf(stderr, "error: something wrong happen\n"); + case '\\': break; + default: fprintf(stderr, "error: something wrong happen: %.20s\n", tmp); } - tmp = strchr(tmp, '\n'); - if (tmp) - tmp++; + tmp = parser_next_line(tmp); } hunk->tlines[LINE_UNM] = line_space; hunk->tlines[LINE_ADD] = line_add; hunk->tlines[LINE_DEL] = line_del; + return tmp; +} + +static char *parse_hunk(struct patch *p, struct part *part, char *tmp) +{ + struct hunk *hunk; + + if (!tmp || !*tmp) + return NULL; + + hunk = hunk_alloc(); + if (!hunk) + return tmp; + + hunk->start = tmp; + tmp = parse_hunk_header(p, part, hunk, tmp); + hunk->data = tmp; + + tmp = (hunk->off[0] == -1 && hunk->line[0] == -1) + ? parse_hunk_unvalid(p, part, hunk, tmp) + : parse_hunk_valid(p, part, hunk, tmp); hunk->end = tmp; part_add_hunk(part, hunk); @@ -116,8 +175,7 @@ } part->filename[0] = part_get_filename(tmp + 4); - tmp = strchr(tmp, '\n'); - tmp++; + tmp = parser_next_line(tmp); if (strncmp(tmp, "+++ ", 4) != 0) { fprintf(stderr, "error: header problem\n"); @@ -125,8 +183,7 @@ } part->filename[1] = part_get_filename(tmp + 4); - tmp = strchr(tmp, '\n'); - tmp++; + tmp = parser_next_line(tmp); while (tmp && *tmp && (strncmp(tmp, "@@ ", 3) == 0)) tmp = parse_hunk(p, part, tmp); @@ -154,12 +211,9 @@ break; } - if (strncmp(tmp, "--- ", 4) == 0) - tmp = parse_part(p, tmp); - else { - tmp = strchr(tmp, '\n'); - if (tmp) tmp++; - } + tmp = (strncmp(tmp, "--- ", 4) == 0) + ? parse_part(p, tmp) + : parser_next_line(tmp); } return p; diff -Naur patchtool-0.3/patchtool.c patchtool-0.4/patchtool.c --- patchtool-0.3/patchtool.c 2005-04-11 00:00:20.000000000 +0000 +++ patchtool-0.4/patchtool.c 2005-04-11 23:22:53.000000000 +0000 @@ -26,14 +26,10 @@ if (argc < 2) usage(NULL); - if (strcmp(argv[1], "split") == 0) - cmd_split(argc - 2, &argv[2]); - else if (strcmp(argv[1], "ls") == 0 || strcmp(argv[1], "list") == 0) - cmd_list(argc - 2, &argv[2]); - else if (strcmp(argv[1], "sparse") == 0) - cmd_sparse(argc - 2, &argv[2]); - else if (strcmp(argv[1], "get") == 0) - cmd_get(argc - 2, &argv[2]); + match_cmd(split) + else match_cmd(list) + else match_cmd(sparse) + else match_cmd(get) else usage(NULL); return 0;