diff --git a/cmd/ww/main.c b/cmd/ww/main.c index aaca8653..3751f6ed 100644 --- a/cmd/ww/main.c +++ b/cmd/ww/main.c @@ -225,13 +225,31 @@ build_one(const char *src, const char *out, const char *extra_includes, else srcdir = libdir; } - /* Compose the search path: any -I dirs first, then srcdir. - * locate_import walks them left-to-right. */ + /* Compose the search path: source-file's directory first, then any + * -I dirs, then srcdir. The source-dir lead matches Hare's CWD-first + * convention (its `hare test` is run from the module dir, making CWD + * == module-dir); our wrappers don't cd, so dirname(src) is the + * closest analog. Also matches cc -I. — source-dir wins ties over + * the system path. locate_import walks left-to-right. */ + char srcd[1024]; + { + const char *slash = strrchr(src, '/'); + if (slash) { + size_t n = (size_t)(slash - src); + if (n >= sizeof srcd) n = sizeof srcd - 1; + memcpy(srcd, src, n); + srcd[n] = '\0'; + } else { + srcd[0] = '.'; + srcd[1] = '\0'; + } + } static char searchpath[4096]; if (extra_includes && extra_includes[0]) - snprintf(searchpath, sizeof searchpath, "%s:%s", extra_includes, srcdir); + snprintf(searchpath, sizeof searchpath, "%s:%s:%s", + srcd, extra_includes, srcdir); else - snprintf(searchpath, sizeof searchpath, "%s", srcdir); + snprintf(searchpath, sizeof searchpath, "%s:%s", srcd, srcdir); srcdir = searchpath; /* Strip extension to derive a stem; e.g. /tmp/foo.ww → /tmp/foo */ diff --git a/selfhost/cmd/ww/main.combined.ww b/selfhost/cmd/ww/main.combined.ww index 54cdfc43..cad71d88 100644 --- a/selfhost/cmd/ww/main.combined.ww +++ b/selfhost/cmd/ww/main.combined.ww @@ -862,10 +862,40 @@ fn buildone(selfdir: *u8, src: *u8, out: *u8, incs: *u8, lf: *lflags) i32 = { cstrseal(dotdotlib, off); }; - // Compose searchpath: incs + ':' + dotdotlib (or just dotdotlib). - let searchpath: *u8 = os.alloc(PATH_MAX * 2u64): *u8; + // Compute the source-file's directory: bytes of `src` up to the + // last '/'. If `src` has no '/', use ".". Hare's CWD-first + // convention assumes you're running from the module dir; our + // wrappers don't cd, so dirname(src) stands in as the closest + // analog. Source-dir wins ties over the system path (cc -I.). + let srcd: *u8 = os.alloc(PATH_MAX): *u8; { - let off: u64 = 0u64; + let slen: u64 = cstrlen(src); + let last: u64 = slen; + let found: bool = false; + let i: u64 = slen; + for (i > 0u64) { + i -= 1u64; + if (src[i] == 47u8) { // '/' + last = i; + found = true; + i = 0u64; + }; + }; + if (found) { + let k: u64 = 0u64; + for (k < last) { srcd[k] = src[k]; k += 1u64; }; + srcd[last] = 0u8; + } else { + srcd[0] = 46u8; // '.' + srcd[1] = 0u8; + }; + }; + + // Compose searchpath: srcd + ':' + incs + ':' + dotdotlib. + let searchpath: *u8 = os.alloc(PATH_MAX * 3u64): *u8; + { + let off: u64 = cstrinto(searchpath, 0u64, srcd); + off = byteinto(searchpath, off, 58u8); // ':' if (incs[0u64] != 0u8) { off = cstrinto(searchpath, off, incs); off = byteinto(searchpath, off, 58u8); // ':' diff --git a/selfhost/cmd/ww/main.ww b/selfhost/cmd/ww/main.ww index ae0077ac..06b25df3 100644 --- a/selfhost/cmd/ww/main.ww +++ b/selfhost/cmd/ww/main.ww @@ -508,10 +508,40 @@ fn buildone(selfdir: *u8, src: *u8, out: *u8, incs: *u8, lf: *lflags) i32 = { cstrseal(dotdotlib, off); }; - // Compose searchpath: incs + ':' + dotdotlib (or just dotdotlib). - let searchpath: *u8 = os.alloc(PATH_MAX * 2u64): *u8; + // Compute the source-file's directory: bytes of `src` up to the + // last '/'. If `src` has no '/', use ".". Hare's CWD-first + // convention assumes you're running from the module dir; our + // wrappers don't cd, so dirname(src) stands in as the closest + // analog. Source-dir wins ties over the system path (cc -I.). + let srcd: *u8 = os.alloc(PATH_MAX): *u8; { - let off: u64 = 0u64; + let slen: u64 = cstrlen(src); + let last: u64 = slen; + let found: bool = false; + let i: u64 = slen; + for (i > 0u64) { + i -= 1u64; + if (src[i] == 47u8) { // '/' + last = i; + found = true; + i = 0u64; + }; + }; + if (found) { + let k: u64 = 0u64; + for (k < last) { srcd[k] = src[k]; k += 1u64; }; + srcd[last] = 0u8; + } else { + srcd[0] = 46u8; // '.' + srcd[1] = 0u8; + }; + }; + + // Compose searchpath: srcd + ':' + incs + ':' + dotdotlib. + let searchpath: *u8 = os.alloc(PATH_MAX * 3u64): *u8; + { + let off: u64 = cstrinto(searchpath, 0u64, srcd); + off = byteinto(searchpath, off, 58u8); // ':' if (incs[0u64] != 0u8) { off = cstrinto(searchpath, off, incs); off = byteinto(searchpath, off, 58u8); // ':'