fdisk: sanitize partition name printing; drop "Code" column; get rid of one static var

function                                             old     new   delta
list_table                                          2335    2373     +38
fill_bounds                                          131     128      -3
part_array_len                                         4       -      -4
get_boot                                            1584    1574     -10
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/2 up/down: 38/-17)             Total: 21 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index af80735..b988e65 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -121,6 +121,7 @@
 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
 #endif
 #include "libbb.h"
+#include "unicode.h"
 
 #if BB_LITTLE_ENDIAN
 # define inline_if_little_endian ALWAYS_INLINE
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c
index 715e227..9b17b4a 100644
--- a/util-linux/fdisk_gpt.c
+++ b/util-linux/fdisk_gpt.c
@@ -36,14 +36,13 @@
 	uint64_t lba_start;
 	uint64_t lba_end;
 	uint64_t flags;
-	uint16_t name[36];
+	uint16_t name36[36];
 } gpt_partition;
 
 static gpt_header *gpt_hdr;
 
 static char *part_array;
 static unsigned int n_parts;
-static unsigned int part_array_len;
 static unsigned int part_entry_len;
 
 static inline gpt_partition *
@@ -73,18 +72,34 @@
 		buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
 }
 
-/* TODO: real unicode support */
 static void
-gpt_print_wide(uint16_t *s, int max_len)
+gpt_print_wide36(uint16_t *s)
 {
+#if ENABLE_UNICODE_SUPPORT
+	char buf[37 * 4];
+	wchar_t wc[37];
 	int i = 0;
-
-	while (i < max_len) {
-		if (*s == 0)
-			return;
-		fputc(*s, stdout);
-		s++;
+	while (i < ARRAY_SIZE(wc)-1) {
+		if (s[i] == 0)
+			break;
+		wc[i] = s[i];
+		i++;
 	}
+	wc[i] = 0;
+	if (wcstombs(buf, wc, sizeof(buf)) <= sizeof(buf)-1)
+		fputs(printable_string(NULL, buf), stdout);
+#else
+	char buf[37];
+	int i = 0;
+	while (i < ARRAY_SIZE(buf)-1) {
+		if (s[i] == 0)
+			break;
+		buf[i] = (s[i] < 0x7f) ? s[i] : '?';
+		i++;
+	}
+	buf[i] = '\0';
+	fputs(printable_string(NULL, buf), stdout);
+#endif
 }
 
 static void
@@ -106,19 +121,28 @@
 		(unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba),
 		(unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba));
 
-	puts("Number  Start (sector)    End (sector)  Size       Code  Name");
+/* "GPT fdisk" has a concept of 16-bit extension of the original MBR 8-bit type codes,
+ * which it displays here: its output columns are ... Size Code Name
+ * They are their own invention and are not stored on disk.
+ * Looks like they use them to support "hybrid" GPT: for example, they have
+ *   AddType(0x8307, "69DAD710-2CE4-4E3C-B16C-21A1D49ABED3", "Linux ARM32 root (/)");
+ * and then (code>>8) matches what you need to put into MBR's type field for such a partition.
+ * To print those codes, we'd need a GUID lookup table. Lets just drop the "Code" column instead:
+ */
+	puts("Number  Start (sector)    End (sector)  Size Name");
+	//    123456 123456789012345 123456789012345 12345 abc
 	for (i = 0; i < n_parts; i++) {
 		gpt_partition *p = gpt_part(i);
 		if (p->lba_start) {
 			smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size,
 				numstr6, " KMGTPEZY")[0] = '\0';
-			printf("%4u %15llu %15llu %11s   %04x  ",
+			printf("%6u %15llu %15llu %s ",
 				i + 1,
 				(unsigned long long)SWAP_LE64(p->lba_start),
 				(unsigned long long)SWAP_LE64(p->lba_end),
-				numstr6,
-				0x0700 /* FIXME */);
-			gpt_print_wide(p->name, 18);
+				numstr6
+			);
+			gpt_print_wide36(p->name36);
 			bb_putchar('\n');
 		}
 	}
@@ -127,6 +151,7 @@
 static int
 check_gpt_label(void)
 {
+	unsigned part_array_len;
 	struct partition *first = pt_offset(MBRbuffer, 0);
 	struct pte pe;
 	uint32_t crc;
@@ -150,6 +175,7 @@
 		return 0;
 	}
 
+	init_unicode();
 	if (!global_crc32_table) {
 		global_crc32_table = crc32_filltable(NULL, 0);
 	}