mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
![Shawn O. Pearce](/assets/img/avatar_default.png)
We shouldn't attempt to assign constant strings into char*, as the string is not writable at runtime. Likewise we should always be treating unsigned values as unsigned values, not as signed values. Most of these are very straightforward. The only exception is the (unnecessary) xstrdup/free in builtin-branch.c for the detached head case. Since this is a user-level interactive type program and that particular code path is executed no more than once, I feel that the extra xstrdup call is well worth the easy elimination of this warning. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
107 lines
2.1 KiB
C
107 lines
2.1 KiB
C
/*
|
|
* 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 1 on a successful substitution pass that fits in result,
|
|
* Returns 0 on a failed or overflowing substitution pass.
|
|
*/
|
|
|
|
int interpolate(char *result, int reslen,
|
|
const char *orig,
|
|
const struct interp *interps, int ninterps)
|
|
{
|
|
const char *src = orig;
|
|
char *dest = result;
|
|
int newlen = 0;
|
|
const char *name, *value;
|
|
int namelen, valuelen;
|
|
int i;
|
|
char c;
|
|
|
|
memset(result, 0, reslen);
|
|
|
|
while ((c = *src) && newlen < reslen - 1) {
|
|
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 < reslen - 1) {
|
|
/* 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++;
|
|
}
|
|
|
|
} else {
|
|
/* Straight copy one non-interpolation character. */
|
|
*dest++ = *src++;
|
|
newlen++;
|
|
}
|
|
}
|
|
|
|
return newlen < reslen - 1;
|
|
}
|