diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/fsys.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/fsys.c | 487 |
1 files changed, 487 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/fsys.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/fsys.c new file mode 100644 index 00000000000..dfad4bd395e --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/fsys.c @@ -0,0 +1,487 @@ +/* Copyright (C) 2000-2004 by George Williams */ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + + * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include "ustring.h" +#include "fileutil.h" +#include "gfile.h" +#include <sys/types.h> +#include <sys/stat.h> /* for mkdir */ +#include <unistd.h> + +#ifdef _WIN32 +#define MKDIR(A,B) mkdir(A) +#else +#define MKDIR(A,B) mkdir(A,B) +#endif + +static char dirname_[1024]; + +char *GFileGetAbsoluteName(char *name, char *result, int rsiz) { + /* result may be the same as name */ + char buffer[1000]; + + if ( *name!='/' ) { + char *pt, *spt, *rpt, *bpt; + + if ( dirname_[0]=='\0' ) { + getcwd(dirname_,sizeof(dirname_)); + } + strcpy(buffer,dirname_); + if ( buffer[strlen(buffer)-1]!='/' ) + strcat(buffer,"/"); + strcat(buffer,name); + + /* Normalize out any .. */ + spt = rpt = buffer; + while ( *spt!='\0' ) { + if ( *spt=='/' ) ++spt; + for ( pt = spt; *pt!='\0' && *pt!='/'; ++pt ); + if ( pt==spt ) /* Found // in a path spec, reduce to / (we've*/ + strcpy(spt,pt); /* skipped past the :// of the machine name) */ + else if ( pt==spt+1 && spt[0]=='.' ) /* Noop */ + strcpy(spt,pt); + else if ( pt==spt+2 && spt[0]=='.' && spt[1]=='.' ) { + for ( bpt=spt-2 ; bpt>rpt && *bpt!='/'; --bpt ); + if ( bpt>=rpt && *bpt=='/' ) { + strcpy(bpt,pt); + spt = bpt; + } else { + rpt = pt; + spt = pt; + } + } else + spt = pt; + } + name = buffer; + if ( rsiz>sizeof(buffer)) rsiz = sizeof(buffer); /* Else valgrind gets unhappy */ + } + if (result!=name) { + strncpy(result,name,rsiz); + result[rsiz-1]='\0'; + } +return(result); +} + +char *GFileMakeAbsoluteName(char *name) { + char buffer[1025]; + + GFileGetAbsoluteName(name,buffer,sizeof(buffer)); +return( copy(buffer)); +} + +char *GFileBuildName(char *dir,char *fname,char *buffer,int size) { + int len; + + if ( dir==NULL || *dir=='\0' ) { + if ( strlen( fname )<size-1 ) /* valgrind didn't like my strncpies but this complication makes it happy */ + strcpy(buffer,fname); + else { + strncpy(buffer,fname,size-1); + buffer[size-1]='\0'; + } + } else { + if ( buffer!=dir ) { + if ( strlen( dir )<size-3 ) + strcpy(buffer,dir); + else { + strncpy(buffer,dir,size-3); + buffer[size-3]='\0'; + } + } + len = strlen(buffer); + if ( buffer[len-1]!='/' ) + buffer[len++] = '/'; + if ( strlen( fname )<size-1 ) + strcpy(buffer+len,fname); + else { + strncpy(buffer+len,fname,size-len-1); + buffer[size-1]='\0'; + } + } +return( buffer ); +} + +/* Given a filename in a directory, pick the directory out of it, and */ +/* create a new filename using that directory and the given nametail */ +char *GFileReplaceName(char *oldname,char *fname,char *buffer,int size) { + int len; + char *dirend; + + dirend = strrchr(oldname,'/'); + if ( dirend == NULL ) { + strncpy(buffer,fname,size-1); + buffer[size-1]='\0'; + } else { + *dirend = '\0'; + if ( buffer!=oldname ) { + strncpy(buffer,oldname,size-3); + buffer[size-3]='\0'; + } + len = strlen(buffer); + *dirend = '/'; + buffer[len++] = '/'; + strncpy(buffer+len,fname,size-len-1); + buffer[size-1]='\0'; + } +return( buffer ); +} + +char *GFileNameTail(const char *oldname) { + char *pt; + + pt = strrchr(oldname,'/'); + if ( pt !=NULL ) +return( pt+1); + else +return( (char *)oldname ); +} + +char *GFileAppendFile(char *dir,char *name,int isdir) { + char *ret, *pt; + + ret = galloc((strlen(dir)+strlen(name)+3)); + strcpy(ret,dir); + pt = ret+strlen(ret); + if ( pt>ret && pt[-1]!='/' ) + *pt++ = '/'; + strcpy(pt,name); + if ( isdir ) { + pt += strlen(pt); + if ( pt>ret && pt[-1]!='/' ) { + *pt++ = '/'; + *pt = '\0'; + } + } +return(ret); +} + +int GFileIsAbsolute(const char *file) { + if ( *file=='/' ) +return( true ); + if ( strstr(file,"://")!=NULL ) +return( true ); + +return( false ); +} + +int GFileIsDir(const char *file) { +#ifdef _WIN32 + struct stat info; + if (stat(file, &info)) +return 0; + else +return ((info.st_mode&_S_IFDIR)); +#else + char buffer[1000]; + sprintf(buffer,"%s/.",file); +return( access(buffer,0)==0 ); +#endif +} + +int GFileExists(const char *file) { +return( access(file,0)==0 ); +} + +int GFileModifyable(const char *file) { +return( access(file,02)==0 ); +} + +int GFileModifyableDir(const char *file) { + char buffer[1024], *pt; + + strcpy(buffer,file); + pt = strrchr(buffer,'/'); + if ( pt==NULL ) + strcpy(buffer,"."); + else + *pt='\0'; +return( GFileModifyable(buffer)); +} + +int GFileReadable(char *file) { +return( access(file,04)==0 ); +} + +int GFileMkDir(char *name) { +return( MKDIR(name,0755)); +} + +int GFileRmDir(char *name) { +return(rmdir(name)); +} + +int GFileUnlink(char *name) { +return(unlink(name)); +} + +char *_GFile_find_program_dir(char *prog) { + char *pt, *path, *program_dir=NULL; + char filename[2000]; + + if ( (pt = strrchr(prog,'/'))!=NULL ) + program_dir = copyn(prog,pt-prog); + else if ( (path = getenv("PATH"))!=NULL ) { + while ((pt = strchr(path,':'))!=NULL ) { + sprintf(filename,"%.*s/%s", (int)(pt-path), path, prog); + /* Under cygwin, applying access to "potrace" will find "potrace.exe" */ + /* no need for special check to add ".exe" */ + if ( access(filename,1)!= -1 ) { + program_dir = copyn(path,pt-path); + break; + } + path = pt+1; + } + if ( program_dir==NULL ) { + sprintf(filename,"%s/%s", path, prog); + if ( access(filename,1)!= -1 ) + program_dir = copy(path); + } + } + if ( program_dir==NULL ) +return( NULL ); + GFileGetAbsoluteName(program_dir,filename,sizeof(filename)); + gfree(program_dir); + program_dir = copy(filename); +return( program_dir ); +} + +unichar_t *u_GFileGetAbsoluteName(unichar_t *name, unichar_t *result, int rsiz) { + /* result may be the same as name */ + unichar_t buffer[1000]; + + if ( *name!='/' ) { + unichar_t *pt, *spt, *rpt, *bpt; + + if ( dirname_[0]=='\0' ) { + getcwd(dirname_,sizeof(dirname_)); + } + uc_strcpy(buffer,dirname_); + if ( buffer[u_strlen(buffer)-1]!='/' ) + uc_strcat(buffer,"/"); + u_strcat(buffer,name); + + /* Normalize out any .. */ + spt = rpt = buffer; + while ( *spt!='\0' ) { + if ( *spt=='/' ) ++spt; + for ( pt = spt; *pt!='\0' && *pt!='/'; ++pt ); + if ( pt==spt ) /* Found // in a path spec, reduce to / (we've*/ + u_strcpy(spt,pt); /* skipped past the :// of the machine name) */ + else if ( pt==spt+1 && spt[0]=='.' ) /* Noop */ + u_strcpy(spt,pt); + else if ( pt==spt+2 && spt[0]=='.' && spt[1]=='.' ) { + for ( bpt=spt-2 ; bpt>rpt && *bpt!='/'; --bpt ); + if ( bpt>=rpt && *bpt=='/' ) { + u_strcpy(bpt,pt); + spt = bpt; + } else { + rpt = pt; + spt = pt; + } + } else + spt = pt; + } + name = buffer; + } + if (result!=name) { + u_strncpy(result,name,rsiz); + result[rsiz-1]='\0'; + } +return(result); +} + +unichar_t *u_GFileBuildName(unichar_t *dir,unichar_t *fname,unichar_t *buffer,int size) { + int len; + + if ( dir==NULL || *dir=='\0' ) { + u_strncpy(buffer,fname,size-1); + buffer[size-1]='\0'; + } else { + if ( buffer!=dir ) { + u_strncpy(buffer,dir,size-3); + buffer[size-3]='\0'; + } + len = u_strlen(buffer); + if ( buffer[len-1]!='/' ) + buffer[len++] = '/'; + u_strncpy(buffer+len,fname,size-len-1); + buffer[size-1]='\0'; + } +return( buffer ); +} + +/* Given a filename in a directory, pick the directory out of it, and */ +/* create a new filename using that directory and the given nametail */ +unichar_t *u_GFileReplaceName(unichar_t *oldname,unichar_t *fname,unichar_t *buffer,int size) { + int len; + unichar_t *dirend; + + dirend = u_strrchr(oldname,'/'); + if ( dirend == NULL ) { + u_strncpy(buffer,fname,size-1); + buffer[size-1]='\0'; + } else { + *dirend = '\0'; + if ( buffer!=oldname ) { + u_strncpy(buffer,oldname,size-3); + buffer[size-3]='\0'; + } + len = u_strlen(buffer); + *dirend = '/'; + buffer[len++] = '/'; + u_strncpy(buffer+len,fname,size-len-1); + buffer[size-1]='\0'; + } +return( buffer ); +} + +unichar_t *u_GFileNameTail(const unichar_t *oldname) { + unichar_t *pt; + + pt = u_strrchr(oldname,'/'); + if ( pt !=NULL ) +return( pt+1); + else +return( (unichar_t *)oldname ); +} + +unichar_t *u_GFileNormalize(unichar_t *name) { + unichar_t *pt, *base, *ppt; + + if ( (pt = uc_strstr(name,"://"))!=NULL ) { + base = u_strchr(pt+3,'/'); + if ( base==NULL ) +return( name ); + ++base; + } else if ( *name=='/' ) + base = name+1; + else + base = name; + for ( pt=base; *pt!='\0'; ) { + if ( *pt=='/' ) + u_strcpy(pt,pt+1); + else if ( uc_strncmp(pt,"./",2)==0 ) + u_strcpy(pt,pt+2); + else if ( uc_strncmp(pt,"../",2)==0 ) { + for ( ppt=pt-2; ppt>=base && *ppt!='/'; --ppt ); + ++ppt; + if ( ppt>=base ) { + u_strcpy(ppt,pt+3); + pt = ppt; + } else + pt += 3; + } else { + while ( *pt!='/' && *pt!='\0' ) ++pt; + if ( *pt == '/' ) ++pt; + } + } +return( name ); +} + +unichar_t *u_GFileAppendFile(unichar_t *dir,unichar_t *name,int isdir) { + unichar_t *ret, *pt; + + ret = galloc((u_strlen(dir)+u_strlen(name)+3)*sizeof(unichar_t)); + u_strcpy(ret,dir); + pt = ret+u_strlen(ret); + if ( pt>ret && pt[-1]!='/' ) + *pt++ = '/'; + u_strcpy(pt,name); + if ( isdir ) { + pt += u_strlen(pt); + if ( pt>ret && pt[-1]!='/' ) { + *pt++ = '/'; + *pt = '\0'; + } + } +return(ret); +} + +int u_GFileIsAbsolute(const unichar_t *file) { + if ( *file=='/' ) +return( true ); + if ( uc_strstr(file,"://")!=NULL ) +return( true ); + +return( false ); +} + +int u_GFileIsDir(const unichar_t *file) { + char buffer[1024]; + cu_strcpy(buffer,file); + strcat(buffer,"/."); +return( access(buffer,0)==0 ); +} + +int u_GFileExists(const unichar_t *file) { + char buffer[1024]; + cu_strcpy(buffer,file); +return( access(buffer,0)==0 ); +} + +int u_GFileModifyable(const unichar_t *file) { + char buffer[1024]; + cu_strcpy(buffer,file); +return( access(buffer,02)==0 ); +} + +int u_GFileModifyableDir(const unichar_t *file) { + char buffer[1024], *pt; + + cu_strcpy(buffer,file); + pt = strrchr(buffer,'/'); + if ( pt==NULL ) + strcpy(buffer,"."); + else + *pt='\0'; +return( GFileModifyable(buffer)); +} + +int u_GFileReadable(unichar_t *file) { + char buffer[1024]; + cu_strcpy(buffer,file); +return( access(buffer,04)==0 ); +} + +int u_GFileMkDir(unichar_t *name) { + char buffer[1024]; + cu_strcpy(buffer,name); +return( MKDIR(buffer,0755)); +} + +int u_GFileRmDir(unichar_t *name) { + char buffer[1024]; + cu_strcpy(buffer,name); +return(rmdir(buffer)); +} + +int u_GFileUnlink(unichar_t *name) { + char buffer[1024]; + cu_strcpy(buffer,name); +return(unlink(buffer)); +} |