Convert unexpand(1) to libutf
This commit is contained in:
		
							
								
								
									
										66
									
								
								unexpand.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								unexpand.c
									
									
									
									
									
								
							@@ -3,14 +3,10 @@
 | 
				
			|||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <wchar.h>
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "utf.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					static void unexpand(const char *, FILE *);
 | 
				
			||||||
	FILE *fp;
 | 
					 | 
				
			||||||
	const char *name;
 | 
					 | 
				
			||||||
} Fdescr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void unexpand(Fdescr *dsc);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int aflag = 0;
 | 
					static int aflag = 0;
 | 
				
			||||||
static int tabsize = 8;
 | 
					static int tabsize = 8;
 | 
				
			||||||
@@ -24,8 +20,8 @@ usage(void)
 | 
				
			|||||||
int
 | 
					int
 | 
				
			||||||
main(int argc, char *argv[])
 | 
					main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Fdescr dsc;
 | 
					 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ARGBEGIN {
 | 
						ARGBEGIN {
 | 
				
			||||||
	case 't':
 | 
						case 't':
 | 
				
			||||||
@@ -41,66 +37,50 @@ main(int argc, char *argv[])
 | 
				
			|||||||
	} ARGEND;
 | 
						} ARGEND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (argc == 0) {
 | 
						if (argc == 0) {
 | 
				
			||||||
		dsc.name = "<stdin>";
 | 
							unexpand("<stdin>", stdin);
 | 
				
			||||||
		dsc.fp = stdin;
 | 
					 | 
				
			||||||
		unexpand(&dsc);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		for (; argc > 0; argc--, argv++) {
 | 
							for (; argc > 0; argc--, argv++) {
 | 
				
			||||||
			if (!(fp = fopen(*argv, "r"))) {
 | 
								if (!(fp = fopen(argv[0], "r"))) {
 | 
				
			||||||
				weprintf("fopen %s:", *argv);
 | 
									weprintf("fopen %s:", argv[0]);
 | 
				
			||||||
 | 
									ret = 1;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			dsc.name = *argv;
 | 
								unexpand(argv[0], fp);
 | 
				
			||||||
			dsc.fp = fp;
 | 
					 | 
				
			||||||
			unexpand(&dsc);
 | 
					 | 
				
			||||||
			fclose(fp);
 | 
								fclose(fp);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static wint_t
 | 
					 | 
				
			||||||
in(Fdescr *f)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	wint_t c = fgetwc(f->fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (c == WEOF && ferror(f->fp))
 | 
					 | 
				
			||||||
		eprintf("%s: read error:", f->name);
 | 
					 | 
				
			||||||
	return c;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
out(wint_t c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	putwchar(c);
 | 
					 | 
				
			||||||
	if (ferror(stdout))
 | 
					 | 
				
			||||||
		eprintf("stdout: write error:");
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
unexpandspan(unsigned int n, unsigned int col)
 | 
					unexpandspan(unsigned int n, unsigned int col)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int off = (col-n) % tabsize;
 | 
						unsigned int off = (col-n) % tabsize;
 | 
				
			||||||
 | 
						Rune r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (n + off >= tabsize && n > 1)
 | 
						if (n + off >= tabsize && n > 1)
 | 
				
			||||||
		n += off;
 | 
							n += off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = '\t';
 | 
				
			||||||
	for (; n >= tabsize; n -= tabsize)
 | 
						for (; n >= tabsize; n -= tabsize)
 | 
				
			||||||
		out('\t');
 | 
							writerune("<stdout>", stdout, &r);
 | 
				
			||||||
 | 
						r = ' ';
 | 
				
			||||||
	while (n--)
 | 
						while (n--)
 | 
				
			||||||
		out(' ');
 | 
							writerune("<stdout>", stdout, &r);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
unexpand(Fdescr *dsc)
 | 
					unexpand(const char *file, FILE *fp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int n = 0, col = 0;
 | 
						unsigned int n = 0, col = 0;
 | 
				
			||||||
 | 
						Rune r;
 | 
				
			||||||
	int bol = 1;
 | 
						int bol = 1;
 | 
				
			||||||
	wint_t c;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((c = in(dsc)) != EOF) {
 | 
						while (1) {
 | 
				
			||||||
		switch (c) {
 | 
							if (!readrune(file, fp, &r))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (r) {
 | 
				
			||||||
		case ' ':
 | 
							case ' ':
 | 
				
			||||||
			if (bol || aflag)
 | 
								if (bol || aflag)
 | 
				
			||||||
				n++;
 | 
									n++;
 | 
				
			||||||
@@ -131,8 +111,8 @@ unexpand(Fdescr *dsc)
 | 
				
			|||||||
			col++;
 | 
								col++;
 | 
				
			||||||
			bol = 0;
 | 
								bol = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if ((c != ' ' && c != '\t') || (!aflag && !bol))
 | 
							if ((r != ' ' && r != '\t') || (!aflag && !bol))
 | 
				
			||||||
			out(c);
 | 
								writerune("<stdout>", stdout, &r);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (n > 0 && (bol || aflag))
 | 
						if (n > 0 && (bol || aflag))
 | 
				
			||||||
		unexpandspan(n, col);
 | 
							unexpandspan(n, col);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user