--- a/usr/src/cmd/localedef/ctype.c Tue Aug 27 13:00:09 2013 -0700
+++ b/usr/src/cmd/localedef/ctype.c Tue Aug 27 18:16:23 2013 -0700
@@ -11,7 +11,8 @@
/*
* Copyright 2010,2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright 2012 Garrett D'Amore <[email protected]> All rights reserved.
+ * Copyright 2012 Garrett D'Amore <[email protected]>
+ * Copyright 2013 DEY Storage Systems, Inc.
*/
/*
@@ -27,6 +28,7 @@
#include <ctype.h>
#include <wctype.h>
#include <unistd.h>
+#include "_ctype.h"
#include "localedef.h"
#include "parser.tab.h"
#include "runefile.h"
@@ -43,6 +45,13 @@
avl_node_t avl;
} ctype_node_t;
+typedef struct width_node {
+ wchar_t start;
+ wchar_t end;
+ int8_t width;
+ avl_node_t avl;
+} width_node_t;
+
static int
ctype_compare(const void *n1, const void *n2)
{
@@ -178,6 +187,48 @@
}
+/*
+ * A word about widths: if the width mask is specified, then libc
+ * unconditionally honors it. Otherwise, it assumes printable
+ * characters have width 1, and non-printable characters have width
+ * -1 (except for NULL which is special with with 0). Hence, we have
+ * no need to inject defaults here -- the "default" unset value of 0
+ * indicates that libc should use its own logic in wcwidth as described.
+ */
+void
+add_width(int wc, int width)
+{
+ ctype_node_t *ctn;
+
+ if ((ctn = get_ctype(wc)) == NULL) {
+ INTERR;
+ return;
+ }
+ ctn->ctype &= ~(_CTYPE_SWM);
+ switch (width) {
+ case 0:
+ ctn->ctype |= _CTYPE_SW0;
+ break;
+ case 1:
+ ctn->ctype |= _CTYPE_SW1;
+ break;
+ case 2:
+ ctn->ctype |= _CTYPE_SW2;
+ break;
+ case 3:
+ ctn->ctype |= _CTYPE_SW3;
+ break;
+ }
+}
+
+void
+add_width_range(int start, int end, int width)
+{
+ for (; start <= end; start++) {
+ add_width(start, width);
+ }
+}
+
void
add_caseconv(int val, int wc)
{
@@ -235,6 +286,7 @@
for (ctn = avl_first(&ctypes); ctn; ctn = AVL_NEXT(&ctypes, ctn)) {
int conflict = 0;
+
wc = ctn->wc;
/*