This thread contains a patchset. You're looking at the original emails,
but you may wish to use the patch review UI.
Review patch
5
3
[PATCH harec] Print paths relative to cwd on errors
Signed-off-by: Max Schillinger <max@mxsr.de>
---
Currently, error locations are printed relative to dependencies' root
directories. This can't be processed easily automatically (p.e. by vim's
:make). Also see
<https://lists.sr.ht/~sircmpwn/hare-users/%3CCWQ9IWWELP77.2TIL8M24VF5F5%40mxsr.de%3E>.
include/util.h | 2 ++
src/main.c | 11 ++ ---------
src/util.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/include/util.h b/include/util.h
index 42127c4..b29cc3e 100644
--- a/include/util.h
+++ b/include/util.h
@@ -28,6 +28,8 @@ char *xstrdup(const char *s);
char *gen_name(int *id, const char *fmt);
+ const char *relpath(const char *dir);
+
void errline(struct location loc);
#endif
diff --git a/src/main.c b/src/main.c
index 313e462..62d2667 100644
--- a/src/main.c
+++ b/src/main.c
@@ -70,7 +70,6 @@ main(int argc, char *argv[])
{
const char *output = NULL, *typedefs = NULL;
const char *target = DEFAULT_TARGET;
- const char *modpath = NULL;
const char *mainsym = "main";
bool is_test = false;
struct unit unit = {0};
@@ -91,7 +90,6 @@ main(int argc, char *argv[])
usage(argv[0]);
return EXIT_SUCCESS;
case 'M':
- modpath = optarg;
break;
case 'm':
mainsym = optarg;
@@ -144,13 +142,8 @@ main(int argc, char *argv[])
memcpy((char **)sources + 1, argv + optind, sizeof(char **) * nsources);
sources[0] = "<unknown>";
- if (modpath) {
- size_t modlen = strlen(modpath);
- for (size_t i = 1; i <= nsources; i++) {
- if (strncmp(sources[i], modpath, modlen) == 0) {
- sources[i] += modlen;
- }
- }
+ for (size_t i = 1; i <= nsources; i++) {
+ sources[i] = relpath(sources[i]);
}
for (size_t i = 0; i < nsources; ++i) {
diff --git a/src/util.c b/src/util.c
index c3691bb..fd62264 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,3 +1,4 @@
+ #include <limits.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <stdbool.h>
@@ -113,6 +114,49 @@ gen_name(int *id, const char *fmt)
return str;
}
+ const char *
+ relpath(const char *dir)
+ {
+ if (dir[0] != '/') {
+ return dir;
+ }
+ char cwd[PATH_MAX];
+ if (getcwd(cwd, sizeof(cwd)) == NULL) {
+ return dir;
+ }
+ size_t cwdlen = strlen(cwd);
+ if (strncmp(dir, cwd, cwdlen) == 0) {
+ return dir + cwdlen + 1;
+ }
+ int common_prefix = -1;
+ for (int i = 0; dir[i] != '\0' && dir[i] == cwd[i]; i++) {
+ if (dir[i] == '/') {
+ common_prefix = i;
+ }
+ }
+ if (common_prefix == -1) {
+ return dir;
+ }
+ int dirs_up = 1;
+ for (int i = common_prefix + 1; cwd[i] != '\0'; i++) {
+ if (cwd[i] == '/') {
+ dirs_up++;
+ }
+ }
+ const char *unique_part = dir + common_prefix + 1;
+ char dir_up[] = "../";
+ size_t l_dir_up = strlen(dir_up);
+ size_t l_reldir = dirs_up * l_dir_up + strlen(unique_part) + 1;
+ char *reldir = xcalloc(1, l_reldir);
+ int i = 0;
+ for (int d = 0; d < dirs_up; d++) {
+ strcpy(reldir + i, dir_up);
+ i += l_dir_up;
+ }
+ strcpy(reldir + i, unique_part);
+ return reldir;
+ }
+
void
errline(struct location loc)
{
--
2.43.0
[harec/patches] build success
comments inline
On Sat, Nov 25, 2023 at 08:10:59PM +0100, Max Schillinger wrote:
> Signed-off-by: Max Schillinger <max@mxsr.de >
> ---
> Currently, error locations are printed relative to dependencies' root
> directories. This can't be processed easily automatically (p.e. by vim's
> :make). Also see
> <https://lists.sr.ht/~sircmpwn/hare-users/%3CCWQ9IWWELP77.2TIL8M24VF5F5%40mxsr.de%3E >.
>
> include/util.h | 2 ++
> src/main.c | 11 ++---------
> src/util.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 48 insertions(+), 9 deletions(-)
>
> diff --git a/include/util.h b/include/util.h
> index 42127c4..b29cc3e 100644
> --- a/include/util.h
> +++ b/include/util.h
> @@ -28,6 +28,8 @@ char *xstrdup(const char *s);
>
> char *gen_name(int *id, const char *fmt);
>
> +const char *relpath(const char *dir);
> +
> void errline(struct location loc);
>
> #endif
> diff --git a/src/main.c b/src/main.c
> index 313e462..62d2667 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -70,7 +70,6 @@ main(int argc, char *argv[])
> {
> const char *output = NULL, *typedefs = NULL;
> const char *target = DEFAULT_TARGET;
> - const char *modpath = NULL;
> const char *mainsym = "main";
> bool is_test = false;
> struct unit unit = {0};
> @@ -91,7 +90,6 @@ main(int argc, char *argv[])
> usage(argv[0]);
> return EXIT_SUCCESS;
> case 'M':
> - modpath = optarg;
> break;
> case 'm':
> mainsym = optarg;
> @@ -144,13 +142,8 @@ main(int argc, char *argv[])
> memcpy((char **)sources + 1, argv + optind, sizeof(char **) * nsources);
> sources[0] = "<unknown>";
>
> - if (modpath) {
> - size_t modlen = strlen(modpath);
> - for (size_t i = 1; i <= nsources; i++) {
> - if (strncmp(sources[i], modpath, modlen) == 0) {
> - sources[i] += modlen;
> - }
> - }
> + for (size_t i = 1; i <= nsources; i++) {
> + sources[i] = relpath(sources[i]);
> }
>
> for (size_t i = 0; i < nsources; ++i) {
> diff --git a/src/util.c b/src/util.c
> index c3691bb..fd62264 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -1,3 +1,4 @@
> +#include <limits.h>
> #include <sys/stat.h>
> #include <stdarg.h>
> #include <stdbool.h>
> @@ -113,6 +114,49 @@ gen_name(int *id, const char *fmt)
> return str;
> }
>
> +const char *
> +relpath(const char *dir)
> +{
> + if (dir[0] != '/') {
> + return dir;
> + }
> + char cwd[PATH_MAX];
> + if (getcwd(cwd, sizeof(cwd)) == NULL) {
> + return dir;
> + }
> + size_t cwdlen = strlen(cwd);
> + if (strncmp(dir, cwd, cwdlen) == 0) {
> + return dir + cwdlen + 1;
this is out of bounds if cwdlen == strlen(dir) (although this function
will never be called this way?)
> + }
> + int common_prefix = -1;
> + for (int i = 0; dir[i] != '\0' && dir[i] == cwd[i]; i++) {
> + if (dir[i] == '/') {
> + common_prefix = i;
> + }
> + }
> + if (common_prefix == -1) {
> + return dir;
> + }
> + int dirs_up = 1;
> + for (int i = common_prefix + 1; cwd[i] != '\0'; i++) {
> + if (cwd[i] == '/') {
> + dirs_up++;
> + }
> + }
> + const char *unique_part = dir + common_prefix + 1;
note that unique_part might be '\0' here, again, just when this function
is called in a way that it wont be? (yet)
> + char dir_up[] = "../";
> + size_t l_dir_up = strlen(dir_up);
> + size_t l_reldir = dirs_up * l_dir_up + strlen(unique_part) + 1;
> + char *reldir = xcalloc(1, l_reldir);
> + int i = 0;
> + for (int d = 0; d < dirs_up; d++) {
> + strcpy(reldir + i, dir_up);
> + i += l_dir_up;
> + }
> + strcpy(reldir + i, unique_part);
> + return reldir;
> +}
> +
> void
> errline(struct location loc)
> {
True. Actually, the input variable is a file, not a directory. I'll
rename it. This means, this case should indeed never happen. But I'll
fix it anyway.
> note that unique_part might be '\0' here, again, just when this function
> is called in a way that it wont be? (yet)
Same as for your other comment: It shouldn't happen because the file
name should have a length >= 1 but I'll fix it to be on the safe side.