shithub: kandr

ref: 91fc7321c2b7df934036f7b88ffdd5d6c826e941
dir: /ex/ex1-19.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>

// Return an allocated buffer containing the reversal of 'in'
Rune*
reverse(Rune *in, Rune *out, usize len)
{
	if(in == nil || len < 1)
		return nil;

	int i;

	//fprint(2, "reversing \"%S\" ;; runelen = %d\n", in, len);
	int to = 0, from = len-1;
	while(from >= 0){
		//fprint(2, "out[%d] = in[%d](%C)\n", to, from, in[from]);
		out[to] = in[from];
		from--;
		to++;
	}

	return out;
}

/* 
Reverse lines of input using a reverse function. 
*/
void
main(int, char*[])
{
	Biobuf	*in, *out;
	in = Bfdopen(0, OREAD);
	out = Bfdopen(1, OWRITE);

	while(1){
		long rlen = 0;
		char *line;
		int len = 0, n, i;
		Rune *rev, *rstr;

		// Read
		line = Brdstr(in, '\n', 1);
		len = Blinelen(in);
		if(line == 0)
			break;
		if(len < 0)
			sysfatal("err: could not read line → %r\n");

		rstr = runesmprint("%s", line);
		if(rstr == nil)
			sysfatal("err: UTF8 conversion failed → %r\n");
		rlen = runestrlen(rstr);
		rev = calloc(rlen+1, sizeof (Rune));
		reverse(rstr, rev, rlen);
		if(rev == nil)
			sysfatal("err: reversal failed\n");
		rev[rlen] = '\0';

		// Write
		n = Bprint(out, "%S\n", rev);
		if(n < 0)
			sysfatal("err: could not write line → %r\n");

		free(line);
		free(rev);
		free(rstr);
	}

	Bterm(in);
	Bterm(out);

	exits(nil);
}