changeset 201:5d523752715a

Start of "patch" support. Writes to stdout at the moment.
author Rob Landley <rob@landley.net>
date Sat, 15 Dec 2007 21:47:25 -0600
parents f868f933bd3b
children 9134f2c1deb4
files lib/lib.c lib/lib.h toys/Config.in toys/toylist.h
diffstat 4 files changed, 83 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/lib/lib.c	Thu Dec 13 07:00:27 2007 -0600
+++ b/lib/lib.c	Sat Dec 15 21:47:25 2007 -0600
@@ -192,6 +192,11 @@
 	return xcreate(path, flags, 0);
 }
 
+void xclose(int fd)
+{
+	if (close(fd)) perror_exit("xclose");
+}
+
 // Die unless we can open/create a file, returning FILE *.
 FILE *xfopen(char *path, char *mode)
 {
@@ -567,3 +572,46 @@
 		close(fd);
 	} while (*++argv);
 }
+
+// Slow, but small.
+
+char *get_rawline(int fd, long *plen)
+{
+	char c, *buf = NULL;
+	long len = 0;
+
+	for (;;) {
+		if (1>read(fd, &c, 1)) break;
+		if (!(len & 63)) buf=xrealloc(buf, len+64);
+		if ((buf[len++]=c) == '\n') break;
+	}
+	if (buf) buf[len]=0;
+	if (plen) *plen = len;
+
+	return buf;
+}
+
+char *get_line(int fd)
+{
+	long len;
+	char *buf = get_rawline(fd, &len);
+
+	if (buf && buf[--len]=='\n') buf[len]=0;
+
+	return buf;
+}
+
+// Copy the rest of in to out and close both files.
+
+void xsendfile(int in, int out)
+{
+	long len;
+
+	if (in<0) return;
+	for (;;) {
+		len = xread(in, toybuf, sizeof(toybuf));
+		if (len<1) break;
+		xwrite(out, toybuf, len);
+	}
+	xclose(in);
+}
--- a/lib/lib.h	Thu Dec 13 07:00:27 2007 -0600
+++ b/lib/lib.h	Sat Dec 15 21:47:25 2007 -0600
@@ -21,6 +21,12 @@
 	char *arg;
 };
 
+struct double_list {
+	struct double_list *next;
+	struct double_list *prev;
+	char *data;
+};
+
 // args.c
 void get_optflags(void);
 
@@ -56,6 +62,7 @@
 void xaccess(char *path, int flags);
 int xcreate(char *path, int flags, int mode);
 int xopen(char *path, int flags);
+void xclose(int fd);
 FILE *xfopen(char *path, char *mode);
 ssize_t readall(int fd, void *buf, size_t len);
 ssize_t writeall(int fd, void *buf, size_t len);
@@ -74,6 +81,9 @@
 off_t fdlength(int fd);
 char *xreadlink(char *name);
 void loopfiles(char **argv, void (*function)(int fd, char *name));
+char *get_rawline(int fd, long *plen);
+char *get_line(int fd);
+void xsendfile(int in, int out);
 
 // getmountlist.c
 struct mtab_list {
--- a/toys/Config.in	Thu Dec 13 07:00:27 2007 -0600
+++ b/toys/Config.in	Sat Dec 15 21:47:25 2007 -0600
@@ -273,6 +273,19 @@
 	  own session.  Then oneit reaps zombies until the child exits, at
 	  which point it reboots (or with -p, powers off) the system.
 
+config PATCH
+	bool "patch"
+	default n
+	help
+	  usage: patch [-i file] [-p depth] [-Ru]
+
+	  Apply a unified diff to one or more files.
+
+	  -i	Input file (defaults=stdin)
+	  -p	number of '/' to strip from start of file paths (default=all)
+	  -R	Reverse patch.
+	  -u	Ignored (only handles "unified" diffs)
+
 config PWD
 	bool "pwd"
 	default y
--- a/toys/toylist.h	Thu Dec 13 07:00:27 2007 -0600
+++ b/toys/toylist.h	Sat Dec 15 21:47:25 2007 -0600
@@ -67,6 +67,16 @@
 	char *console;
 };
 
+struct patch_data {
+	char *infile;
+	long prefix;
+
+	struct double_list *plines, *flines;
+	long oldline, oldlen, newline, newlen;
+	int context, state;
+	int filein, fileout, filepatch;
+};
+
 struct sleep_data {
 	long seconds;
 };
@@ -92,6 +102,7 @@
 	struct mkfifo_data mkfifo;
 	struct netcat_data netcat;
 	struct oneit_data oneit;
+	struct patch_data patch;
 	struct sleep_data sleep;
 	struct touch_data touch;
 	struct toysh_data toysh;
@@ -140,6 +151,7 @@
 USE_NETCAT(OLDTOY(nc, netcat, "i#w#l@p#s:q#f:e", TOYFLAG_BIN))
 USE_NETCAT(NEWTOY(netcat, "i#w#l@p#s:q#f:e", TOYFLAG_BIN))
 USE_ONEIT(NEWTOY(oneit, "+<1c:p", TOYFLAG_SBIN))
+USE_PATCH(NEWTOY(patch, "up#i:R", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PWD(NEWTOY(pwd, NULL, TOYFLAG_BIN))
 USE_READLINK(NEWTOY(readlink, "<1f", TOYFLAG_BIN))
 USE_TOYSH(OLDTOY(sh, toysh, "c:i", TOYFLAG_BIN))