commit - 80b447444e135e42383c31acf4e452fefbd6ecad
commit + 3e6cba3a54789e151b37851eef9cdccc4180ae40
blob - 023a35d7013c43a90d6d1d7f6cc55c2b5834c492
blob + cbf36375d4d7bd0e742b3785518f45c59f5444cf
--- diff/diff.c
+++ diff/diff.c
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <diff/diff_main.h>
int
main(int argc, char *argv[])
{
- int ch;
+ int ch, rc;
while ((ch = getopt(argc, argv, "p")) != -1) {
switch (ch) {
if (argc != 2)
usage();
- return diffreg(argv[0], argv[1], 0);
+ rc = diffreg(argv[0], argv[1], 0);
+ if (rc != DIFF_RC_OK) {
+ fprintf(stderr, "diff: %s\n", strerror(rc));
+ return 1;
+ }
+ return 0;
}
const struct diff_algo_config myers_then_patience;
.right_path = file2,
};
struct diff_result *result;
- enum diff_rc rc;
+ int rc;
const struct diff_config *cfg;
cfg = do_patience ? &diff_config_patience : &diff_config;
blob - ae582411bdb59d5b3c89163d9a81c5b48fab369d
blob + 00cef1ebed7779aaad54a20ad936c4914a78ec4b
--- include/diff/diff_main.h
+++ include/diff/diff_main.h
}
/* List of all possible return codes of a diff invocation. */
-enum diff_rc {
- DIFF_RC_USE_DIFF_ALGO_FALLBACK = -1,
- DIFF_RC_OK = 0,
- DIFF_RC_ENOTSUP = ENOTSUP,
- DIFF_RC_ENOMEM = ENOMEM,
- DIFF_RC_EINVAL = EINVAL,
-};
+#define DIFF_RC_USE_DIFF_ALGO_FALLBACK -1
+#define DIFF_RC_OK 0
+/* Any positive return values are errno values from sys/errno.h */
struct diff_data;
#define DIFF_RESULT_ALLOC_BLOCKSIZE 128
struct diff_result {
- enum diff_rc rc;
+ int rc;
struct diff_data left;
struct diff_data right;
diff_chunk_arraylist_t chunks;
* right: struct diff_data with right->data and right->len already set up, and
* right->atoms to be created.
*/
-typedef enum diff_rc (*diff_atomize_func_t)(void *func_data,
+typedef int (*diff_atomize_func_t)(void *func_data,
struct diff_data *left,
struct diff_data *right);
-extern enum diff_rc diff_atomize_text_by_line(void *func_data,
+extern int diff_atomize_text_by_line(void *func_data,
struct diff_data *left,
struct diff_data *right);
struct diff_algo_config;
-typedef enum diff_rc (*diff_algo_impl_t)(
+typedef int (*diff_algo_impl_t)(
const struct diff_algo_config *algo_config, struct diff_state *state);
/* Form a result with all left-side removed and all right-side added, i.e. no
* actual diff algorithm involved. */
-enum diff_rc diff_algo_none(const struct diff_algo_config *algo_config,
+int diff_algo_none(const struct diff_algo_config *algo_config,
struct diff_state *state);
/* Myers Diff tracing from the start all the way through to the end, requiring
* quadratic amounts of memory. This can fail if the required space surpasses
* algo_config->permitted_state_size. */
-extern enum diff_rc diff_algo_myers(const struct diff_algo_config *algo_config,
+extern int diff_algo_myers(const struct diff_algo_config *algo_config,
struct diff_state *state);
/* Myers "Divide et Impera": tracing forwards from the start and backwards from
* the end to find a midpoint that divides the problem into smaller chunks.
* Requires only linear amounts of memory. */
-extern enum diff_rc diff_algo_myers_divide(
+extern int diff_algo_myers_divide(
const struct diff_algo_config *algo_config, struct diff_state *state);
/* Patience Diff algorithm, which divides a larger diff into smaller chunks. For
* very specific scenarios, it may lead to a complete diff result by itself, but
* needs a fallback algo to solve chunks that don't have common-unique atoms. */
-extern enum diff_rc diff_algo_patience(
+extern int diff_algo_patience(
const struct diff_algo_config *algo_config, struct diff_state *state);
/* Diff algorithms to use, possibly nested. For example:
blob - b36e18bec3150b1185bd70c72a07067b0f7799bc
blob + 0b28108d3fcf55aa81c9464272b99a224fc722da
--- include/diff/diff_output.h
+++ include/diff/diff_output.h
const char *right_path;
};
-enum diff_rc diff_output_plain(FILE *dest, const struct diff_input_info *info,
+int diff_output_plain(FILE *dest, const struct diff_input_info *info,
const struct diff_result *result);
-enum diff_rc diff_output_unidiff(FILE *dest, const struct diff_input_info *info,
+int diff_output_unidiff(FILE *dest, const struct diff_input_info *info,
const struct diff_result *result,
unsigned int context_lines);
-enum diff_rc diff_output_info(FILE *dest, const struct diff_input_info *info);
+int diff_output_info(FILE *dest, const struct diff_input_info *info);
void diff_output_lines(FILE *dest, const char *prefix,
struct diff_atom *start_atom, unsigned int count);
blob - 47d5d29a32cf5deb5d6838c66924649c60606e24
blob + 02d2c8c9384587c4564891250aaa82438fb44072
--- lib/diff_atomize_text.c
+++ lib/diff_atomize_text.c
/* Record the found line as diff atom */
ARRAYLIST_ADD(atom, d->atoms);
if (!atom)
- return DIFF_RC_ENOMEM;
+ return ENOMEM;
*atom = (struct diff_atom){
.d = d,
struct diff_atom *atom;
ARRAYLIST_ADD(atom, d->atoms);
if (!atom)
- return DIFF_RC_ENOMEM;
+ return ENOMEM;
*atom = (struct diff_atom){
.d = d,
return diff_data_atomize_text_lines_mmap(d);
}
-enum diff_rc
+int
diff_atomize_text_by_line(void *func_data, struct diff_data *left,
struct diff_data *right)
{
- enum diff_rc rc;
+ int rc;
rc = diff_data_atomize_text_lines(left);
if (rc != DIFF_RC_OK)
return rc;
blob - 3e7d4492a6ef544e6df8c1c3ec43b42fa2f0d3e8
blob + fa1314409c7f4b958f1c231fe6531512521c9add
--- lib/diff_main.c
+++ lib/diff_main.c
ARRAYLIST_FREE(diff_data->atoms);
}
-enum diff_rc
+int
diff_algo_none(const struct diff_algo_config *algo_config,
struct diff_state *state)
{
equal_atoms,
&state->right.atoms.head[0],
equal_atoms))
- return DIFF_RC_ENOMEM;
+ return ENOMEM;
}
/* Add a "minus" chunk with all lines from the left. */
&state->left.atoms.head[equal_atoms],
state->left.atoms.len - equal_atoms,
NULL, 0))
- return DIFF_RC_ENOMEM;
+ return ENOMEM;
}
/* Add a "plus" chunk with all lines from the right. */
NULL, 0,
&state->right.atoms.head[equal_atoms],
state->right.atoms.len - equal_atoms))
- return DIFF_RC_ENOMEM;
+ return ENOMEM;
}
return DIFF_RC_OK;
}
-enum diff_rc
+int
diff_run_algo(const struct diff_algo_config *algo_config,
struct diff_state *state)
{
- enum diff_rc rc;
+ int rc;
ARRAYLIST_FREE(state->temp_result);
if (!algo_config || !algo_config->impl
struct diff_chunk *final_c;
ARRAYLIST_ADD(final_c, state->result->chunks);
if (!final_c) {
- rc = DIFF_RC_ENOMEM;
+ rc = ENOMEM;
goto return_rc;
}
*final_c = *c;
diff_data_init_root(&result->right, right_fd, right_data, right_len);
if (!config->atomize_func) {
- result->rc = DIFF_RC_EINVAL;
+ result->rc = EINVAL;
return result;
}
blob - 4ab3f306b594b78d50eb8182ebef5b69b1ad2870
blob + 9c3cc47bf30ab96392aaa4797b567bcf7e3d3722
--- lib/diff_myers.c
+++ lib/diff_myers.c
/* Myers "Divide et Impera": tracing forwards from the start and backwards from
* the end to find a midpoint that divides the problem into smaller chunks.
* Requires only linear amounts of memory. */
-enum diff_rc
+int
diff_algo_myers_divide(const struct diff_algo_config *algo_config,
struct diff_state *state)
{
- enum diff_rc rc = DIFF_RC_ENOMEM;
+ int rc = ENOMEM;
struct diff_data *left = &state->left;
struct diff_data *right = &state->right;
size_t kd_buf_size = kd_len << 1;
int *kd_buf = reallocarray(NULL, kd_buf_size, sizeof(int));
if (!kd_buf)
- return DIFF_RC_ENOMEM;
+ return ENOMEM;
int i;
for (i = 0; i < kd_buf_size; i++)
kd_buf[i] = -1;
/* Myers Diff tracing from the start all the way through to the end, requiring
* quadratic amounts of memory. This can fail if the required space surpasses
* algo_config->permitted_state_size. */
-enum diff_rc
+int
diff_algo_myers(const struct diff_algo_config *algo_config,
struct diff_state *state)
{
/* do a diff_divide_myers_forward() without a _backward(), so that it
* walks forward across the entire files to reach the end. Keep each
* run's state, and do a final backtrace. */
- enum diff_rc rc = DIFF_RC_ENOMEM;
+ int rc = ENOMEM;
struct diff_data *left = &state->left;
struct diff_data *right = &state->right;
int *kd_buf = reallocarray(NULL, kd_buf_size, sizeof(int));
if (!kd_buf)
- return DIFF_RC_ENOMEM;
+ return ENOMEM;
int i;
for (i = 0; i < kd_buf_size; i++)
kd_buf[i] = -1;
struct diff_atom *right_atom = &right->atoms.head[y];
int right_section_len = next_y - y;
- rc = DIFF_RC_ENOMEM;
+ rc = ENOMEM;
if (left_section_len && right_section_len) {
/* This must be a snake slide.
* Snake slides have a straight line leading into them
blob - 67effa60cee65ccf37fdd85d42607d9456e75e06
blob + 55255ed4ab1e8d1471c7ba2f5f1f12a19d3a5582
--- lib/diff_output_plain.c
+++ lib/diff_output_plain.c
#include <diff/diff_output.h>
-enum diff_rc
+int
diff_output_plain(FILE *dest, const struct diff_input_info *info,
const struct diff_result *result)
{
if (!result)
- return DIFF_RC_EINVAL;
+ return EINVAL;
if (result->rc != DIFF_RC_OK)
return result->rc;
blob - 55f348231b92db3f47e8600ae6c5bf0799c23725
blob + 76e4da190f34bc2e1083a4ae61146ba0841feb83
--- lib/diff_output_unidiff.c
+++ lib/diff_output_unidiff.c
cc->left.end - chunk_end_line);
}
-enum diff_rc
+int
diff_output_unidiff(FILE *dest, const struct diff_input_info *info,
const struct diff_result *result,
unsigned int context_lines)
{
if (!result)
- return DIFF_RC_EINVAL;
+ return EINVAL;
if (result->rc != DIFF_RC_OK)
return result->rc;
blob - 1692de85f77fcbbdf88845d243be3b335741190c
blob + 624b58c23e986a0853e87eca86d14cdd6141a3d1
--- lib/diff_patience.c
+++ lib/diff_patience.c
* See https://bramcohen.livejournal.com/73318.html and, for a much more
* detailed explanation,
* https://blog.jcoglan.com/2017/09/19/the-patience-diff-algorithm/ */
-enum diff_rc
+int
diff_algo_patience(const struct diff_algo_config *algo_config,
struct diff_state *state)
{
- enum diff_rc rc = DIFF_RC_ENOMEM;
+ int rc = ENOMEM;
struct diff_data *left = &state->left;
struct diff_data *right = &state->right;