diff options
Diffstat (limited to 'listing.c')
-rw-r--r-- | listing.c | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/listing.c b/listing.c new file mode 100644 index 0000000..c87e178 --- /dev/null +++ b/listing.c @@ -0,0 +1,500 @@ +/* $Xorg: listing.c,v 1.5 2001/02/09 02:05:49 xorgcvs Exp $ */ +/************************************************************ + Copyright 1996 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. + + ********************************************************/ +/*********************************************************** + +Copyright 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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 <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <X11/keysym.h> + +#if defined(sgi) +#include <malloc.h> +#endif + +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR listingDebug +#include "xkbcomp.h" +#ifndef X_NOT_STDC_ENV +#include <stdlib.h> +#endif +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#ifndef PATH_MAX +#ifdef WIN32 +#define PATH_MAX 512 +#else +#include <sys/param.h> +#endif +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + +#ifdef WIN32 +#define BOOL wBOOL +#include <windows.h> +#undef BOOL +#define FileName(file) file.cFileName +#else +#define FileName(file) file->d_name +#ifndef X_NOT_POSIX +#include <dirent.h> +#else +#ifdef SYSV +#include <dirent.h> +#else +#ifdef USG +#include <dirent.h> +#else +#include <sys/dir.h> +#ifndef dirent +#define dirent direct +#endif +#endif +#endif +#endif +#endif + +#include "xkbpath.h" +#include "parseutils.h" +#include "misc.h" +#include "tokens.h" +#include <X11/extensions/XKBgeom.h> + +#define lowbit(x) ((x) & (-(x))) + +static int szListing= 0; +static int nListed= 0; +static int nFilesListed= 0; + +typedef struct _Listing { + char * file; + char * map; +} Listing; + +static int szMapOnly; +static int nMapOnly; +static char ** mapOnly; + +static Listing * list= NULL; + +/***====================================================================***/ + +int +#if NeedFunctionPrototypes +AddMapOnly(char *map) +#else +AddMapOnly(map) + char *map; +#endif +{ + if (nMapOnly>=szMapOnly) { + if (szMapOnly<1) szMapOnly= 5; + else szMapOnly*= 2; + mapOnly= uTypedRealloc(list,szMapOnly,char *); + if (!mapOnly) { + WSGO("Couldn't allocate list of maps\n"); + return 0; + } + } + mapOnly[nMapOnly++]= map; + return 1; +} + +int +#if NeedFunctionPrototypes +AddListing(char *file,char *map) +#else +AddListing(file,map) + char *file; + char *map; +#endif +{ + if (nListed>=szListing) { + if (szListing<1) szListing= 10; + else szListing*= 2; + list= uTypedRealloc(list,szListing,Listing); + if (!list) { + WSGO("Couldn't allocate list of files and maps\n"); + ACTION("Exiting\n"); + exit(1); + } + } + + list[nListed].file= file; + list[nListed].map= map; + nListed++; + if (file!=NULL) + nFilesListed++; + return 1; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +ListFile(FILE *outFile,char *fileName,XkbFile *map) +#else +ListFile(outFile,fileName,map) +FILE * outFile; +char * fileName; +XkbFile * map; +#endif +{ +register unsigned flags; +char * mapName; + + flags= map->flags; + if ((flags&XkbLC_Hidden)&&(!(verboseLevel&WantHiddenMaps))) + return; + if ((flags&XkbLC_Partial)&&(!(verboseLevel&WantPartialMaps))) + return; + if (verboseLevel&WantLongListing) { + fprintf(outFile,(flags&XkbLC_Hidden)?"h":"-"); + fprintf(outFile,(flags&XkbLC_Default)?"d":"-"); + fprintf(outFile,(flags&XkbLC_Partial)?"p":"-"); + fprintf(outFile,"----- "); + if (map->type==XkmSymbolsIndex) { + fprintf(outFile,(flags&XkbLC_AlphanumericKeys)?"a":"-"); + fprintf(outFile,(flags&XkbLC_ModifierKeys)?"m":"-"); + fprintf(outFile,(flags&XkbLC_KeypadKeys)?"k":"-"); + fprintf(outFile,(flags&XkbLC_FunctionKeys)?"f":"-"); + fprintf(outFile,(flags&XkbLC_AlternateGroup)?"g":"-"); + fprintf(outFile,"--- "); + } + else fprintf(outFile,"-------- "); + } + mapName= map->name; + if ((!(verboseLevel&WantFullNames))&&((flags&XkbLC_Default)!=0)) + mapName= NULL; + if (dirsToStrip>0) { + char *tmp,*last; + int i; + for (i=0,tmp=last=fileName;(i<dirsToStrip)&&tmp;i++) { + last= tmp; + tmp= strchr(tmp,'/'); + if (tmp!=NULL) + tmp++; + } + fileName= (tmp?tmp:last); + } + if (mapName) + fprintf(outFile,"%s(%s)\n",fileName,mapName); + else fprintf(outFile,"%s\n",fileName); + return; +} + +/***====================================================================***/ + +static int +#if NeedFunctionPrototypes +AddDirectory(char *head,char *ptrn,char *rest,char *map) +#else +AddDirectory(head,ptrn,rest,map) + char * head; + char * ptrn; + char * rest; + char * map; +#endif +{ +#ifdef WIN32 + HANDLE dirh; + WIN32_FIND_DATA file; +#else + DIR *dirp; + struct dirent *file; +#endif + int nMatch; + + if (map==NULL) { + char *tmp = ptrn; + if ((rest==NULL)&&(ptrn!=NULL)&&(strchr(ptrn,'/')==NULL)) { + tmp= ptrn; + map= strchr(ptrn,'('); + } + else if ((rest==NULL)&&(ptrn==NULL)&& + (head!=NULL)&&(strchr(head,'/')==NULL)) { + tmp= head; + map= strchr(head,'('); + } + if (map!=NULL) { + tmp= strchr(tmp,')'); + if ((tmp==NULL)||(tmp[1]!='\0')) { + ERROR("File and map must have the format file(map)\n"); + return 0; + } + *map= '\0'; map++; + *tmp= '\0'; + } + } +#ifdef WIN32 + if ((dirh = FindFirstFile("*.*", &file)) == INVALID_HANDLE_VALUE) + return 0; +#else + if ((dirp = opendir ((head?head:"."))) == NULL) + return 0; + nMatch= 0; +#endif +#ifdef WIN32 + do +#else + while ((file = readdir (dirp)) != NULL) +#endif + { + char *tmp,*filename; + struct stat sbuf; + + filename= FileName(file); + if (!filename || filename[0]=='.') + continue; + if (ptrn && (!XkbNameMatchesPattern(filename,ptrn))) + continue; + tmp= (char *)uAlloc((head?strlen(head):0)+strlen(filename)+2); + if (!tmp) + continue; + sprintf(tmp,"%s%s%s",(head?head:""),(head?"/":""),filename); + if (stat(tmp,&sbuf)<0) { + uFree(tmp); + continue; + } + if (((rest!=NULL)&&(!S_ISDIR(sbuf.st_mode)))|| + ((map!=NULL)&&(S_ISDIR(sbuf.st_mode)))) { + uFree(tmp); + continue; + } + if (S_ISDIR(sbuf.st_mode)) { + if ((rest!=NULL)||(verboseLevel&ListRecursive)) + nMatch+= AddDirectory(tmp,rest,NULL,map); + } + else nMatch+= AddListing(tmp,map); + } +#ifdef WIN32 + while (FindNextFile(dirh, &file)); +#endif + return nMatch; +} + +/***====================================================================***/ + +Bool +#if NeedFunctionPrototypes +AddMatchingFiles(char *head_in) +#else +AddMatchingFiles(head_in) + char * head_in; +#endif +{ +char *str,*head,*ptrn,*rest= NULL; + + if (head_in==NULL) + return 0; + ptrn= NULL; + for (str=head_in;(*str!='\0')&&(*str!='?')&&(*str!='*');str++) { + if ((str!=head_in)&&(*str=='/')) + ptrn= str; + } + if (*str=='\0') { /* no wildcards */ + head= head_in; + ptrn= NULL; + rest= NULL; + } + else if (ptrn==NULL) { /* no slash before the first wildcard */ + head= NULL; + ptrn= head_in; + } + else { /* slash followed by wildcard */ + head= head_in; + *ptrn= '\0'; ptrn++; + } + if (ptrn) { + rest= strchr(ptrn,'/'); + if (rest!=NULL) { + *rest= '\0'; + rest++; + } + } + if(((rest && ptrn)&&((strchr(ptrn,'(')!=NULL)||(strchr(ptrn,')')!=NULL)))|| + (head && ((strchr(head,'(')!=NULL)||(strchr(head,')')!=NULL)))) { + ERROR("Files/maps to list must have the form file(map)\n"); + ACTION("Illegal specifier ignored\n"); + return 0; + } + return AddDirectory(head,ptrn,rest,NULL); +} + +/***====================================================================***/ + +Bool +MapMatches(mapToConsider,ptrn) + char * mapToConsider; + char * ptrn; +{ +int i; + + if (ptrn!=NULL) + return XkbNameMatchesPattern(mapToConsider,ptrn); + if (nMapOnly<1) + return True; + for (i=0;i<nMapOnly;i++) { + if (XkbNameMatchesPattern(mapToConsider,mapOnly[i])) + return True; + } + return False; +} + +int +#if NeedFunctionPrototypes +GenerateListing(char *out_name) +#else +GenerateListing(out_name) + char * out_name; +#endif +{ +int i; +FILE * inputFile,*outFile; +XkbFile * rtrn,*mapToUse; +unsigned oldWarningLevel; +char * mapName; + + if (nFilesListed<1) { + ERROR("Must specify at least one file or pattern to list\n"); + return 0; + } + if ((!out_name)||((out_name[0]=='-')&&(out_name[1]=='\0'))) + outFile= stdout; + else if ((outFile=fopen(out_name,"w"))==NULL) { + ERROR1("Cannot open \"%s\" to write keyboard description\n",out_name); + ACTION("Exiting\n"); + return 0; + } +#ifdef DEBUG + if (warningLevel>9) + fprintf(stderr,"should list:\n"); +#endif + for (i=0;i<nListed;i++) { +#ifdef DEBUG + if (warningLevel>9) { + fprintf(stderr,"%s(%s)\n",(list[i].file?list[i].file:"*"), + (list[i].map?list[i].map:"*")); + } +#endif + oldWarningLevel= warningLevel; + warningLevel= 0; + if (list[i].file) { + struct stat sbuf; + + if (stat(list[i].file,&sbuf)<0) { + if (oldWarningLevel>5) + WARN1("Couldn't open \"%s\"\n",list[i].file); + continue; + } + if (S_ISDIR(sbuf.st_mode)) { + if (verboseLevel&ListRecursive) + AddDirectory(list[i].file,NULL,NULL,NULL); + continue; + } + + inputFile= fopen(list[i].file,"r"); + if (!inputFile) { + if (oldWarningLevel>5) + WARN1("Couldn't open \"%s\"\n",list[i].file); + continue; + } + if (XKBParseFile(inputFile,&rtrn)&&(rtrn!=NULL)) { + mapName= list[i].map; + mapToUse= rtrn; + for (;mapToUse;mapToUse= (XkbFile *)mapToUse->common.next) { + if (!MapMatches(mapToUse->name,mapName)) + continue; + ListFile(outFile,list[i].file,mapToUse); + } + } + fclose(inputFile); + } + warningLevel= oldWarningLevel; + } + return 1; +} + |