1 3b0f3d61 2020-01-22 neels /* Commandline diff utility to test diff implementations. */
3 3b0f3d61 2020-01-22 neels * Copyright (c) 2018 Martin Pieuchot
4 3b0f3d61 2020-01-22 neels * Copyright (c) 2020 Neels Hofmeyr <neels@hofmeyr.de>
6 3b0f3d61 2020-01-22 neels * Permission to use, copy, modify, and distribute this software for any
7 3b0f3d61 2020-01-22 neels * purpose with or without fee is hereby granted, provided that the above
8 3b0f3d61 2020-01-22 neels * copyright notice and this permission notice appear in all copies.
10 3b0f3d61 2020-01-22 neels * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 3b0f3d61 2020-01-22 neels * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 3b0f3d61 2020-01-22 neels * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 3b0f3d61 2020-01-22 neels * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 3b0f3d61 2020-01-22 neels * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 3b0f3d61 2020-01-22 neels * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 3b0f3d61 2020-01-22 neels * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 3b0f3d61 2020-01-22 neels #include <sys/mman.h>
20 3b0f3d61 2020-01-22 neels #include <sys/stat.h>
22 3b0f3d61 2020-01-22 neels #include <err.h>
23 3b0f3d61 2020-01-22 neels #include <fcntl.h>
24 3b0f3d61 2020-01-22 neels #include <inttypes.h>
25 3b0f3d61 2020-01-22 neels #include <stdio.h>
26 3b0f3d61 2020-01-22 neels #include <stdlib.h>
27 3b0f3d61 2020-01-22 neels #include <unistd.h>
29 3b0f3d61 2020-01-22 neels #ifdef __linux__
30 3b0f3d61 2020-01-22 neels /* stupid shims to compile and test on linux */
31 3b0f3d61 2020-01-22 neels #define __dead
33 3b0f3d61 2020-01-22 neels static const char *getprogname()
35 3b0f3d61 2020-01-22 neels return "diff";
39 3b0f3d61 2020-01-22 neels __dead void usage(void);
40 3b0f3d61 2020-01-22 neels int diffreg(char *, char *, int);
41 3b0f3d61 2020-01-22 neels char *mmapfile(const char *, struct stat *);
43 3b0f3d61 2020-01-22 neels __dead void
44 3b0f3d61 2020-01-22 neels usage(void)
46 3b0f3d61 2020-01-22 neels fprintf(stderr, "usage: %s file1 file2\n", getprogname());
51 3b0f3d61 2020-01-22 neels main(int argc, char *argv[])
55 3b0f3d61 2020-01-22 neels while ((ch = getopt(argc, argv, "")) != -1) {
56 3b0f3d61 2020-01-22 neels switch (ch) {
62 3b0f3d61 2020-01-22 neels argc -= optind;
63 3b0f3d61 2020-01-22 neels argv += optind;
65 3b0f3d61 2020-01-22 neels if (argc != 2)
68 3b0f3d61 2020-01-22 neels return diffreg(argv[0], argv[1], 0);
71 3b0f3d61 2020-01-22 neels #include <diff/diff_main.h>
72 3b0f3d61 2020-01-22 neels #include <diff/diff_output.h>
74 3b0f3d61 2020-01-22 neels const struct diff_algo_config myers, patience, myers_divide;
76 3b0f3d61 2020-01-22 neels const struct diff_algo_config myers = (struct diff_algo_config){
77 3b0f3d61 2020-01-22 neels .impl = diff_algo_myers,
78 3b0f3d61 2020-01-22 neels .permitted_state_size = 104 * sizeof(int),
79 3b0f3d61 2020-01-22 neels .fallback_algo = &patience,
82 3b0f3d61 2020-01-22 neels const struct diff_algo_config patience = (struct diff_algo_config){
83 3b0f3d61 2020-01-22 neels .impl = diff_algo_patience,
84 3b0f3d61 2020-01-22 neels .inner_algo = &patience, // After subdivision, do Patience again.
85 3b0f3d61 2020-01-22 neels .fallback_algo = &myers_divide, // If subdivision failed, do Myers Divide et Impera.
88 3b0f3d61 2020-01-22 neels const struct diff_algo_config myers_divide = (struct diff_algo_config){
89 3b0f3d61 2020-01-22 neels .impl = diff_algo_myers_divide,
90 3b0f3d61 2020-01-22 neels .inner_algo = &myers, // When division succeeded, start from the top.
91 3b0f3d61 2020-01-22 neels // (fallback_algo = NULL implies diff_algo_none).
94 3b0f3d61 2020-01-22 neels const struct diff_config diff_config = {
95 3b0f3d61 2020-01-22 neels .atomize_func = diff_atomize_text_by_line,
96 3b0f3d61 2020-01-22 neels .algo = &myers,
100 3b0f3d61 2020-01-22 neels diffreg(char *file1, char *file2, int flags)
102 3b0f3d61 2020-01-22 neels char *str1, *str2;
103 3b0f3d61 2020-01-22 neels struct stat st1, st2;
104 3b0f3d61 2020-01-22 neels struct diff_input_info info = {
105 3b0f3d61 2020-01-22 neels .left_path = file1,
106 3b0f3d61 2020-01-22 neels .right_path = file2,
109 3b0f3d61 2020-01-22 neels str1 = mmapfile(file1, &st1);
110 3b0f3d61 2020-01-22 neels str2 = mmapfile(file2, &st2);
112 81b40973 2020-01-22 neels diff_unidiff(stdout, &diff_config, &info, str1, st1.st_size, str2, st2.st_size, 3);
114 3b0f3d61 2020-01-22 neels munmap(str1, st1.st_size);
115 3b0f3d61 2020-01-22 neels munmap(str2, st2.st_size);
121 3b0f3d61 2020-01-22 neels mmapfile(const char *path, struct stat *st)
126 3b0f3d61 2020-01-22 neels fd = open(path, O_RDONLY);
127 3b0f3d61 2020-01-22 neels if (fd == -1)
128 3b0f3d61 2020-01-22 neels err(2, "%s", path);
130 3b0f3d61 2020-01-22 neels if (fstat(fd, st) == -1)
131 3b0f3d61 2020-01-22 neels err(2, "%s", path);
133 3b0f3d61 2020-01-22 neels if ((uintmax_t)st->st_size > SIZE_MAX)
134 3b0f3d61 2020-01-22 neels errx(2, "%s: file too big to fit memory", path);
136 3b0f3d61 2020-01-22 neels p = mmap(NULL, st->st_size, PROT_READ, MAP_PRIVATE, fd, 0);
137 3b0f3d61 2020-01-22 neels if (p == MAP_FAILED)
138 3b0f3d61 2020-01-22 neels err(2, "mmap");
140 3b0f3d61 2020-01-22 neels close(fd);