diff options
Diffstat (limited to 'contrib/cvs/src/expand_path.c')
-rw-r--r-- | contrib/cvs/src/expand_path.c | 112 |
1 files changed, 93 insertions, 19 deletions
diff --git a/contrib/cvs/src/expand_path.c b/contrib/cvs/src/expand_path.c index 9898051..7d0bc39 100644 --- a/contrib/cvs/src/expand_path.c +++ b/contrib/cvs/src/expand_path.c @@ -81,10 +81,12 @@ variable_set (nameval) } /* This routine will expand the pathname to account for ~ and $ - characters as described above. If an error occurs, an error - message is printed via error() and NULL is returned. FILE and - LINE are the filename and linenumber to include in the error - message. */ + characters as described above. Returns a pointer to a newly + malloc'd string. If an error occurs, an error message is printed + via error() and NULL is returned. FILE and LINE are the filename + and linenumber to include in the error message. FILE must point + to something; LINE can be zero to indicate the line number is not + known. */ char * expand_path (name, file, line) char *name; @@ -93,40 +95,82 @@ expand_path (name, file, line) { char *s; char *d; - /* FIXME: arbitrary limit. */ - char mybuf[PATH_MAX]; - char buf[PATH_MAX]; + + char *mybuf = NULL; + size_t mybuf_size = 0; + char *buf = NULL; + size_t buf_size = 0; + + size_t doff; + char *result; + + /* Sorry this routine is so ugly; it is a head-on collision + between the `traditional' unix *d++ style and the need to + dynamically allocate. It would be much cleaner (and probably + faster, not that this is a bottleneck for CVS) with more use of + strcpy & friends, but I haven't taken the effort to rewrite it + thusly. */ + + /* First copy from NAME to MYBUF, expanding $<foo> as we go. */ s = name; d = mybuf; + doff = d - mybuf; + expand_string (&mybuf, &mybuf_size, doff + 1); + d = mybuf + doff; while ((*d++ = *s)) + { if (*s++ == '$') { char *p = d; char *e; int flag = (*s == '{'); + doff = d - mybuf; + expand_string (&mybuf, &mybuf_size, doff + 1); + d = mybuf + doff; for (; (*d++ = *s); s++) + { if (flag ? *s =='}' : isalnum (*s) == 0 && *s != '_') break; - *--d = 0; + doff = d - mybuf; + expand_string (&mybuf, &mybuf_size, doff + 1); + d = mybuf + doff; + } + *--d = '\0'; e = expand_variable (&p[flag], file, line); if (e) { + doff = d - mybuf; + expand_string (&mybuf, &mybuf_size, doff + 1); + d = mybuf + doff; for (d = &p[-1]; (*d++ = *e++);) - ; + { + doff = d - mybuf; + expand_string (&mybuf, &mybuf_size, doff + 1); + d = mybuf + doff; + } --d; if (flag && *s) s++; } else /* expand_variable has already printed an error message. */ - return NULL; + goto error_exit; } - *d = 0; + doff = d - mybuf; + expand_string (&mybuf, &mybuf_size, doff + 1); + d = mybuf + doff; + } + doff = d - mybuf; + expand_string (&mybuf, &mybuf_size, doff + 1); + d = mybuf + doff; + *d = '\0'; + + /* Then copy from MYBUF to BUF, expanding ~. */ s = mybuf; d = buf; /* If you don't want ~username ~/ to be expanded simply remove @@ -156,8 +200,15 @@ expand_path (name, file, line) } t = ps->pw_dir; } + doff = d - buf; + expand_string (&buf, &buf_size, doff + 1); + d = buf + doff; while ((*d++ = *t++)) - ; + { + doff = d - buf; + expand_string (&buf, &buf_size, doff + 1); + d = buf + doff; + } --d; if (*p == 0) *p = '/'; /* always add / */ @@ -166,12 +217,35 @@ expand_path (name, file, line) else --s; /* Kill up to here */ + doff = d - buf; + expand_string (&buf, &buf_size, doff + 1); + d = buf + doff; while ((*d++ = *s++)) - ; - *d=0; - result = xmalloc (sizeof(char) * strlen(buf)+1); - strcpy (result, buf); + { + doff = d - buf; + expand_string (&buf, &buf_size, doff + 1); + d = buf + doff; + } + doff = d - buf; + expand_string (&buf, &buf_size, doff + 1); + d = buf + doff; + *d = '\0'; + + /* OK, buf contains the value we want to return. Clean up and return + it. */ + free (mybuf); + /* Save a little memory with xstrdup; buf will tend to allocate + more than it needs to. */ + result = xstrdup (buf); + free (buf); return result; + + error_exit: + if (mybuf != NULL) + free (mybuf); + if (buf != NULL) + free (buf); + return NULL; } static char * @@ -181,7 +255,7 @@ expand_variable (name, file, line) int line; { if (strcmp (name, CVSROOT_ENV) == 0) - return CVSroot; + return CVSroot_original; else if (strcmp (name, RCSBIN_ENV) == 0) return Rcsbin; else if (strcmp (name, EDITOR1_ENV) == 0) @@ -231,10 +305,10 @@ expand_variable (name, file, line) that various crazy syntaxes might be invented for inserting information about revisions, branches, etc. */ if (line != 0) - error (0, 0, "%s:%d: unrecognized varaible syntax %s", + error (0, 0, "%s:%d: unrecognized variable syntax %s", file, line, name); else - error (0, 0, "%s: unrecognized varaible syntax %s", + error (0, 0, "%s: unrecognized variable syntax %s", file, name); return NULL; } |