aboutsummaryrefslogtreecommitdiff
path: root/lib/src/strexpand.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/src/strexpand.c')
-rw-r--r--lib/src/strexpand.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/src/strexpand.c b/lib/src/strexpand.c
new file mode 100644
index 0000000..7e552eb
--- /dev/null
+++ b/lib/src/strexpand.c
@@ -0,0 +1,55 @@
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "util.h"
+
+char *strexpand(const char *inp, size_t argc, const char *const *argv)
+{
+ char *out, *dst;
+ const char *ptr;
+ size_t i, len;
+
+ ptr = inp;
+ len = 0;
+
+ while (*ptr != '\0') {
+ if (ptr[0] == '%' && isdigit(ptr[1])) {
+ i = ptr[1] - '0';
+ if (i < argc)
+ len += strlen(argv[i]);
+ ptr += 2;
+ } else if (ptr[0] == '%' && ptr[1] == '%') {
+ ptr += 2;
+ len += 1;
+ } else {
+ ++ptr;
+ ++len;
+ }
+ }
+
+ out = calloc(1, len + 1);
+ if (out == NULL)
+ return NULL;
+
+ dst = out;
+
+ while (*inp != '\0') {
+ if (inp[0] == '%' && isdigit(inp[1])) {
+ i = inp[1] - '0';
+ if (i < argc) {
+ len = strlen(argv[i]);
+ memcpy(dst, argv[i], len);
+ dst += len;
+ }
+ inp += 2;
+ } else if (inp[0] == '%' && inp[1] == '%') {
+ *(dst++) = '%';
+ inp += 2;
+ } else {
+ *(dst++) = *(inp++);
+ }
+ }
+
+ return out;
+}