diff options
Diffstat (limited to 'app/xkbcomp/xkbpath.c')
-rw-r--r-- | app/xkbcomp/xkbpath.c | 486 |
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; } - |