Julien Jehannet avatar Julien Jehannet committed 600a552

try to switch to wide-character strings (CRASHING !)

Comments (0)

Files changed (2)

 
 # flags
 CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\"
-CFLAGS   = -ansi -pedantic -Wall -Os ${CPPFLAGS} -std=c99
+CFLAGS   = -ansi -pedantic -Wall -Os ${CPPFLAGS} -std=c99 -g -ggdb
 LDFLAGS  = -s
 
 # compiler and linker
 #include <termios.h>
 #include <unistd.h>
 #include <stdbool.h>
+#include <wchar.h>
+
+wchar_t *wcsdup(const wchar_t *s);
+int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n);
+
 
 #define XSEL          "xsel -h >/dev/null 2>&1 && test -n \"$DISPLAY\" && xsel -ob || cat /tmp/.sandy.clipboard.$USER"
 #define CONTROL(ch)   (ch ^ 0x40)
 
 typedef struct Item Item;
 struct Item {
-	char *text;
+	wchar_t *text;
 	Item *left, *right;
 };
 
 static void   calcoffsets(void);
 static void   cleanup(void);
 static void   die(const char*);
-static void   drawtext(const char*, size_t, Color);
+static void   drawtext(const wchar_t*, size_t, Color);
 static void   drawmenu(void);
-static char  *fstrstr(const char*, const char*);
-static void   insert(const char*, ssize_t);
+static wchar_t *fstrstr(const wchar_t*, const wchar_t*);
+static void   insert(const wchar_t*, ssize_t);
 static void   match(bool);
 static size_t nextrune(int);
 static void   readstdin(void);
-static int    run(void);
+static void   run(void);
 static void   setup(int);
-static size_t textw(const char*);
+static size_t textw(const wchar_t*);
 
-static char   text[BUFSIZ] = "";
+static wchar_t   text[BUFSIZ] = L"";
 static int    mw;
 static int    inputw, promptw;
 static size_t cursor;
-static char  *prompt = NULL;
+static wchar_t  *prompt = NULL;
 static Item  *items = NULL;
 static Item  *matches, *matchend;
 static Item  *prev, *curr, *next, *sel;
 static struct termios tio_old, tio_new;
-static int  (*fstrncmp)(const char *, const char *, size_t) = strncmp;
+static int  (*fstrncmp)(const wchar_t*, const wchar_t*, size_t) = wcsncmp;
 
 void
 appenditem(Item *item, Item **list, Item **last) {
 calcoffsets(void) {
         int i, n;
 
-	n = mw - (promptw + inputw + textw("<") + textw(">"));
+	n = mw - (promptw + inputw + textw(L"◀") + textw(L"▶"));
 
         for(i = 0, next = curr; next; next = next->right)
                 if((i += MIN(textw(next->text), n)) > n)
 }
 
 void
-drawtext(const char *t, size_t w, Color col) {
-	const char *prestr, *poststr;
+drawtext(const wchar_t *t, size_t w, Color col) {
+	const wchar_t *prestr, *poststr;
 	int i;
-	char *buf;
+	wchar_t *buf;
 
 	if((buf=calloc(1, (w+1))) == NULL) die("Can't calloc.");
 	switch(col) {
 	case C_Reverse:
-		prestr="\033[7m";
-		poststr="\033[0m";
+		prestr=L"\033[7m";
+		poststr=L"\033[0m";
 		break;
 	case C_Normal:
 	default:
-		prestr=poststr="";
+		prestr=poststr=L"";
 	}
 
-	memset(buf, ' ', w);
-	buf[w]='\0';
-	memcpy(buf, t, w);
+	wmemset(buf, L' ', w);
+	buf[w]=L'\0';
+	wmemcpy(buf, t, w);
 	if(textw(t)-4>w)
-		for(i=MAX((w-4), 0); i<w; i++) buf[i]='.';
+		for(i=MAX((w-4), 0); i<w; i++) buf[i]=L'.';
 
-	fprintf(stderr, "%s  %s  %s", prestr, buf, poststr);
+	fwprintf(stderr, L"%s  %s  %s", prestr, buf, poststr);
 	free(buf);
 }
 
 	if(matches) {
 		rw=mw-(promptw+inputw);
 		if(curr->left)
-			drawtext("<", 5, C_Normal);
+			drawtext(L"◀", 5, C_Normal);
 		for(item = curr; item != next; item = item->right) {
 			drawtext(item->text, MIN(textw(item->text), rw), (item == sel) ? C_Reverse : C_Normal);
 			if((rw-= textw(item->text)) <= 0) break;
 		}
 		if(next) {
 			fprintf(stderr, "\033[%iG", mw-5);
-			drawtext(">", 5, C_Normal);
+			drawtext(L"▶", 5, C_Normal);
 		}
 
 	}
 	/* fprintf(stderr, "\n"); */
 }
 
-char*
-fstrstr(const char *s, const char *sub) {
+wchar_t*
+fstrstr(const wchar_t *s, const wchar_t *sub) {
 	size_t len;
 
-	for(len = strlen(sub); *s; s++)
+	for(len = wcslen(sub); *s; s++)
 		if(!fstrncmp(s, sub, len))
-			return (char *)s;
+			return (wchar_t *)s;
 	return NULL;
 }
 
 void
-insert(const char *str, ssize_t n) {
-	if(strlen(text) + n > sizeof text - 1)
+insert(const wchar_t *str, ssize_t n) {
+	if(wcslen(text) + n > sizeof text - 1)
 		return;
-	memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
+	wmemmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
 	if(n > 0)
-		memcpy(&text[cursor], str, n);
+		wmemcpy(&text[cursor], str, n);
 	cursor += n;
-	match(n > 0 && text[cursor] == '\0');
+	match(n > 0 && text[cursor] == L'\0');
 }
 
 void
 match(bool sub) {
-	size_t len = strlen(text);
+	size_t len = wcslen(text);
 	Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend;
 	Item *item, *lnext;
 
 
 void
 readstdin() {
-	char buf[sizeof text], *p, *maxstr = NULL;
+	wchar_t buf[sizeof text], *p, *maxstr = NULL;
 	size_t i, max = 0, size = 0;
 
-	for(i = 0; fgets(buf, sizeof buf, stdin); i++) {
+	for(i = 0; fgetws(buf, sizeof buf, stdin); i++) {
 		if(i+1 >= size / sizeof *items)
 			if(!(items = realloc(items, (size += BUFSIZ))))
 				die("Can't realloc.");
-		if((p = strchr(buf, '\n')))
+		if((p = wmemchr(buf, L'\n', sizeof buf)))
 			*p = '\0';
-		if(!(items[i].text = strdup(buf)))
-			die("Can't strdup.");
-		if(strlen(items[i].text) > max)
-			max = strlen(maxstr = items[i].text);
+		if(!(items[i].text = wcsdup(buf)))
+			die("Can't wcsdup.");
+		if(wcslen(items[i].text) > max)
+			max = wcslen(maxstr = items[i].text);
 	}
 	if(items)
 		items[i].text = NULL;
 	inputw = textw(maxstr);
 }
 
-int
+void
 run(void) {
-	char buf[32];
-	char c;
+	wchar_t buf[32];
+	wchar_t c;
 	FILE *f;
 	int n;
 
 	while(1) {
 		read(0, &c, 1);
-		memset(buf, '\0', sizeof buf);
+		wmemset(buf, L'\0', sizeof buf);
 		buf[0]=c;
 		switch_top:
 		switch(c) {
 		case CONTROL('G'):
 		case CONTROL('C'):
 			puts("");
-			return EXIT_SUCCESS;
 		case CONTROL('M'): /* Return */
 		case CONTROL('J'):
-			puts(sel ? sel->text : text);
-			return EXIT_SUCCESS;
+			fputws(sel ? sel->text : text, stdout);
 		case CONTROL(']'):
 		case CONTROL('\\'): /* These are usually close enough to RET to replace Shift+RET, again due to console limitations */
-			puts(text);
-			return EXIT_SUCCESS;
+			fputws(text, stdout);
 		case CONTROL('A'):
 			if(sel == matches) {
 				cursor=0;
 			break;
 		case CONTROL('E'):
 			if(text[cursor] != '\0') {
-				cursor = strlen(text);
+				cursor = wcslen(text);
 				break;
 			}
 			if(next) {
 		case CONTROL('I'): /* TAB */
 			if(!sel)
 				break;
-			strncpy(text, sel->text, sizeof text);
-			cursor = strlen(text);
+			wcsncpy(text, sel->text, sizeof text);
+			cursor = wcslen(text);
 			match(true);
 			break;
 		case CONTROL('K'):
 			}
 		default:
 			if(!iscntrl(*buf))
-				insert(buf, strlen(buf));
+				insert(buf, wcslen(buf));
 			break;
 		}
 		drawmenu();
 
 	/* change terminal attributes, save old */
 	tcgetattr(0, &tio_old);
-	memcpy ((char *)&tio_new, (char *)&tio_old, sizeof(struct termios));
+	wmemcpy ((wchar_t *)&tio_new, (wchar_t *)&tio_old, sizeof(struct termios));
 	tio_new.c_iflag &= ~(BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
 	tio_new.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
 	tio_new.c_cflag &= ~(CSIZE|PARENB);
 }
 
 size_t
-textw(const char *s) {
-	return (s?strlen(s):0)+4;
+textw(const wchar_t *s) {
+	return (s?wcslen(s):0)+4;
 }
 
 int
 			exit(EXIT_SUCCESS);
 		}
 		else if(!strcmp(argv[i], "-p"))
-			prompt=argv[++i];
+			mbstowcs(prompt, argv[++i], sizeof argv[i]);
 		else if(!strcmp(argv[i], "-i"))
-			fstrncmp = strncasecmp;
+			fstrncmp = wcsncasecmp;
 		else if(!strcmp(argv[i], "-t"))
 			position=1;
 		else if(!strcmp(argv[i], "-b"))
 
 	readstdin();
 	setup(position);
-	i = run();
+	run();
 	cleanup();
-	return i;
 }
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.