X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=interpolate.c;h=00826778fc3d760a9b001423cd9c26e7972c126f;hb=b39c53e662b97108ee1bda72076630d9d0e56211;hp=fb30694f4741147bba62350f704111d3afbf8133;hpb=1b2782a5e2f88bf5e6e2cbb58e54fea015e21af5;p=git.git diff --git a/interpolate.c b/interpolate.c index fb30694f4..00826778f 100644 --- a/interpolate.c +++ b/interpolate.c @@ -44,33 +44,33 @@ void interp_clear_table(struct interp *table, int ninterps) * { "%%", "%"}, * } * - * Returns 1 on a successful substitution pass that fits in result, - * Returns 0 on a failed or overflowing substitution pass. + * Returns 0 on a successful substitution pass that fits in result, + * Returns a number of bytes needed to hold the full substituted + * string otherwise. */ -int interpolate(char *result, int reslen, +unsigned long interpolate(char *result, unsigned long reslen, const char *orig, const struct interp *interps, int ninterps) { const char *src = orig; char *dest = result; - int newlen = 0; + unsigned long newlen = 0; const char *name, *value; - int namelen, valuelen; + unsigned long namelen, valuelen; int i; char c; memset(result, 0, reslen); - while ((c = *src) && newlen < reslen - 1) { + while ((c = *src)) { if (c == '%') { /* Try to match an interpolation string. */ for (i = 0; i < ninterps; i++) { name = interps[i].name; namelen = strlen(name); - if (strncmp(src, name, namelen) == 0) { + if (strncmp(src, name, namelen) == 0) break; - } } /* Check for valid interpolation. */ @@ -78,29 +78,25 @@ int interpolate(char *result, int reslen, value = interps[i].value; valuelen = strlen(value); - if (newlen + valuelen < reslen - 1) { + if (newlen + valuelen + 1 < reslen) { /* Substitute. */ strncpy(dest, value, valuelen); - newlen += valuelen; dest += valuelen; - src += namelen; - } else { - /* Something's not fitting. */ - return 0; } - - } else { - /* Skip bogus interpolation. */ - *dest++ = *src++; - newlen++; + newlen += valuelen; + src += namelen; + continue; } - - } else { - /* Straight copy one non-interpolation character. */ - *dest++ = *src++; - newlen++; } + /* Straight copy one non-interpolation character. */ + if (newlen + 1 < reslen) + *dest++ = *src; + src++; + newlen++; } - return newlen < reslen - 1; + if (newlen + 1 < reslen) + return 0; + else + return newlen + 2; }