summaryrefslogtreecommitdiff
path: root/app/xkbcomp/xkbpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/xkbcomp/xkbpath.c')
-rw-r--r--app/xkbcomp/xkbpath.c486
1 files changed, 292 insertions, 194 deletions
diff --git a/app/xkbcomp/xkbpath.c b/app/xkbcomp/xkbpath.c
index 0a7329c8e..68020129e 100644
--- a/app/xkbcomp/xkbpath.c
+++ b/app/xkbcomp/xkbpath.c
@@ -1,4 +1,3 @@
-/* $Xorg: xkbpath.c,v 1.3 2000/08/17 19:54:34 cpqbld Exp $ */
/************************************************************
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
@@ -24,12 +23,10 @@
THE USE OR PERFORMANCE OF THIS SOFTWARE.
********************************************************/
-/* $XFree86: xc/programs/xkbcomp/xkbpath.c,v 3.7 2002/06/05 00:00:38 dawes Exp $ */
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
-#define DEBUG_VAR_NOT_LOCAL
#define DEBUG_VAR debugFlags
#include "utils.h"
#include <stdlib.h>
@@ -44,87 +41,130 @@
#define PATH_MAX 1024
#endif
-#define PATH_CHUNK 8
+#define PATH_CHUNK 8 /* initial szPath */
-static Bool noDefaultPath = False;
-static int longestPath;
-static int szPath;
-static int nPathEntries;
-static char ** includePath;
+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)
+XkbParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
+ char *nextop_rtrn, char **extra_data)
{
-char *tmp,*str,*next;
+ char *tmp, *str, *next;
- str= *str_inout;
- if ((*str=='+')||(*str=='|')) {
- *file_rtrn= *map_rtrn= NULL;
- *nextop_rtrn= *str;
- next= str+1;
+ 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 if (*str == '%')
+ {
+ *file_rtrn = *map_rtrn = NULL;
+ *nextop_rtrn = str[1];
+ next = str + 2;
}
- else {
- next= strpbrk(str,"|+");
- if (next) {
- *nextop_rtrn= *next;
- *next++= '\0';
- }
- else {
- *nextop_rtrn= '\0';
- next= NULL;
- }
- 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);
- }
+ 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;
+ 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;
+ szPath = PATH_CHUNK;
+ includePath = (char **) calloc(szPath, sizeof(char *));
+ if (includePath == NULL)
+ return False;
return True;
}
@@ -132,191 +172,249 @@ void
XkbAddDefaultDirectoriesToPath(void)
{
if (noDefaultPath)
- return;
+ return;
XkbAddDirectoryToPath(DFLT_XKB_CONFIG_ROOT);
}
+/**
+ * Remove all entries from the global includePath.
+ */
void
XkbClearIncludePath(void)
{
-register int i;
+ register int i;
- if (szPath>0) {
- for (i=0;i<nPathEntries;i++) {
- if (includePath[i]!=NULL) {
- uFree(includePath[i]);
- includePath[i]= NULL;
- }
- }
- nPathEntries= 0;
- longestPath= 0;
+ 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;
+ int len;
+ if ((dir == NULL) || (dir[0] == '\0'))
+ {
+ XkbClearIncludePath();
+ return True;
}
#ifdef __UNIXOS2__
- dir = (char*)__XOS2RedirRoot(dir);
+ 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;
+ 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 (len>longestPath)
- longestPath= len;
- if (nPathEntries>=szPath) {
- szPath+= PATH_CHUNK;
- includePath= (char **)realloc(includePath,szPath*sizeof(char *));
- if (includePath==NULL) {
- WSGO("Allocation failed (includePath)\n");
- 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;
+ 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);
+ 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];
+ 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;
+ 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;
+typedef struct _FileCacheEntry
+{
+ char *name;
+ unsigned type;
+ char *path;
+ void *data;
+ struct _FileCacheEntry *next;
} FileCacheEntry;
-static FileCacheEntry *fileCache;
+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)
+XkbAddFileToCache(char *name, unsigned type, char *path, void *data)
{
-FileCacheEntry *entry;
+ 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;
- }
+ 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;
+ 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)
+XkbFindFileInCache(char *name, unsigned type, char **pathRtrn)
{
-FileCacheEntry *entry;
+ FileCacheEntry *entry;
- for (entry=fileCache;entry!=NULL;entry=entry->next) {
- if ((type==entry->type)&&(uStringEqual(name,entry->name))) {
- *pathRtrn= entry->path;
- return entry->data;
- }
+ 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)
+XkbFindFileInPath(char *name, unsigned type, char **pathRtrn)
{
-register int i;
-FILE *file= NULL;
-int nameLen,typeLen,pathLen;
-char buf[PATH_MAX],*typeDir;
+ 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;
+ 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;
- }
- sprintf(buf,"%s/%s/%s",includePath[i],typeDir,name);
- file= fopen(buf,"r");
- if (file!=NULL)
- break;
+ 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);
+ if ((file != NULL) && (pathRtrn != NULL))
+ {
+ *pathRtrn = (char *) calloc(strlen(buf) + 1, sizeof(char));
+ if (*pathRtrn != NULL)
+ strcpy(*pathRtrn, buf);
}
return file;
}
-