/**************************************************************************** PARAMETERS: dir - path to store fntcache.inf in cache - cache structure to save REMARKS: Attempt to save fonts cache information to file fntcache.inf in the directory. Silently fails if the directory is not writeable. SEE ALSO: loadFontCache {secret} ****************************************************************************/ static void saveFontCache( const char *dir, dirCache *cache) { char filename[PM_MAX_PATH]; FILE *f; size_t i; if (cache->validCnt == 0) return; strcpy(filename, dir); PM_backslash(filename); strcat(filename, CACHE_FILE); f = __MGL_fopen(filename, "wt"); if (f == NULL) return; qsort(cache->files, cache->filesCnt, sizeof(fileCache), comparFileCache); fprintf(f, "%li\n", cache->validCnt); for (i = 0; i < cache->filesCnt; i++) { if (!cache->files[i].exists) continue; fprintf(f, "%s\t%c-%c-%c-%c\t%s\n", cache->files[i].fileName, cache->files[i].fontLibType + '0', cache->files[i].isFixed ? 'f' : 'p', cache->files[i].isBold ? 'b' : 'n', cache->files[i].isItalic ? 'i' : 'n', cache->files[i].familyName); } __MGL_fclose(f); }
/**************************************************************************** REMARKS: Return the path to the SNAP configuration files. ****************************************************************************/ const char * PMAPI PM_getSNAPConfigPath(void) { static char path[256]; strcpy(path,PM_getSNAPPath()); PM_backslash(path); strcat(path,"config"); return path; }
/**************************************************************************** DESCRIPTION: Initializes font information cache. REMARKS: Scans standard locations for fonts and stores all found font families to _MGL_fontEnumCache global variable. Called by MGL_enumerateFonts upon first invocation. {secret} ****************************************************************************/ void _MGL_initFontEnumCache(void) { char path[PM_MAX_PATH]; enumFontsInDir(".", &_MGL_fontEnumCache); path[0] = '\0'; if (_MGL_path[0] != '\0') { strcpy(path, _MGL_path); PM_backslash(path); } strcat(path, MGL_FONTS); enumFontsInDir(path, &_MGL_fontEnumCache); if (getenv(MGL_ROOT)) { strcpy(path, getenv(MGL_ROOT)); PM_backslash(path); strcat(path, MGL_FONTS); enumFontsInDir(path, &_MGL_fontEnumCache); } }
/**************************************************************************** DESCRIPTION: Restricts the output from the display device context to a specified output region. HEADER: mgraph.h PARAMETERS: dir - MGL directory to find the find under name - Name of the file to open REMARKS: Attempts to open the specified MGL file in binary mode. This routine will use the standard MGL directory searching algorithm to find the specified file. First an attempt is made to locate the file in the current directory. Then we search in the directory relative to the current directory. If that fails, we then search relative to the _MGL_path variable (initialized by the application program via the MGL_init call). If this fails, an attempt is made to search for the file relative to the MGL_ROOT environment variable if this is present. {secret} ****************************************************************************/ ibool MGLAPI _MGL_findFile( char *validpath, const char *dir, const char *name, const char *mode) { FILE *f; /* First try opening the file with just the file name (checking for * local directories and an explicit file path). */ strcpy(validpath,name); if ((f = __MGL_fopen(validpath,mode)) == NULL) { strcpy(validpath, dir); PM_backslash(validpath); strcat(validpath, name); if ((f = __MGL_fopen(validpath,mode)) == NULL) { validpath[0] = '\0'; if (_MGL_path[0] != '\0') { strcpy(validpath, _MGL_path); PM_backslash(validpath); } strcat(validpath, dir); PM_backslash(validpath); strcat(validpath, name); if ((f = __MGL_fopen(validpath,mode)) == NULL) { /* Search the environment variable */ if (getenv(MGL_ROOT)) { strcpy(validpath, getenv(MGL_ROOT)); PM_backslash(validpath); strcat(validpath, dir); PM_backslash(validpath); strcat(validpath, name); f = __MGL_fopen(validpath, mode); } } } } if (f) __MGL_fclose(f); return (f != NULL); }
const char * PMAPI PM_getSNAPConfigPath(void) { static char path[512]; char *env; #ifdef __QNXNTO__ char temp[64]; gethostname(temp, sizeof (temp)); temp[sizeof (temp) - 1] = '\0'; /* Paranoid */ sprintf(path,"/etc/config/scitech/%s/config", temp); #else sprintf(path,"/etc/config/scitech/%d/config", getnid()); #endif if ((env = getenv("SNAP_PATH")) != NULL) { strcpy(path,env); PM_backslash(path); strcat(path,"config"); } return path; }
void findRemovedFiles( const char *path) { FILE *log,*f; char buf[PM_MAX_PATH]; char buf2[PM_MAX_PATH]; char *p; int i,len; if ((f = fopen(path,"r")) == NULL) PM_fatalError("Unable to open temporary file"); if ((log = fopen(tempPath,"w")) == NULL) PM_fatalError("Unable to open temporary file"); while (!feof(f)) { if (fgets(buf,sizeof(buf),f) && (len = strlen(buf)) > CVS_DEPOT_LEN) { p = buf+CVS_DEPOT_LEN; // Skip past //depot//cvs/ len -= CVS_DEPOT_LEN; if (p[len-1] == '\n') p[--len] = 0; #ifndef __UNIX__ for (i = 0; i < len; i++) { if (p[i] == '/') p[i] = '\\'; } strlwr(p); #endif for (i = 0; i < len; i++) { if (p[i] == '#') { p[i] = 0; break; } } strcpy(buf2,CVS_ROOT); PM_backslash(buf2); strcat(buf2,p); if (access(buf2,0) != 0) fprintf(log,"%s\n", buf2); } } fclose(log); fclose(f); }
/**************************************************************************** PARAMETERS: path - directory to scan for fonts wildcard - wildcard to match. cache - local cache for one directory REMARKS: Enumerates fonts in path matching wildard and puts information about them into directory cache cache. {secret} ****************************************************************************/ static void enumFontsByWildcard( const char *path, const char *wildcard, dirCache *cache) { char fullwild[PM_MAX_PATH]; PM_findData findData; void *handle; strcpy(fullwild, path); PM_backslash(fullwild); strcat(fullwild, wildcard); findData.dwSize = sizeof(findData); handle = PM_findFirstFile(fullwild, &findData); if (handle == PM_FILE_INVALID) return; do { enumFontFile(path, findData.name, cache); } while (PM_findNextFile(handle, &findData)); PM_findClose(handle); }
void recurseCollectFiles( FILE *log, const char *path, const char *fileMask, ibool logCVS) { PM_findData findData; void *hfile; int done; char files[PM_MAX_PATH]; char name[PM_MAX_PATH]; // First dump all matching files findData.dwSize = sizeof(findData); strcpy(files,path); if (strlen(path) > 0) PM_backslash(files); #ifndef __UNIX__ if (strcmp(fileMask,"*") == 0) strcat(files,"*.*"); else #endif strcat(files,fileMask); done = (hfile = PM_findFirstFile(files,&findData)) == PM_FILE_INVALID; while (!done) { strcpy(name,path); if (strlen(path) > 0) PM_backslash(name); strcat(name,findData.name); if (!(findData.attrib & PM_FILE_DIRECTORY)) fprintf(log,"%s\n", name); done = !PM_findNextFile(hfile,&findData); } if (hfile != PM_FILE_INVALID) PM_findClose(hfile); // Now recurse all subdirectories strcpy(files,path); if (strlen(path) > 0) PM_backslash(files); #ifdef __UNIX__ strcat(files,"*"); #else strcat(files,"*.*"); #endif done = (hfile = PM_findFirstFile(files,&findData)) == PM_FILE_INVALID; while (!done) { if ((strcmp(findData.name,".") != 0) && (strcmp(findData.name,"..") != 0)) { if (findData.attrib & PM_FILE_DIRECTORY) { strcpy(name,path); if (strlen(path) > 0) PM_backslash(name); strcat(name,findData.name); if (logCVS && (strcmp(findData.name,"CVS") == 0 || strcmp(findData.name,"CVSROOT") == 0)) { recurseCollectFiles(log,name,"*",false); } else recurseCollectFiles(log,name,fileMask,logCVS); } } done = !PM_findNextFile(hfile,&findData); } }
int main(int argc,char *argv[]) { char *p,*branch; char command[PM_MAX_PATH]; char drive[PM_MAX_DRIVE]; char dir[PM_MAX_PATH]; char name[PM_MAX_PATH]; char ext[PM_MAX_PATH]; ibool checkout = false; if (argc >= 2 && stricmp(argv[1],"-c") == 0) { checkout = true; argc--; argv++; } if (argc != 2 && argc != 3) { printf("Usage: p4_cvs [-c] <cvs command> <cvs branch>\n"); return 0; } if (argc == 3) branch = argv[2]; else branch = NULL; if ((p = getenv("TEMP")) == NULL) { if ((p = getenv("TMP")) == NULL) PM_fatalError("Unable to find temporary directory!"); } PM_splitpath(p,drive,dir,name,ext); PM_backslash(dir); strcat(dir,name); PM_splitpath(tmpnam(NULL),NULL,NULL,name,ext); PM_makepath(tempPath,drive,dir,name,ext); PM_splitpath(tmpnam(NULL),NULL,NULL,name,ext); PM_makepath(tempPath2,drive,dir,name,ext); PM_splitpath(logName,NULL,NULL,name,ext); PM_makepath(logPath,drive,dir,name,ext); #ifndef __UNIX__ strlwr(tempPath); strlwr(tempPath2); strlwr(logPath); #endif remove(logPath); printf("Opening CVS files in Perforce ... "); fflush(stdout); collectFiles("*",true,false); sprintf(command,"p4p -x %s open >>& %s",tempPath,logPath); system(command); printf("Done\n"); fflush(stdout); if (checkout) { printf("Removing Perforce files ... "); fflush(stdout); sprintf(command,"k_rm -rf *",tempPath,logPath); system(command); printf("Done\n"); fflush(stdout); } printf("Syncing to latest CVS files ... "); fflush(stdout); if (checkout) { if (branch) sprintf(command,"%s checkout -r %s >>& %s",argv[1],branch,logPath); else sprintf(command,"%s checkout . >>& %s",argv[1],logPath); } else { if (branch) sprintf(command,"%s update -r %s >>& %s",argv[1],branch,logPath); else sprintf(command,"%s update . >>& %s",argv[1],logPath); } system(command); printf("Done\n"); fflush(stdout); printf("Adding new files to Perforce ... "); fflush(stdout); collectFiles("*",true,false); sprintf(command,"p4p -x %s add >>& %s",tempPath,logPath); system(command); printf("Done\n"); fflush(stdout); printf("Reverting CVS special files ... "); fflush(stdout); collectFiles(".cvsignore",true,true); sprintf(command,"p4p -x %s revert >>& %s",tempPath,logPath); system(command); printf("Done\n"); fflush(stdout); printf("Reverting unchanged files ... "); fflush(stdout); sprintf(command,"p4p diff -sr | p4p -x - revert >>& %s",logPath); system(command); printf("Done\n"); fflush(stdout); remove(tempPath); printf("Deleting removed files ... "); fflush(stdout); sprintf(command,"p4p opened >>& %s",tempPath2); system(command); findRemovedFiles(tempPath2); sprintf(command,"p4p -x %s revert >>& %s",tempPath,logPath); system(command); sprintf(command,"p4p -x %s delete >>& %s",tempPath,logPath); system(command); printf("Done\n"); fflush(stdout); // Clean up and exit remove(tempPath); remove(tempPath2); return 0; }
/**************************************************************************** PARAMETERS: path - directory with font file filename - filename of the font file cache - local cache for one directory REMARKS: Updates cache entry for given font file. If such file is not in the cache, loads it with MGL_openFontLib and extracts information about font library type, family and face from it. A font is marked as bold if its name ends with " Bold", as italic if it ends with " Italic". Suffixes are cumulative. Family name is face name with recognized suffixes stripped off. For example, cache entry for font "Arial Bold Italic" will read "family is Arial, face is bold and italic". {secret} ****************************************************************************/ static void enumFontFile( const char *path, const char *filename, dirCache *cache) { char fullname[PM_MAX_PATH]; font_lib_t *fontLib; fileCache *entry; ibool isNewer; ibool foundSuffix; #if 0 // TODO: missing PM_getFileTime under Unix and DOS PM_time time; long ytimef, ytimec; #endif char *buf; size_t buflen; strcpy(fullname, path); PM_backslash(fullname); strcat(fullname, filename); /* Try to find entry in cache: */ entry = (fileCache*) bsearch(filename, cache->files, cache->filesCnt, sizeof(fileCache), searchFileCache); isNewer = (entry == NULL); #if 0 // TODO: missing PM_getFileTime under Unix and DOS if (!isNewer && PM_getFileTime(fullname, true, &time)) { ytimef = time.sec + 60 * (time.min + 60 * (time.hour + 24 * (time.day + 31 * time.mon))); ytimec = cache->timestamp.sec + 60 * (cache->timestamp.min + 60 * ( cache->timestamp.hour + 24 * (cache->timestamp.day + 31 * cache->timestamp.mon))); isNewer = time.year > cache->timestamp.year || (time.year == cache->timestamp.year && ytimef > ytimec); } #endif if (!isNewer) { cache->validCnt++; entry->exists = true; return; } /* Nothing in cache, we have to open the font: */ fontLib = MGL_openFontLib(fullname); if (fontLib == NULL) return; if (entry == NULL) { if (cache->filesCnt % CACHE_BLOCK_SIZE == 0) { cache->filesBlocks++; cache->files = PM_realloc(cache->files, sizeof(fileCache) * cache->filesBlocks * CACHE_BLOCK_SIZE); } entry = cache->files + cache->filesCnt; cache->filesCnt++; } else { PM_free(entry->fileName); PM_free(entry->familyName); } /* Try to determine family name and face type from facename: */ if ((entry->fileName = PM_malloc(strlen(filename) + 1)) == NULL) FATALERROR(grNoMem); strcpy(entry->fileName, filename); entry->fontLibType = fontLib->fontLibType; buflen = strlen(fontLib->name); if ((buf = PM_malloc(buflen + 1)) == NULL) FATALERROR(grNoMem); strcpy(buf, fontLib->name); entry->isBold = entry->isItalic = false; do { foundSuffix = false; if (buflen >= 5 && strcmp(buf + buflen - 5, " Bold") == 0) { foundSuffix = true; entry->isBold = true; buf[buflen - 5] = '\0'; buflen -= 5; } if (buflen >= 7 && strcmp(buf + buflen - 7, " Italic") == 0) { foundSuffix = true; entry->isItalic = true; buf[buflen - 7] = '\0'; buflen -= 7; } } while (buflen > 0 && foundSuffix); if (buflen == 0) { if ((entry->familyName = PM_malloc(strlen(filename) + 1)) == NULL) FATALERROR(grNoMem); strcpy(entry->familyName, filename); } else { if ((entry->familyName = PM_malloc(strlen(buf) + 1)) == NULL) FATALERROR(grNoMem); strcpy(entry->familyName, buf); } PM_free(buf); /* Check if the font is fixed width or proportional. In absence of better method, we do it by comparing average and maximum character width: */ entry->isFixed = fontIsFixed(fontLib); MGL_closeFontLib(fontLib); cache->validCnt++; entry->exists = true; }
/**************************************************************************** PARAMETERS: dir - path to look for fntcache.inf in cache - cache structure to save loaded data to REMARKS: Initializes dirCache structure and tries to load fntcache.inf file from given directory. Silently fails if such file does not exist. fntcache.inf is text file in the following format: first line contains number of entries in decimal format, which indicates the number of file lines to follow. Each file line contains three column delimined by '\t'. Font file name is in the first column. Second column has fixed "T-F-B-I" format where T is '0', '1' or '2' (as numerical values of MGL_fontLibType are), F is 'f' for fixed size fonts and 'p' for proportional, B is 'b' for bold face and 'n' otherwise and I is 'i' for italic face and 'n' otherwise. Third column contains family name. The cache is sorted alphabetically by file name. Example file: 9 1979rg__.ttf 1-p-n-n 1979 1stgrade.ttf 1-p-n-n FirstGrader-Normal 39smooth.ttf 1-p-n-n 39 Smooth 7hours.ttf 1-p-n-n 7 hours Scot000.ttf 1-p-n-n Scott verdana.ttf 1-p-n-n Verdana verdanab.ttf 1-p-b-n Verdana verdanai.ttf 1-p-n-i Verdana verdanaz.ttf 1-p-b-i Verdana {secret} ****************************************************************************/ static void loadFontCache( const char *dir, dirCache *cache) { char filename[PM_MAX_PATH]; char buf[CACHE_LINE_SIZE]; char *c1, *c2; char bufType, bufFixed, bufBold, bufItalic; fileCache *file; FILE *f; size_t i; /* empty cache: */ cache->filesCnt = 0; cache->validCnt = 0; cache->filesBlocks = 0; cache->files = NULL; /* try to load fonts cache file from directory, silently fail if it doesn't exist: */ strcpy(filename, dir); PM_backslash(filename); strcat(filename, CACHE_FILE); f = __MGL_fopen(filename, "rt"); if (f == NULL) return; #if 0 // TODO: missing PM_getFileTime under Unix and DOS PM_getFileTime(filename, true, &cache->timestamp); #endif if (fgets(buf, CACHE_LINE_SIZE, f) == NULL) { __MGL_fclose(f); return; } /* get number of items in the cache: */ if (sscanf(buf, "%li", &cache->filesCnt) != 1 || cache->filesCnt == 0) { __MGL_fclose(f); return; } cache->filesBlocks = ((cache->filesCnt - 1) / CACHE_BLOCK_SIZE) + 1; cache->files = PM_malloc(sizeof(fileCache) * cache->filesBlocks * CACHE_BLOCK_SIZE); if (cache->files == NULL) FATALERROR(grNoMem); /* read entries. Each font file has one entry, there's one entry per line. The cache is sorted alphabetically by filename. */ for (i = 0; i < cache->filesCnt; i++) { file = cache->files + i; file->exists = false; if (fgets(buf, CACHE_LINE_SIZE, f) == NULL) { cache->filesCnt = i; __MGL_fclose(f); return; } c1 = buf; for (c2 = c1; *c2 != '\0' && *c2 != '\t'; c2++) {} *c2 = '\0'; if ((file->fileName = PM_malloc(strlen(c1) + 1)) == NULL) FATALERROR(grNoMem); strcpy(file->fileName, c1); c1 = c2 + 1; for (c2 = c1; *c2 != '\0' && *c2 != '\t'; c2++) {} *c2 = '\0'; if (sscanf(c1, "%c-%c-%c-%c", &bufType, &bufFixed, &bufBold, &bufItalic) != 4) continue; file->isBold = (bufBold == 'b'); file->isItalic = (bufItalic == 'i'); file->isFixed = (bufFixed == 'f'); file->fontLibType = bufType - '0'; c1 = c2 + 1; for (c2 = c1; *c2 != '\0'; c2++) if (*c2 == '\n' || *c2 == '\r') *c2 = '\0'; if ((file->familyName = PM_malloc(strlen(c1) + 1)) == NULL) FATALERROR(grNoMem); strcpy(file->familyName, c1); } __MGL_fclose(f); }