Date: Thu, 29 Apr 1999 10:15:29 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: "Mark E." , DJ Delorie , Andris Pavenis , djgpp-workers AT delorie DOT com Subject: Re: v2.03: wrapping up In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On Wed, 28 Apr 1999, I wrote: > > A special filename that evaluated to $DJDIR would also work (e.g. > > /dev/djgpp like Andris suggested a few days ago) or if there were > > someway of evaluating a env. variable in a filename (e.g. > > /dev/env/djdir/). > > Perhaps a better way would be to invent a ficticious drive called, say, > `{', and then use /dev/{/DJDIR etc.? After some thought, I like Mark's idea about automatic expansion of environment variables a lot. I implemented it in putpath.c, and the code doesn't seem too large. See the diffs below. Please comment on the idea and its implementation, so we could put this problem behind us. What the new code does is to let you say things like /dev/%/DJDIR/include or /dev/%/DJDIR?c:/djgpp?/include or even /dev/%/C_INCLUDE_PATH?/dev/%/DJDIR?/include (the part between the `?'s is the default value that gets used if the environment variable is undefined or empty). I've chosen the `%' as the pseudo-device name because it seems to be not too special in Bash. But if it proves to be a bad idea, we could find some other character, I guess. This should allow to put a -imacros option into the cpp section of the specs file that goes with the compiler, and have it seamlessly pull in the sys/version.h header that defines the version symbols. Also, this will allow to define file names in --prefix and other cases when building ported GNU tools and have them transparently expand at run time to the right directories/file names. Please comment on this idea and its implementation, and whether solving the problems with __DJGPP__ and __DJGPP_MINOR__ (by recompiling the GCC/EGCS distribution with the library that supports this feature) is an okay solution. I didn't check in the changes below yet, but if we agree on this being the solution for the version symbols, I would recommend to get this into v2.03. Last, but not least: thanks to Mark for suggesting this simple but powerful feature! Even if we don't use it for the immediate problem, I think it should be part of DJGPP v2.04. *** src/libc/dos/io/putpath.c~0 Thu Oct 29 10:24:44 1998 --- src/libc/dos/io/putpath.c Wed Apr 28 22:48:18 1999 *************** *** 8,20 **** #include #include ! void _put_path(const char *path) { ! _put_path2(path, 0); } ! void _put_path2(const char *path, int offset) { int o = __tb+offset; --- 8,20 ---- #include #include ! int _put_path(const char *path) { ! return _put_path2(path, 0); } ! int _put_path2(const char *path, int offset) { int o = __tb+offset; *************** _put_path2(const char *path, int offset) *** 47,52 **** --- 47,100 ---- path = p + 6; space -= 2; } + else if (p[5] == '%' && (p[6] == '/' || p[6] == '\\')) + { + /* /dev/%/foo/bar: expand env var foo and generate %foo%/bar */ + const char *p1; + char *var_name; + char *var_value; + int new_offset; + int c; + + p += 7; /* point to the beginning of the variable name */ + for (p1 = p; *p1 && *p1 != '/' && *p1 != '\\' && *p1 != '?'; p1++) + ; + + var_name = memcpy (alloca (p1 - p + 1), p, p1 - p); + var_name[p1 - p] = '\0'; + var_value = getenv (var_name); + if (var_value && *var_value) + { + new_offset = _put_path2(var_value, offset); + space -= new_offset - offset; + o += new_offset - offset; + if (*p1 == '?') /* skip the default value if present */ + for (++p1; *p1 && *p1 != '?'; p1++) + ; + else + p1--; + } + else if (*p1 == '?') /* use the default value if present */ + { + for (p = ++p1; *p1 && *p1 != '?'; p1++) + ; + var_value = memcpy (alloca (p1 - p + 1), p, p1 - p); + var_value[p1 - p] = '\0'; + new_offset = _put_path2(var_value, offset); + space -= new_offset - offset; + o += new_offset - offset; + } + else + p1--; + + /* if the rest of path begins with a slash, remove the trailing + slash in the transfer buffer */ + if ((p1[1] == '/' || p1[1] == '\\') + && o-1 >= __tb+offset + && ((c = _farnspeekb(o-1)) == '/' || c == '\\')) + o--; + path = p1 + 1; + } else if (p[5]) path = p + 5; } *************** _put_path2(const char *path, int offset) *** 72,75 **** --- 120,124 ---- /* null terminate it */ _farnspokeb(o, 0); + return o - __tb; } *** include/libc/dosio.h~0 Sat Aug 31 22:09:34 1996 --- include/libc/dosio.h Wed Apr 28 20:40:58 1999 *************** *** 21,28 **** /* puts "path" in the transfer buffer, fixing unix-allowed multi-slashes */ ! void _put_path(const char *_path); ! void _put_path2(const char *_path, int _offset); /* Convenience functions for setting up transfers */ --- 21,28 ---- /* puts "path" in the transfer buffer, fixing unix-allowed multi-slashes */ ! int _put_path(const char *_path); ! int _put_path2(const char *_path, int _offset); /* Convenience functions for setting up transfers */