summaryrefslogtreecommitdiffstats
path: root/usr.bin/rcs/rcsutil.c
diff options
context:
space:
mode:
authorxsa <xsa@openbsd.org>2006-04-27 07:59:33 +0000
committerxsa <xsa@openbsd.org>2006-04-27 07:59:33 +0000
commit714c2363e2f6194b3fcf4112870eb9d8adb61d56 (patch)
tree23e7f02bfa3b89c87b5b2705e83d4d2050a12556 /usr.bin/rcs/rcsutil.c
parentmove -M into compat land; ok xsa (diff)
downloadwireguard-openbsd-714c2363e2f6194b3fcf4112870eb9d8adb61d56.tar.xz
wireguard-openbsd-714c2363e2f6194b3fcf4112870eb9d8adb61d56.zip
zap util.[ch] and move the content into rcsutil.[ch].
discussed with joris@.
Diffstat (limited to 'usr.bin/rcs/rcsutil.c')
-rw-r--r--usr.bin/rcs/rcsutil.c156
1 files changed, 155 insertions, 1 deletions
diff --git a/usr.bin/rcs/rcsutil.c b/usr.bin/rcs/rcsutil.c
index 8c732a0e944..31119174e33 100644
--- a/usr.bin/rcs/rcsutil.c
+++ b/usr.bin/rcs/rcsutil.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcsutil.c,v 1.6 2006/04/26 21:55:22 joris Exp $ */
+/* $OpenBSD: rcsutil.c,v 1.7 2006/04/27 07:59:33 xsa Exp $ */
/*
* Copyright (c) 2005, 2006 Joris Vink <joris@openbsd.org>
* Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org>
@@ -486,3 +486,157 @@ rcs_set_description(RCSFILE *file, const char *in)
rcs_desc_set(file, content);
xfree(content);
}
+
+/*
+ * Split the contents of a file into a list of lines.
+ */
+struct rcs_lines *
+rcs_splitlines(const char *fcont)
+{
+ char *dcp;
+ struct rcs_lines *lines;
+ struct rcs_line *lp;
+
+ lines = xmalloc(sizeof(*lines));
+ TAILQ_INIT(&(lines->l_lines));
+ lines->l_nblines = 0;
+ lines->l_data = xstrdup(fcont);
+
+ lp = xmalloc(sizeof(*lp));
+ lp->l_line = NULL;
+ lp->l_lineno = 0;
+ TAILQ_INSERT_TAIL(&(lines->l_lines), lp, l_list);
+
+ for (dcp = lines->l_data; *dcp != '\0';) {
+ lp = xmalloc(sizeof(*lp));
+ lp->l_line = dcp;
+ lp->l_lineno = ++(lines->l_nblines);
+ TAILQ_INSERT_TAIL(&(lines->l_lines), lp, l_list);
+
+ dcp = strchr(dcp, '\n');
+ if (dcp == NULL)
+ break;
+ *(dcp++) = '\0';
+ }
+
+ return (lines);
+}
+
+void
+rcs_freelines(struct rcs_lines *lines)
+{
+ struct rcs_line *lp;
+
+ while ((lp = TAILQ_FIRST(&(lines->l_lines))) != NULL) {
+ TAILQ_REMOVE(&(lines->l_lines), lp, l_list);
+ xfree(lp);
+ }
+
+ xfree(lines->l_data);
+ xfree(lines);
+}
+
+BUF *
+rcs_patchfile(const char *data, const char *patch,
+ int (*p)(struct rcs_lines *, struct rcs_lines *))
+{
+ struct rcs_lines *dlines, *plines;
+ struct rcs_line *lp;
+ size_t len;
+ int lineno;
+ BUF *res;
+
+ len = strlen(data);
+
+ if ((dlines = rcs_splitlines(data)) == NULL)
+ return (NULL);
+
+ if ((plines = rcs_splitlines(patch)) == NULL)
+ return (NULL);
+
+ if (p(dlines, plines) < 0) {
+ rcs_freelines(dlines);
+ rcs_freelines(plines);
+ return (NULL);
+ }
+
+ lineno = 0;
+ res = rcs_buf_alloc(len, BUF_AUTOEXT);
+ TAILQ_FOREACH(lp, &dlines->l_lines, l_list) {
+ if (lineno != 0)
+ rcs_buf_fappend(res, "%s\n", lp->l_line);
+ lineno++;
+ }
+
+ rcs_freelines(dlines);
+ rcs_freelines(plines);
+ return (res);
+}
+
+/*
+ * rcs_yesno()
+ *
+ * Read from standart input for `y' or `Y' character.
+ * Returns 0 on success, or -1 on failure.
+ */
+int
+rcs_yesno(void)
+{
+ int c, ret;
+
+ ret = 0;
+
+ fflush(stderr);
+ fflush(stdout);
+
+ if ((c = getchar()) != 'y' && c != 'Y')
+ ret = -1;
+ else
+ while (c != EOF && c != '\n')
+ c = getchar();
+
+ return (ret);
+}
+
+/*
+ * rcs_strsplit()
+ *
+ * Split a string <str> of <sep>-separated values and allocate
+ * an argument vector for the values found.
+ */
+struct rcs_argvector *
+rcs_strsplit(char *str, const char *sep)
+{
+ struct rcs_argvector *av;
+ size_t i = 0;
+ char **nargv;
+ char *cp, *p;
+
+ cp = xstrdup(str);
+ av = xmalloc(sizeof(*av));
+ av->str = cp;
+ av->argv = xcalloc(i + 1, sizeof(*(av->argv)));
+
+ while ((p = strsep(&cp, sep)) != NULL) {
+ av->argv[i++] = p;
+ nargv = xrealloc(av->argv,
+ i + 1, sizeof(*(av->argv)));
+ av->argv = nargv;
+ }
+ av->argv[i] = NULL;
+
+ return (av);
+}
+
+/*
+ * rcs_argv_destroy()
+ *
+ * Free an argument vector previously allocated by rcs_strsplit().
+ */
+void
+rcs_argv_destroy(struct rcs_argvector *av)
+{
+ xfree(av->str);
+ xfree(av->argv);
+ xfree(av);
+}