X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcstr.c;h=368761dfb65d2eca3fa8b76412f47a7e0387e3af;hb=1de7a4cc09172bbc99912e1410f46fc16c1a05ec;hp=5d1961c3af47ee0f74857d6ed7df4e9cea976cfc;hpb=31b7e6d7f58616ebdc6281c3230282a2d7b57d6d;p=fontconfig.git diff --git a/src/fcstr.c b/src/fcstr.c index 5d1961c..368761d 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -26,6 +26,9 @@ #include #include #include +#ifdef _WIN32 +#include +#endif FcChar8 * FcStrCopy (const FcChar8 *s) @@ -764,26 +767,21 @@ FcStrCopyFilename (const FcChar8 *s) if (*s == '~') { FcChar8 *home = FcConfigHome (); + FcChar8 *full; int size; if (!home) return 0; size = strlen ((char *) home) + strlen ((char *) s); - new = (FcChar8 *) malloc (size); - if (!new) + full = (FcChar8 *) malloc (size); + if (!full) return 0; - FcMemAlloc (FC_MEM_STRING, size); - strcpy ((char *) new, (char *) home); - strcat ((char *) new, (char *) s + 1); + strcpy ((char *) full, (char *) home); + strcat ((char *) full, (char *) s + 1); + new = FcStrCanonFilename (full); + free (full); } else - { - int size = strlen ((char *) s) + 1; - new = (FcChar8 *) malloc (size); - if (!new) - return 0; - FcMemAlloc (FC_MEM_STRING, size); - memcpy (new, s, size); - } + new = FcStrCanonFilename (s); return new; } @@ -835,6 +833,121 @@ FcStrBasename (const FcChar8 *file) return FcStrCopy (slash + 1); } +FcChar8 * +FcStrCanonAbsoluteFilename (const FcChar8 *s) +{ + FcChar8 *file; + FcChar8 *f; + const FcChar8 *slash; + int size; + + size = strlen ((char *) s) + 1; + file = malloc (size); + if (!file) + return NULL; + FcMemAlloc (FC_MEM_STRING, size); + slash = NULL; + f = file; + for (;;) { + if (*s == '/' || *s == '\0') + { + if (slash) + { + switch (s - slash) { + case 2: + if (!strncmp ((char *) slash, "/.", 2)) + { + f -= 2; /* trim /. from file */ + } + break; + case 3: + if (!strncmp ((char *) slash, "/..", 3)) + { + f -= 3; /* trim /.. from file */ + while (f > file) { + if (*--f == '/') + break; + } + } + break; + } + } + slash = s; + } + if (!(*f++ = *s++)) + break; + } + 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) { @@ -995,3 +1108,7 @@ FcStrListDone (FcStrList *list) FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList)); free (list); } + +#define __fcstr__ +#include "fcaliastail.h" +#undef __fcstr__