git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Implementing diff, was Re: git 0.99.7b doesn't build on Cygwin

From
DLDavide Libenzi <davidel@xmailserver.org>
Date
Sep 25, 2005, 19:16 UTC
Message-ID
<Pine.LNX.4.63.0509251205230.23415@localhost.localdomain>
In-Reply-To
<Pine.LNX.4.58.0509250959540.3308@g5.osdl.org>
On Sun, 25 Sep 2005, Linus Torvalds wrote:
Show 11 quoted lines
> On Sun, 25 Sep 2005, Davide Libenzi wrote:
>>
>> What you'd have to do, if you chose to use diffutils stuff, is to
>> transform the main() of diff in diff_main(), use setjmp/longjmp to capture
>> its exit()s, and make it use a proper allocator (if you want to avoid
>> leaks upon aborts).
>
> I'd love to use libxdiff instead since you say it can do it, but quite
> frankly, the man-page didn't much help me. Do you have an example of how
> to generate a uni-diff with it? Something that mortal men can read and say
> "oh"?

Ahh, you looked at the docs. Don't do that ;) Take a look at the test/xdiff_test.c for an example on how to use its most important APIs. There is also a regression test (xregression) that create random files, renadomly changes them, and then try that (A-B)+B=A and (B-A)+A=B (for both text and binary). I'm dropping inline an example on how to text-diff ...

- Davide

#include "xmacros.h" #include "xdiff.h"

#define XDLT_STD_BLKSIZE (1024 * 8)
static int xdlt_load_mmfile(char const *fname, mmfile_t *mf, int binmode) {
         char cc;
         int fd;
         long size, bsize;
         char *blk;
         if (xdl_init_mmfile(mf, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0) {
                 return -1;
         }
         if ((fd = open(fname, O_RDONLY)) == -1) {
                 perror(fname);
                 xdl_free_mmfile(mf);
                 return -1;
         }
         if ((size = bsize = lseek(fd, 0, SEEK_END)) > 0 && !binmode) {
                 if (lseek(fd, -1, SEEK_END) != (off_t) -1 &&
                     read(fd, &cc, 1) && cc != '\n')
                         bsize++;
         }
         lseek(fd, 0, SEEK_SET);
         if (!(blk = (char *) xdl_mmfile_writeallocate(mf, bsize))) {
                 xdl_free_mmfile(mf);
                 close(fd);
                 return -1;
         }
         if (read(fd, blk, (size_t) size) != (size_t) size) {
                 perror(fname);
                 xdl_free_mmfile(mf);
                 close(fd);
                 return -1;
         }
         close(fd);
         if (bsize > size)
                 blk[size] = '\n';
         return 0;
}
static int xdlt_outf(void *priv, mmbuffer_t *mb, int nbuf) {
         int i;
         for (i = 0; i < nbuf; i++)
                 if (!fwrite(mb[i].ptr, mb[i].size, 1, (FILE *) priv))
                         return -1;
         return 0;
}
static void *wrap_malloc(void *priv, unsigned int size) {
         return malloc(size);
}
static void wrap_free(void *priv, void *ptr) {
         free(ptr);
}
static void *wrap_realloc(void *priv, void *ptr, unsigned int size) {
         return realloc(ptr, size);
}
int sample_textdiff(char const *pre, char const *post, FILE *outf) {
         int error;
         memallocator_t malt;
         mmfile_t mf1, mf2;
         xpparam_t xpp;
         xdemitconf_t xecfg;
         xdemitcb_t ecb;
         malt.priv = NULL;
         malt.malloc = wrap_malloc;
         malt.free = wrap_free;
         malt.realloc = wrap_realloc;
         xdl_set_allocator(&malt);
         if (xdlt_load_mmfile(pre, &mf1, 0) < 0)
                 return -1;
         if (xdlt_load_mmfile(post, &mf2, 0) < 0) {
                 xdl_free_mmfile(&mf1);
                 return -1;
         }
         xpp.flags = 0;
         xecfg.ctxlen = 3;
         ecb.priv = outf;
         ecb.outf = xdlt_outf;
         error = xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
         xdl_free_mmfile(&mf2);
         xdl_free_mmfile(&mf1);
         return error;
}
Previous: Linus TorvaldsNext: Johannes Schindelin
Message 12 of 38 in “git 0.99.7b doesn't build on Cygwin”
  1. Peter TB BrettSep 23, 2005
  2. Johannes SchindelinSep 23, 2005
  3. Peter TB BrettSep 23, 2005
  4. Martin LanghoffSep 23, 2005
  5. Petr BaudisSep 23, 2005
  6. Linus TorvaldsSep 24, 2005
  7. Linus TorvaldsSep 24, 2005
  8. Junio C HamanoSep 25, 2005
  9. Implementing diff, was Re: git 0.99.7b doesn't build on CygwinJohannes Schindelin, Sep 25, 2005
  10. Davide LibenziSep 25, 2005
  11. Linus TorvaldsSep 25, 2005
  12. Davide LibenziSep 25, 2005
  13. Johannes SchindelinSep 24, 2005
  14. Linus TorvaldsSep 24, 2005
  15. Junio C HamanoSep 24, 2005
  16. Davide LibenziSep 24, 2005
  17. Linus TorvaldsSep 24, 2005
  18. Davide LibenziSep 24, 2005
  19. Junio C HamanoSep 24, 2005
  20. Davide LibenziSep 24, 2005
  21. Junio C HamanoSep 24, 2005
  22. Junio C HamanoSep 24, 2005
  23. Davide LibenziSep 24, 2005
  24. Linus TorvaldsSep 24, 2005
  25. Linus TorvaldsSep 24, 2005
  26. Linus TorvaldsSep 25, 2005
  27. Jon LoeligerSep 26, 2005
  28. Junio C HamanoSep 26, 2005
  29. Davide LibenziSep 24, 2005
  30. Giuseppe BilottaSep 25, 2005
  31. Junio C HamanoSep 26, 2005
  32. Davide LibenziSep 26, 2005
  33. Giuseppe BilottaSep 26, 2005
  34. H. Peter AnvinSep 26, 2005
  35. Davide LibenziSep 26, 2005
  36. H. Peter AnvinSep 26, 2005
  37. Daniel BarkalowSep 25, 2005
  38. Davide LibenziSep 24, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.