use memmove to avoid malloc

also use a string struct
This commit is contained in:
Gautham 2025-01-12 08:18:06 -06:00
parent 850a7dab74
commit 4f49a4f1d0

View file

@ -84,23 +84,6 @@ static wontreturn void ShowUsage(int rc, int fd) {
exit(rc); exit(rc);
} }
static wontreturn void DieOom(void) {
Die("renamestr", "out of memory");
}
static void *Malloc(size_t n) {
void *p;
if (!(p = malloc(n)))
DieOom();
return p;
}
static void *Realloc(void *p, size_t n) {
if (!(p = realloc(p, n)))
DieOom();
return p;
}
static void Pwrite(const void *data, size_t size, uint64_t offset) { static void Pwrite(const void *data, size_t size, uint64_t offset) {
ssize_t rc; ssize_t rc;
const char *p, *e; const char *p, *e;
@ -111,11 +94,14 @@ static void Pwrite(const void *data, size_t size, uint64_t offset) {
} }
} }
struct String {
const char *str;
size_t len;
};
struct Param { struct Param {
const char *from_string; struct String from;
size_t from_len; struct String to;
const char *to_string;
size_t to_len;
int count; int count;
char *roloc; char *roloc;
}; };
@ -143,22 +129,22 @@ static void GetOpts(int argc, char *argv[]) {
if (!param) { if (!param) {
Die(prog, "too many replacements provided"); Die(prog, "too many replacements provided");
} }
if (param->from_string) { if (param->from.str) {
Die(prog, "from string already provided"); Die(prog, "from string already provided");
} }
param->from_string = optarg; param->from.str = optarg;
param->from_len = strlen(optarg); param->from.len = strlen(optarg);
partial = !partial; partial = !partial;
break; break;
case 't': case 't':
if (!param) { if (!param) {
Die(prog, "too many replacements provided"); Die(prog, "too many replacements provided");
} }
if (param->to_string) { if (param->to.str) {
Die(prog, "to string already provided"); Die(prog, "to string already provided");
} }
param->to_string = optarg; param->to.str = optarg;
param->to_len = strlen(optarg); param->to.len = strlen(optarg);
partial = !partial; partial = !partial;
break; break;
case 'v': case 'v':
@ -169,9 +155,9 @@ static void GetOpts(int argc, char *argv[]) {
default: default:
ShowUsage(1, 2); ShowUsage(1, 2);
} }
if (param->from_string && param->to_string) { if (param->from.str && param->to.str) {
if (param->from_len < param->to_len) { if (param->from.len < param->to.len) {
Die(prog, "to_string longer than from_string, cannot replace"); Die(prog, "to.str longer than from.str, cannot replace");
} }
params.n++; params.n++;
} }
@ -182,14 +168,6 @@ static void GetOpts(int argc, char *argv[]) {
if (partial) { if (partial) {
Die(prog, "partial replacement provided"); Die(prog, "partial replacement provided");
} }
for (int i = 0; i < params.n; ++i) { // no-op
if (!params.p[i].from_string) {
Die(prog, "need from_string for replacement");
}
if (!params.p[i].to_string) {
Die(prog, "need to_string for replacement");
}
}
if (optind == argc) { if (optind == argc) {
Die(prog, "missing input argument"); Die(prog, "missing input argument");
} }
@ -228,17 +206,10 @@ static void OpenInput(const char *path) {
static void ReplaceString(struct Param *param) { static void ReplaceString(struct Param *param) {
Elf64_Xword len = strnlen(param->roloc, roend - param->roloc); Elf64_Xword len = strnlen(param->roloc, roend - param->roloc);
char *targstr = Malloc(len + 1); memmove(param->roloc, param->to.str, param->to.len);
for (Elf64_Xword i = 0; i < len + 1; ++i) memmove(param->roloc + param->to.len, param->roloc + param->from.len,
targstr[i] = 0; len + 1 - param->from.len);
strcpy(targstr, param->to_string); param->roloc += param->to.len;
strcat(targstr, param->roloc + param->from_len);
#ifdef MODE_DBG
kprintf("'%s' should be '%s'\n", param->roloc, targstr);
#endif
strcpy(param->roloc, targstr);
param->roloc += param->to_len;
free(targstr);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -273,19 +244,18 @@ int main(int argc, char *argv[]) {
param->roloc = rostart; param->roloc = rostart;
param->count = 0; param->count = 0;
#ifdef MODE_DBG #ifdef MODE_DBG
kprintf("need to replace '%s' with '%s'\n", param->from_string, kprintf("need to replace '%s' with '%s'\n", param->from.str, param->to.str);
param->to_string);
#endif #endif
} }
#define NEXT_ROLOC(z) \ #define NEXT_ROLOC(z) \
memmem((z)->roloc, roend - (z)->roloc, (z)->from_string, (z)->from_len) memmem((z)->roloc, roend - (z)->roloc, (z)->from.str, (z)->from.len)
for (int i = 0; i < params.n; ++i) { for (int i = 0; i < params.n; ++i) {
struct Param *param = &(params.p[i]); struct Param *param = &(params.p[i]);
for (param->roloc = NEXT_ROLOC(param); param->roloc != NULL; for (param->roloc = NEXT_ROLOC(param); param->roloc != NULL;
param->roloc = NEXT_ROLOC(param)) { param->roloc = NEXT_ROLOC(param)) {
ReplaceString(param); ReplaceString(param);
param->count++; param->count++;
} }
} }
#undef NEXT_ROLOC #undef NEXT_ROLOC
@ -297,8 +267,8 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < params.n; ++i) { for (int i = 0; i < params.n; ++i) {
struct Param *param = &(params.p[i]); struct Param *param = &(params.p[i]);
printf("'%s' -> '%s': %d replacements\n", param->from_string, printf("'%s' -> '%s': %d replacements\n", param->from.str, param->to.str,
param->to_string, param->count); param->count);
} }
return 0; return 0;
} }