| 152 | } |
| 153 | |
| 154 | int cbm_parse_hunks(const char *output, cbm_changed_hunk_t *out, int max_out) { |
| 155 | if (!output || !out || max_out <= 0) { |
| 156 | return 0; |
| 157 | } |
| 158 | |
| 159 | int count = 0; |
| 160 | char current_file[CBM_SZ_512] = {0}; |
| 161 | const char *line = output; |
| 162 | |
| 163 | while (*line && count < max_out) { |
| 164 | const char *eol = strchr(line, '\n'); |
| 165 | size_t line_len = eol ? (size_t)(eol - line) : strlen(line); |
| 166 | |
| 167 | if (line_len == 0) { |
| 168 | line = eol ? eol + SKIP_ONE : line + line_len; |
| 169 | continue; |
| 170 | } |
| 171 | |
| 172 | if (line_len > GD_PLUS_PREFIX && strncmp(line, "+++ b/", SLEN("+++ b/")) == 0) { |
| 173 | size_t flen = line_len - GD_PLUS_PREFIX; |
| 174 | if (flen >= sizeof(current_file)) { |
| 175 | flen = sizeof(current_file) - SKIP_ONE; |
| 176 | } |
| 177 | memcpy(current_file, line + 6, flen); |
| 178 | current_file[flen] = '\0'; |
| 179 | } else if (line_len >= PAIR_LEN && line[0] == '@' && line[GD_STATUS_IDX] == '@' && |
| 180 | current_file[0]) { |
| 181 | cbm_changed_hunk_t h; |
| 182 | if (parse_hunk_line(line, line_len, current_file, &h)) { |
| 183 | out[count++] = h; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | line = eol ? eol + SKIP_ONE : line + line_len; |
| 188 | } |
| 189 | return count; |
| 190 | } |
no test coverage detected