Pádraig Brady wrote: ... > Subject: [PATCH] realpath: remove extraneous '/' for --relative-to edge cases > > * src/realpath.c (path_common_prefix): Be consistent and > always include a leading '/' in the count returned. > (relpath): Account for the change in path_common_prefix() > and avoid outputting extra '/' chars in relative paths that > span the root dir. > * tests/misc/realpath: Add the two reported cases. > Reported by Mike Frysinger > --- > src/realpath.c | 16 +++++++++++----- > tests/misc/realpath | 11 ++++++++--- > 2 files changed, 19 insertions(+), 8 deletions(-) > > diff --git a/src/realpath.c b/src/realpath.c > index b39f7bf..8a07ab6 100644 > --- a/src/realpath.c > +++ b/src/realpath.c > @@ -136,7 +136,7 @@ path_common_prefix (const char *path1, const char *path2) > if (*path1 != *path2) > break; > if (*path1 == '/') > - ret = i; > + ret = i + 1; > path1++; > path2++; > i++; > @@ -171,11 +171,16 @@ relpath (const char *can_fname) > const char *relto_suffix = can_relative_to + common_index; > const char *fname_suffix = can_fname + common_index; > > + /* skip over extraneous '/'. */ > + if (*relto_suffix == '/') > + relto_suffix++; > + if (*fname_suffix == '/') > + fname_suffix++; > + > /* Replace remaining components of --relative-to with '..', to get > to a common directory. Then output the remainder of fname. */ > if (*relto_suffix) > { > - ++relto_suffix; > printf ("%s", ".."); > for (; *relto_suffix; ++relto_suffix) > { > @@ -183,14 +188,15 @@ relpath (const char *can_fname) > printf ("%s", "/.."); > } > > - printf ("%s", fname_suffix); > + if (*fname_suffix) > + printf ("/%s", fname_suffix); > } > else > { > if (*fname_suffix) > - printf ("%s", ++fname_suffix); > + printf ("%s", fname_suffix); > else > - printf ("%c", '.'); > + putchar ('.'); > }
That looks fine and passes existing and new tests (of course). Thanks. On an unrelated note, have you considered removing the remaining printf uses in favor of fputc/fputs, since they're all trivial?