Make HFS implementation use MacRoman.

* grub-core/fs/hfs.c (MAX_UTF8_PER_MAC_ROMAN): New define.
	(macroman): New const array.
	(macroman_to_utf8): New function.
	(utf8_to_macroman): Likewise.
	(grub_hfs_find_dir): Use utf8_to_macroman.
	(grub_hfs_dir): Use macroman_to_utf8.
	Set case_insensitive.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-12-24 20:20:41 +01:00
parent 4ea0316e67
commit 74bbf0dbae
2 changed files with 208 additions and 4 deletions

View file

@ -1,3 +1,15 @@
2011-12-24 Vladimir Serbinenko <phcoder@gmail.com>
Make HFS implementation to use MacRoman.
* grub-core/fs/hfs.c (MAX_UTF8_PER_MAC_ROMAN): New define.
(macroman): New const array.
(macroman_to_utf8): New function.
(utf8_to_macroman): Likewise.
(grub_hfs_find_dir): Use utf8_to_macroman.
(grub_hfs_dir): Use macroman_to_utf8.
Set case_insensitive.
2011-12-24 Vladimir Serbinenko <phcoder@gmail.com>
* docs/grub.texi (Filesystems): Add IEEE1275 full-path example.

View file

@ -862,6 +862,190 @@ grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx,
return grub_errno;
}
#define MAX_UTF8_PER_MAC_ROMAN 3
static const char macroman[0x80][MAX_UTF8_PER_MAC_ROMAN + 1] =
{
/* 80 */ "\xc3\x84",
/* 81 */ "\xc3\x85",
/* 82 */ "\xc3\x87",
/* 83 */ "\xc3\x89",
/* 84 */ "\xc3\x91",
/* 85 */ "\xc3\x96",
/* 86 */ "\xc3\x9c",
/* 87 */ "\xc3\xa1",
/* 88 */ "\xc3\xa0",
/* 89 */ "\xc3\xa2",
/* 8A */ "\xc3\xa4",
/* 8B */ "\xc3\xa3",
/* 8C */ "\xc3\xa5",
/* 8D */ "\xc3\xa7",
/* 8E */ "\xc3\xa9",
/* 8F */ "\xc3\xa8",
/* 90 */ "\xc3\xaa",
/* 91 */ "\xc3\xab",
/* 92 */ "\xc3\xad",
/* 93 */ "\xc3\xac",
/* 94 */ "\xc3\xae",
/* 95 */ "\xc3\xaf",
/* 96 */ "\xc3\xb1",
/* 97 */ "\xc3\xb3",
/* 98 */ "\xc3\xb2",
/* 99 */ "\xc3\xb4",
/* 9A */ "\xc3\xb6",
/* 9B */ "\xc3\xb5",
/* 9C */ "\xc3\xba",
/* 9D */ "\xc3\xb9",
/* 9E */ "\xc3\xbb",
/* 9F */ "\xc3\xbc",
/* A0 */ "\xe2\x80\xa0",
/* A1 */ "\xc2\xb0",
/* A2 */ "\xc2\xa2",
/* A3 */ "\xc2\xa3",
/* A4 */ "\xc2\xa7",
/* A5 */ "\xe2\x80\xa2",
/* A6 */ "\xc2\xb6",
/* A7 */ "\xc3\x9f",
/* A8 */ "\xc2\xae",
/* A9 */ "\xc2\xa9",
/* AA */ "\xe2\x84\xa2",
/* AB */ "\xc2\xb4",
/* AC */ "\xc2\xa8",
/* AD */ "\xe2\x89\xa0",
/* AE */ "\xc3\x86",
/* AF */ "\xc3\x98",
/* B0 */ "\xe2\x88\x9e",
/* B1 */ "\xc2\xb1",
/* B2 */ "\xe2\x89\xa4",
/* B3 */ "\xe2\x89\xa5",
/* B4 */ "\xc2\xa5",
/* B5 */ "\xc2\xb5",
/* B6 */ "\xe2\x88\x82",
/* B7 */ "\xe2\x88\x91",
/* B8 */ "\xe2\x88\x8f",
/* B9 */ "\xcf\x80",
/* BA */ "\xe2\x88\xab",
/* BB */ "\xc2\xaa",
/* BC */ "\xc2\xba",
/* BD */ "\xce\xa9",
/* BE */ "\xc3\xa6",
/* BF */ "\xc3\xb8",
/* C0 */ "\xc2\xbf",
/* C1 */ "\xc2\xa1",
/* C2 */ "\xc2\xac",
/* C3 */ "\xe2\x88\x9a",
/* C4 */ "\xc6\x92",
/* C5 */ "\xe2\x89\x88",
/* C6 */ "\xe2\x88\x86",
/* C7 */ "\xc2\xab",
/* C8 */ "\xc2\xbb",
/* C9 */ "\xe2\x80\xa6",
/* CA */ "\xc2\xa0",
/* CB */ "\xc3\x80",
/* CC */ "\xc3\x83",
/* CD */ "\xc3\x95",
/* CE */ "\xc5\x92",
/* CF */ "\xc5\x93",
/* D0 */ "\xe2\x80\x93",
/* D1 */ "\xe2\x80\x94",
/* D2 */ "\xe2\x80\x9c",
/* D3 */ "\xe2\x80\x9d",
/* D4 */ "\xe2\x80\x98",
/* D5 */ "\xe2\x80\x99",
/* D6 */ "\xc3\xb7",
/* D7 */ "\xe2\x97\x8a",
/* D8 */ "\xc3\xbf",
/* D9 */ "\xc5\xb8",
/* DA */ "\xe2\x81\x84",
/* DB */ "\xe2\x82\xac",
/* DC */ "\xe2\x80\xb9",
/* DD */ "\xe2\x80\xba",
/* DE */ "\xef\xac\x81",
/* DF */ "\xef\xac\x82",
/* E0 */ "\xe2\x80\xa1",
/* E1 */ "\xc2\xb7",
/* E2 */ "\xe2\x80\x9a",
/* E3 */ "\xe2\x80\x9e",
/* E4 */ "\xe2\x80\xb0",
/* E5 */ "\xc3\x82",
/* E6 */ "\xc3\x8a",
/* E7 */ "\xc3\x81",
/* E8 */ "\xc3\x8b",
/* E9 */ "\xc3\x88",
/* EA */ "\xc3\x8d",
/* EB */ "\xc3\x8e",
/* EC */ "\xc3\x8f",
/* ED */ "\xc3\x8c",
/* EE */ "\xc3\x93",
/* EF */ "\xc3\x94",
/* F0 */ "\xef\xa3\xbf",
/* F1 */ "\xc3\x92",
/* F2 */ "\xc3\x9a",
/* F3 */ "\xc3\x9b",
/* F4 */ "\xc3\x99",
/* F5 */ "\xc4\xb1",
/* F6 */ "\xcb\x86",
/* F7 */ "\xcb\x9c",
/* F8 */ "\xc2\xaf",
/* F9 */ "\xcb\x98",
/* FA */ "\xcb\x99",
/* FB */ "\xcb\x9a",
/* FC */ "\xc2\xb8",
/* FD */ "\xcb\x9d",
/* FE */ "\xcb\x9b",
/* FF */ "\xcb\x87",
};
static void
macroman_to_utf8 (char *to, const grub_uint8_t *from, grub_size_t len)
{
char *optr = to;
const grub_uint8_t *iptr;
for (iptr = from; iptr < from + len && *iptr; iptr++)
{
if (!(*iptr & 0x80))
{
*optr++ = *iptr;
continue;
}
optr = grub_stpcpy (optr, macroman[*iptr & 0x7f]);
}
*optr = 0;
}
static grub_ssize_t
utf8_to_macroman (grub_uint8_t *to, const char *from)
{
grub_uint8_t *end = to + 31;
grub_uint8_t *optr = to;
const char *iptr = from;
while (*iptr && optr < end)
{
int i, clen;
if (!(*iptr & 0x80))
{
*optr++ = *iptr++;
continue;
}
clen = 2;
if ((*iptr & 0xf0) == 0xe0)
clen++;
for (i = 0; i < 0x80; i++)
if (grub_memcmp (macroman[i], iptr, clen) == 0)
break;
if (i == 0x80)
break;
*optr++ = i | 0x80;
iptr += clen;
}
/* Too long or not encodable. */
if (*iptr)
return -1;
return optr - to;
}
/* Find a file or directory with the pathname PATH in the filesystem
DATA. Return the file record in RETDATA when it is non-zero.
@ -896,6 +1080,7 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
while (path && grub_strlen (path))
{
grub_ssize_t slen;
if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
@ -913,8 +1098,13 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
struct grub_hfs_catalog_key key;
key.parent_dir = grub_cpu_to_be32 (inode);
key.strlen = grub_strlen (path);
grub_strcpy ((char *) (key.str), path);
slen = utf8_to_macroman (key.str, path);
if (slen < 0)
{
grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", path);
goto fail;
}
key.strlen = slen;
/* Lookup this node. */
if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
@ -955,14 +1145,16 @@ grub_hfs_dir (grub_device_t device, const char *path,
int dir_hook (struct grub_hfs_record *rec)
{
char fname[32] = { 0 };
char fname[32 * MAX_UTF8_PER_MAC_ROMAN] = { 0 };
struct grub_hfs_dirrec *drec = rec->data;
struct grub_hfs_filerec *frec = rec->data;
struct grub_hfs_catalog_key *ckey = rec->key;
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
macroman_to_utf8 (fname, ckey->str, ckey->strlen);
info.case_insensitive = 1;
if (drec->type == GRUB_HFS_FILETYPE_DIR)
{