/* * Copyright 2006 Jon Loeliger */ #include "git-compat-util.h" #include "interpolate.h" void interp_set_entry(struct interp *table, int slot, const char *value) { char *oldval = table[slot].value; char *newval = NULL; if (oldval) free(oldval); if (value) newval = xstrdup(value); table[slot].value = newval; } void interp_clear_table(struct interp *table, int ninterps) { int i; for (i = 0; i < ninterps; i++) { interp_set_entry(table, i, NULL); } } /* * Convert a NUL-terminated string in buffer orig * into the supplied buffer, result, whose length is reslen, * performing substitutions on %-named sub-strings from * the table, interps, with ninterps entries. * * Example interps: * { * { "%H", "example.org"}, * { "%port", "123"}, * { "%%", "%"}, * } * * Returns 0 on a successful substitution pass that fits in result, * Returns a number of bytes needed to hold the full substituted * string otherwise. */ unsigned long interpolate(char *result, unsigned long reslen, const char *orig, const struct interp *interps, int ninterps) { const char *src = orig; char *dest = result; unsigned long newlen = 0; const char *name, *value; unsigned long namelen, valuelen; int i; char c; memset(result, 0, reslen); 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) break; } /* Check for valid interpolation. */ if (i < ninterps) { value = interps[i].value; valuelen = strlen(value); if (newlen + valuelen + 1 < reslen) { /* Substitute. */ strncpy(dest, value, valuelen); dest += valuelen; } newlen += valuelen; src += namelen; continue; } } /* Straight copy one non-interpolation character. */ if (newlen + 1 < reslen) *dest++ = *src; src++; newlen++; } if (newlen + 1 < reslen) return 0; else return newlen + 2; }