diff options
author | marha <marha@users.sourceforge.net> | 2012-11-19 10:38:33 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2012-11-19 10:38:33 +0100 |
commit | 24635abae6008bef13e30d798b3f33abab412770 (patch) | |
tree | e799fbde24e0fd935af76b0bc48d30ef69f75d54 /xkbcomp/xkbpath.c | |
parent | e0844ae8b5ef87049537a7e0ebff81acc2695256 (diff) | |
parent | 6ce1d8f0f8c23e186175a7c84c21d7bfbe168dc5 (diff) | |
download | vcxsrv-24635abae6008bef13e30d798b3f33abab412770.tar.gz vcxsrv-24635abae6008bef13e30d798b3f33abab412770.tar.bz2 vcxsrv-24635abae6008bef13e30d798b3f33abab412770.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
Changed file permissions
dos -> unix
Conflicts:
libX11/include/X11/Xregion.h
libX11/src/ConvSel.c
libX11/src/CrGlCur.c
libX11/src/CrWindow.c
libX11/src/GetDflt.c
libX11/src/StrKeysym.c
libX11/src/Window.c
libX11/src/xkb/XKBBind.c
libX11/src/xkb/XKBGetMap.c
libX11/src/xkb/XKBSetGeom.c
libX11/src/xkb/XKBUse.c
libX11/src/xlibi18n/XimProto.h
libX11/src/xlibi18n/lcDynamic.c
libXdmcp/Key.c
libXdmcp/Write.c
libxcb/src/xcb_windefs.h
xkbcomp/keycodes.c
xkbcomp/xkbpath.c
xorg-server/hw/xwin/glx/winpriv.h
xorg-server/xkeyboard-config/rules/bin/ml1_s.sh
xorg-server/xkeyboard-config/rules/bin/ml1v1_s.sh
xorg-server/xkeyboard-config/rules/bin/ml1v_s.sh
xorg-server/xkeyboard-config/rules/bin/ml_s.sh
xorg-server/xkeyboard-config/rules/bin/mln_s.sh
xorg-server/xkeyboard-config/rules/bin/mlnvn_s.sh
xorg-server/xkeyboard-config/rules/bin/mlv_s.sh
xorg-server/xkeyboard-config/rules/compat/.gitignore
Diffstat (limited to 'xkbcomp/xkbpath.c')
-rw-r--r-- | xkbcomp/xkbpath.c | 842 |
1 files changed, 421 insertions, 421 deletions
diff --git a/xkbcomp/xkbpath.c b/xkbcomp/xkbpath.c index 5bb4ddc04..f5b21e6b8 100644 --- a/xkbcomp/xkbpath.c +++ b/xkbcomp/xkbpath.c @@ -1,421 +1,421 @@ -/************************************************************
- Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ********************************************************/
-
-#include <X11/Xlib.h>
-#include <X11/XKBlib.h>
-
-#define DEBUG_VAR debugFlags
-#include "utils.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <X11/extensions/XKM.h>
-#include "xkbpath.h"
-
-#ifndef DFLT_XKB_CONFIG_ROOT
-#define DFLT_XKB_CONFIG_ROOT "xkbdata"
-#endif
-
-#ifndef PATH_MAX
-#define PATH_MAX 1024
-#endif
-
-#define PATH_CHUNK 8 /* initial szPath */
-
-static Bool noDefaultPath = False;
-static int szPath; /* number of entries allocated for includePath */
-static int nPathEntries; /* number of actual entries in includePath */
-static char **includePath; /* Holds all directories we might be including data from */
-
-/**
- * Extract the first token from an include statement.
- * @param str_inout Input statement, modified in-place. Can be passed in
- * repeatedly. If str_inout is NULL, the parsing has completed.
- * @param file_rtrn Set to the include file to be used.
- * @param map_rtrn Set to whatever comes after ), if any.
- * @param nextop_rtrn Set to the next operation in the complete statement.
- * @param extra_data Set to the string between ( and ), if any.
- *
- * @return True if parsing was succcessful, False for an illegal string.
- *
- * Example: "evdev+aliases(qwerty)"
- * str_inout = aliases(qwerty)
- * nextop_retrn = +
- * extra_data = NULL
- * file_rtrn = evdev
- * map_rtrn = NULL
- *
- * 2nd run with "aliases(qwerty)"
- * str_inout = NULL
- * file_rtrn = aliases
- * map_rtrn = qwerty
- * extra_data = NULL
- * nextop_retrn = ""
- *
- */
-Bool
-XkbParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
- char *nextop_rtrn, char **extra_data)
-{
- char *tmp, *str, *next;
-
- str = *str_inout;
- if ((*str == '+') || (*str == '|'))
- {
- *file_rtrn = *map_rtrn = NULL;
- *nextop_rtrn = *str;
- next = str + 1;
- }
- else if (*str == '%')
- {
- *file_rtrn = *map_rtrn = NULL;
- *nextop_rtrn = str[1];
- next = str + 2;
- }
- else
- {
- /* search for tokens inside the string */
- next = strpbrk(str, "|+");
- if (next)
- {
- /* set nextop_rtrn to \0, next to next character */
- *nextop_rtrn = *next;
- *next++ = '\0';
- }
- else
- {
- *nextop_rtrn = '\0';
- next = NULL;
- }
- /* search for :, store result in extra_data */
- tmp = strchr(str, ':');
- if (tmp != NULL)
- {
- *tmp++ = '\0';
- *extra_data = uStringDup(tmp);
- }
- else
- {
- *extra_data = NULL;
- }
- tmp = strchr(str, '(');
- if (tmp == NULL)
- {
- *file_rtrn = uStringDup(str);
- *map_rtrn = NULL;
- }
- else if (str[0] == '(')
- {
- uFree(*extra_data);
- return False;
- }
- else
- {
- *tmp++ = '\0';
- *file_rtrn = uStringDup(str);
- str = tmp;
- tmp = strchr(str, ')');
- if ((tmp == NULL) || (tmp[1] != '\0'))
- {
- uFree(*file_rtrn);
- uFree(*extra_data);
- return False;
- }
- *tmp++ = '\0';
- *map_rtrn = uStringDup(str);
- }
- }
- if (*nextop_rtrn == '\0')
- *str_inout = NULL;
- else if ((*nextop_rtrn == '|') || (*nextop_rtrn == '+'))
- *str_inout = next;
- else
- return False;
- return True;
-}
-
-/**
- * Init memory for include paths.
- */
-Bool
-XkbInitIncludePath(void)
-{
- szPath = PATH_CHUNK;
- includePath = (char **) calloc(szPath, sizeof(char *));
- if (includePath == NULL)
- return False;
- return True;
-}
-
-void
-XkbAddDefaultDirectoriesToPath(void)
-{
- if (noDefaultPath)
- return;
- XkbAddDirectoryToPath(DFLT_XKB_CONFIG_ROOT);
-}
-
-/**
- * Remove all entries from the global includePath.
- */
-void
-XkbClearIncludePath(void)
-{
- register int i;
-
- if (szPath > 0)
- {
- for (i = 0; i < nPathEntries; i++)
- {
- if (includePath[i] != NULL)
- {
- uFree(includePath[i]);
- includePath[i] = NULL;
- }
- }
- nPathEntries = 0;
- }
- noDefaultPath = True;
- return;
-}
-
-/**
- * Add the given path to the global includePath variable.
- * If dir is NULL, the includePath is emptied.
- */
-Bool
-XkbAddDirectoryToPath(const char *dir)
-{
- int len;
- if ((dir == NULL) || (dir[0] == '\0'))
- {
- XkbClearIncludePath();
- return True;
- }
-#ifdef __UNIXOS2__
- dir = (char *) __XOS2RedirRoot(dir);
-#endif
- len = strlen(dir);
- if (len + 2 >= PATH_MAX)
- { /* allow for '/' and at least one character */
- ERROR2("Path entry (%s) too long (maxiumum length is %d)\n",
- dir, PATH_MAX - 3);
- return False;
- }
- if (nPathEntries >= szPath)
- {
- szPath += PATH_CHUNK;
- includePath = (char **) realloc(includePath, szPath * sizeof(char *));
- if (includePath == NULL)
- {
- WSGO("Allocation failed (includePath)\n");
- return False;
- }
- }
- includePath[nPathEntries] =
- (char *) calloc(strlen(dir) + 1, sizeof(char));
- if (includePath[nPathEntries] == NULL)
- {
- WSGO1("Allocation failed (includePath[%d])\n", nPathEntries);
- return False;
- }
- strcpy(includePath[nPathEntries++], dir);
- return True;
-}
-
-/***====================================================================***/
-
-/**
- * Return the xkb directory based on the type.
- * Do not free the memory returned by this function.
- */
-char *
-XkbDirectoryForInclude(unsigned type)
-{
- static char buf[32];
-
- switch (type)
- {
- case XkmSemanticsFile:
- strcpy(buf, "semantics");
- break;
- case XkmLayoutFile:
- strcpy(buf, "layout");
- break;
- case XkmKeymapFile:
- strcpy(buf, "keymap");
- break;
- case XkmKeyNamesIndex:
- strcpy(buf, "keycodes");
- break;
- case XkmTypesIndex:
- strcpy(buf, "types");
- break;
- case XkmSymbolsIndex:
- strcpy(buf, "symbols");
- break;
- case XkmCompatMapIndex:
- strcpy(buf, "compat");
- break;
- case XkmGeometryFile:
- case XkmGeometryIndex:
- strcpy(buf, "geometry");
- break;
- default:
- strcpy(buf, "");
- break;
- }
- return buf;
-}
-
-/***====================================================================***/
-
-typedef struct _FileCacheEntry
-{
- char *name;
- unsigned type;
- char *path;
- void *data;
- struct _FileCacheEntry *next;
-} FileCacheEntry;
-static FileCacheEntry *fileCache;
-
-/**
- * Add the file with the given name to the internal cache to avoid opening and
- * parsing the file multiple times. If a cache entry for the same name + type
- * is already present, the entry is overwritten and the data belonging to the
- * previous entry is returned.
- *
- * @parameter name The name of the file (e.g. evdev).
- * @parameter type Type of the file (XkbTypesIdx, ... or XkbSemanticsFile, ...)
- * @parameter path The full path to the file.
- * @parameter data Already parsed data.
- *
- * @return The data from the overwritten file or NULL.
- */
-void *
-XkbAddFileToCache(char *name, unsigned type, char *path, void *data)
-{
- FileCacheEntry *entry;
-
- for (entry = fileCache; entry != NULL; entry = entry->next)
- {
- if ((type == entry->type) && (uStringEqual(name, entry->name)))
- {
- void *old = entry->data;
- WSGO2("Replacing file cache entry (%s/%d)\n", name, type);
- entry->path = path;
- entry->data = data;
- return old;
- }
- }
- entry = uTypedAlloc(FileCacheEntry);
- if (entry != NULL)
- {
- entry->name = name;
- entry->type = type;
- entry->path = path;
- entry->data = data;
- entry->next = fileCache;
- fileCache = entry;
- }
- return NULL;
-}
-
-/**
- * Search for the given name + type in the cache.
- *
- * @parameter name The name of the file (e.g. evdev).
- * @parameter type Type of the file (XkbTypesIdx, ... or XkbSemanticsFile, ...)
- * @parameter pathRtrn Set to the full path of the given entry.
- *
- * @return the data from the cache entry or NULL if no matching entry was found.
- */
-void *
-XkbFindFileInCache(char *name, unsigned type, char **pathRtrn)
-{
- FileCacheEntry *entry;
-
- for (entry = fileCache; entry != NULL; entry = entry->next)
- {
- if ((type == entry->type) && (uStringEqual(name, entry->name)))
- {
- *pathRtrn = entry->path;
- return entry->data;
- }
- }
- return NULL;
-}
-
-/***====================================================================***/
-
-/**
- * Search for the given file name in the include directories.
- *
- * @param type one of XkbTypesIndex, XkbCompatMapIndex, ..., or
- * XkbSemanticsFile, XkmKeymapFile, ...
- * @param pathReturn is set to the full path of the file if found.
- *
- * @return an FD to the file or NULL. If NULL is returned, the value of
- * pathRtrn is undefined.
- */
-FILE *
-XkbFindFileInPath(char *name, unsigned type, char **pathRtrn)
-{
- register int i;
- FILE *file = NULL;
- int nameLen, typeLen, pathLen;
- char buf[PATH_MAX], *typeDir;
-
- typeDir = XkbDirectoryForInclude(type);
- nameLen = strlen(name);
- typeLen = strlen(typeDir);
- for (i = 0; i < nPathEntries; i++)
- {
- pathLen = strlen(includePath[i]);
- if (typeLen < 1)
- continue;
-
- if ((nameLen + typeLen + pathLen + 2) >= PATH_MAX)
- {
- ERROR3("File name (%s/%s/%s) too long\n", includePath[i],
- typeDir, name);
- ACTION("Ignored\n");
- continue;
- }
- snprintf(buf, sizeof(buf), "%s/%s/%s", includePath[i], typeDir, name);
- file = fopen(buf, "r");
- if (file != NULL)
- break;
- }
-
- if ((file != NULL) && (pathRtrn != NULL))
- {
- *pathRtrn = (char *) calloc(strlen(buf) + 1, sizeof(char));
- if (*pathRtrn != NULL)
- strcpy(*pathRtrn, buf);
- }
- return file;
-}
+/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH + THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ********************************************************/ + +#include <X11/Xlib.h> +#include <X11/XKBlib.h> + +#define DEBUG_VAR debugFlags +#include "utils.h" +#include <stdlib.h> +#include <unistd.h> +#include <X11/extensions/XKM.h> +#include "xkbpath.h" + +#ifndef DFLT_XKB_CONFIG_ROOT +#define DFLT_XKB_CONFIG_ROOT "xkbdata" +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#define PATH_CHUNK 8 /* initial szPath */ + +static Bool noDefaultPath = False; +static int szPath; /* number of entries allocated for includePath */ +static int nPathEntries; /* number of actual entries in includePath */ +static char **includePath; /* Holds all directories we might be including data from */ + +/** + * Extract the first token from an include statement. + * @param str_inout Input statement, modified in-place. Can be passed in + * repeatedly. If str_inout is NULL, the parsing has completed. + * @param file_rtrn Set to the include file to be used. + * @param map_rtrn Set to whatever comes after ), if any. + * @param nextop_rtrn Set to the next operation in the complete statement. + * @param extra_data Set to the string between ( and ), if any. + * + * @return True if parsing was succcessful, False for an illegal string. + * + * Example: "evdev+aliases(qwerty)" + * str_inout = aliases(qwerty) + * nextop_retrn = + + * extra_data = NULL + * file_rtrn = evdev + * map_rtrn = NULL + * + * 2nd run with "aliases(qwerty)" + * str_inout = NULL + * file_rtrn = aliases + * map_rtrn = qwerty + * extra_data = NULL + * nextop_retrn = "" + * + */ +Bool +XkbParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, + char *nextop_rtrn, char **extra_data) +{ + char *tmp, *str, *next; + + str = *str_inout; + if ((*str == '+') || (*str == '|')) + { + *file_rtrn = *map_rtrn = NULL; + *nextop_rtrn = *str; + next = str + 1; + } + else if (*str == '%') + { + *file_rtrn = *map_rtrn = NULL; + *nextop_rtrn = str[1]; + next = str + 2; + } + else + { + /* search for tokens inside the string */ + next = strpbrk(str, "|+"); + if (next) + { + /* set nextop_rtrn to \0, next to next character */ + *nextop_rtrn = *next; + *next++ = '\0'; + } + else + { + *nextop_rtrn = '\0'; + next = NULL; + } + /* search for :, store result in extra_data */ + tmp = strchr(str, ':'); + if (tmp != NULL) + { + *tmp++ = '\0'; + *extra_data = uStringDup(tmp); + } + else + { + *extra_data = NULL; + } + tmp = strchr(str, '('); + if (tmp == NULL) + { + *file_rtrn = uStringDup(str); + *map_rtrn = NULL; + } + else if (str[0] == '(') + { + uFree(*extra_data); + return False; + } + else + { + *tmp++ = '\0'; + *file_rtrn = uStringDup(str); + str = tmp; + tmp = strchr(str, ')'); + if ((tmp == NULL) || (tmp[1] != '\0')) + { + uFree(*file_rtrn); + uFree(*extra_data); + return False; + } + *tmp++ = '\0'; + *map_rtrn = uStringDup(str); + } + } + if (*nextop_rtrn == '\0') + *str_inout = NULL; + else if ((*nextop_rtrn == '|') || (*nextop_rtrn == '+')) + *str_inout = next; + else + return False; + return True; +} + +/** + * Init memory for include paths. + */ +Bool +XkbInitIncludePath(void) +{ + szPath = PATH_CHUNK; + includePath = (char **) calloc(szPath, sizeof(char *)); + if (includePath == NULL) + return False; + return True; +} + +void +XkbAddDefaultDirectoriesToPath(void) +{ + if (noDefaultPath) + return; + XkbAddDirectoryToPath(DFLT_XKB_CONFIG_ROOT); +} + +/** + * Remove all entries from the global includePath. + */ +void +XkbClearIncludePath(void) +{ + register int i; + + if (szPath > 0) + { + for (i = 0; i < nPathEntries; i++) + { + if (includePath[i] != NULL) + { + uFree(includePath[i]); + includePath[i] = NULL; + } + } + nPathEntries = 0; + } + noDefaultPath = True; + return; +} + +/** + * Add the given path to the global includePath variable. + * If dir is NULL, the includePath is emptied. + */ +Bool +XkbAddDirectoryToPath(const char *dir) +{ + int len; + if ((dir == NULL) || (dir[0] == '\0')) + { + XkbClearIncludePath(); + return True; + } +#ifdef __UNIXOS2__ + dir = (char *) __XOS2RedirRoot(dir); +#endif + len = strlen(dir); + if (len + 2 >= PATH_MAX) + { /* allow for '/' and at least one character */ + ERROR2("Path entry (%s) too long (maxiumum length is %d)\n", + dir, PATH_MAX - 3); + return False; + } + if (nPathEntries >= szPath) + { + szPath += PATH_CHUNK; + includePath = (char **) realloc(includePath, szPath * sizeof(char *)); + if (includePath == NULL) + { + WSGO("Allocation failed (includePath)\n"); + return False; + } + } + includePath[nPathEntries] = + (char *) calloc(strlen(dir) + 1, sizeof(char)); + if (includePath[nPathEntries] == NULL) + { + WSGO1("Allocation failed (includePath[%d])\n", nPathEntries); + return False; + } + strcpy(includePath[nPathEntries++], dir); + return True; +} + +/***====================================================================***/ + +/** + * Return the xkb directory based on the type. + * Do not free the memory returned by this function. + */ +char * +XkbDirectoryForInclude(unsigned type) +{ + static char buf[32]; + + switch (type) + { + case XkmSemanticsFile: + strcpy(buf, "semantics"); + break; + case XkmLayoutFile: + strcpy(buf, "layout"); + break; + case XkmKeymapFile: + strcpy(buf, "keymap"); + break; + case XkmKeyNamesIndex: + strcpy(buf, "keycodes"); + break; + case XkmTypesIndex: + strcpy(buf, "types"); + break; + case XkmSymbolsIndex: + strcpy(buf, "symbols"); + break; + case XkmCompatMapIndex: + strcpy(buf, "compat"); + break; + case XkmGeometryFile: + case XkmGeometryIndex: + strcpy(buf, "geometry"); + break; + default: + strcpy(buf, ""); + break; + } + return buf; +} + +/***====================================================================***/ + +typedef struct _FileCacheEntry +{ + char *name; + unsigned type; + char *path; + void *data; + struct _FileCacheEntry *next; +} FileCacheEntry; +static FileCacheEntry *fileCache; + +/** + * Add the file with the given name to the internal cache to avoid opening and + * parsing the file multiple times. If a cache entry for the same name + type + * is already present, the entry is overwritten and the data belonging to the + * previous entry is returned. + * + * @parameter name The name of the file (e.g. evdev). + * @parameter type Type of the file (XkbTypesIdx, ... or XkbSemanticsFile, ...) + * @parameter path The full path to the file. + * @parameter data Already parsed data. + * + * @return The data from the overwritten file or NULL. + */ +void * +XkbAddFileToCache(char *name, unsigned type, char *path, void *data) +{ + FileCacheEntry *entry; + + for (entry = fileCache; entry != NULL; entry = entry->next) + { + if ((type == entry->type) && (uStringEqual(name, entry->name))) + { + void *old = entry->data; + WSGO2("Replacing file cache entry (%s/%d)\n", name, type); + entry->path = path; + entry->data = data; + return old; + } + } + entry = uTypedAlloc(FileCacheEntry); + if (entry != NULL) + { + entry->name = name; + entry->type = type; + entry->path = path; + entry->data = data; + entry->next = fileCache; + fileCache = entry; + } + return NULL; +} + +/** + * Search for the given name + type in the cache. + * + * @parameter name The name of the file (e.g. evdev). + * @parameter type Type of the file (XkbTypesIdx, ... or XkbSemanticsFile, ...) + * @parameter pathRtrn Set to the full path of the given entry. + * + * @return the data from the cache entry or NULL if no matching entry was found. + */ +void * +XkbFindFileInCache(char *name, unsigned type, char **pathRtrn) +{ + FileCacheEntry *entry; + + for (entry = fileCache; entry != NULL; entry = entry->next) + { + if ((type == entry->type) && (uStringEqual(name, entry->name))) + { + *pathRtrn = entry->path; + return entry->data; + } + } + return NULL; +} + +/***====================================================================***/ + +/** + * Search for the given file name in the include directories. + * + * @param type one of XkbTypesIndex, XkbCompatMapIndex, ..., or + * XkbSemanticsFile, XkmKeymapFile, ... + * @param pathReturn is set to the full path of the file if found. + * + * @return an FD to the file or NULL. If NULL is returned, the value of + * pathRtrn is undefined. + */ +FILE * +XkbFindFileInPath(char *name, unsigned type, char **pathRtrn) +{ + register int i; + FILE *file = NULL; + int nameLen, typeLen, pathLen; + char buf[PATH_MAX], *typeDir; + + typeDir = XkbDirectoryForInclude(type); + nameLen = strlen(name); + typeLen = strlen(typeDir); + for (i = 0; i < nPathEntries; i++) + { + pathLen = strlen(includePath[i]); + if (typeLen < 1) + continue; + + if ((nameLen + typeLen + pathLen + 2) >= PATH_MAX) + { + ERROR3("File name (%s/%s/%s) too long\n", includePath[i], + typeDir, name); + ACTION("Ignored\n"); + continue; + } + snprintf(buf, sizeof(buf), "%s/%s/%s", includePath[i], typeDir, name); + file = fopen(buf, "r"); + if (file != NULL) + break; + } + + if ((file != NULL) && (pathRtrn != NULL)) + { + *pathRtrn = (char *) calloc(strlen(buf) + 1, sizeof(char)); + if (*pathRtrn != NULL) + strcpy(*pathRtrn, buf); + } + return file; +} |