src/fccache.c | 5 +++ src/fcstr.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 78 insertions(+), 15 deletions(-) New commits: diff-tree 1de7a4cc09172bbc99912e1410f46fc16c1a05ec (from cc104e6a910427db009be36ec34125962889ecb8) Author: Han-Wen Nienhuys <hanwen@xs4all.nl> Date: Sun Sep 17 14:34:46 2006 -0700 FcStrCanonFileName buggy for mingw. (bug 8311) FcStrCanonFileName checks whether s[0] == ''/'', and recurses if not. This only works on POSIX. On dos, this crashes with a stack overflow. The patch attached splits this functionality in two functions (FcStrCanonAbsoluteFilename) and uses GetFullPathName on windows to get an absolute path. It also fixes a number of other issues. With this patch, LilyPond actually produces output on Windows. diff --git a/src/fccache.c b/src/fccache.c index 7e2c1be..6a3d8e8 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -689,6 +689,11 @@ bail1: return NULL; } + +#ifdef _WIN32 +#define mkdir(path,mode) _mkdir(path) +#endif + static FcBool FcMakeDirectory (const FcChar8 *dir) { diff --git a/src/fcstr.c b/src/fcstr.c index 7ec2ab4..368761d 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -26,6 +26,9 @@ #include <stdlib.h> #include <ctype.h> #include <string.h> +#ifdef _WIN32 +#include <windows.h> +#endif FcChar8 * FcStrCopy (const FcChar8 *s) @@ -831,26 +834,13 @@ FcStrBasename (const FcChar8 *file) } FcChar8 * -FcStrCanonFilename (const FcChar8 *s) +FcStrCanonAbsoluteFilename (const FcChar8 *s) { FcChar8 *file; FcChar8 *f; const FcChar8 *slash; int size; - - if (*s != ''/'') - { - FcChar8 *full; - - FcChar8 cwd[FC_MAX_FILE_LEN + 2]; - if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL) - return NULL; - strcat ((char *) cwd, "/"); - full = FcStrPlus (cwd, s); - file = FcStrCanonFilename (full); - FcStrFree (full); - return file; - } + size = strlen ((char *) s) + 1; file = malloc (size); if (!file) @@ -889,6 +879,74 @@ FcStrCanonFilename (const FcChar8 *s) } return file; } + +#ifdef _WIN32 +/* + * Convert ''\\'' to ''/'' , remove double ''/'' + */ +static void +FcConvertDosPath (char *str) +{ + size_t len = strlen (str); + char *p = str; + char *dest = str; + char *end = str + len; + char last = 0; + + while (p < end) + { + if (*p == ''\\'') + *p = ''/''; + + if (*p != ''/'' + || last != ''/'') + { + *dest++ = *p; + } + + last = *p; + p++; + } + + *dest = 0; +} +#endif + +FcChar8 * +FcStrCanonFilename (const FcChar8 *s) +{ +#ifdef _WIN32 + FcChar8 full[FC_MAX_FILE_LEN + 2]; + FcChar8 basename[FC_MAX_FILE_LEN + 2]; + int size = GetFullPathName (s, sizeof (full) -1, + full, + basename); + + if (size == 0) + perror ("GetFullPathName"); + + FcConvertDosPath (full); + return FcStrCanonAbsoluteFilename (full); +#else + if (s[0] == ''/'') + return FcStrCanonAbsoluteFilename (s); + else + { + FcChar8 *full; + FcChar8 *file; + + FcChar8 cwd[FC_MAX_FILE_LEN + 2]; + if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL) + return NULL; + strcat ((char *) cwd, "/"); + full = FcStrPlus (cwd, s); + file = FcStrCanonAbsoluteFilename (full); + FcStrFree (full); + return file; + } +#endif +} + FcStrSet * FcStrSetCreate (void)