📄 dopen.c
字号:
/*dopen.c,v 1.3 1994/01/06 14:32:26 mcr Exp*//* dopen() is a massively system-dependent function, so I've placed * it in a separate file. *//* Macros used... * * IS_ABS -- a macro that returns nonzero if the string argument is an * absolute path, or 0 if it is a relative path. * PATH_STR -- a string of characters which separate directory components. * SUF_STR -- suffix for configuration files * PATH_SEP -- character to separate directory from filename. * LIST_SEP -- character that separates pathnames in a list. * exists(f) -- returns nonzero if the file f exists. * if not defined, then use fopen to determine existence. * HAS_ENV -- if defined, environment variables are searched. * *//* * Our algorithm is to try the following in sequence, until one works. * * The filename as-is. * The filename with SUF_STR appended. * * If IS_ABS returns nonzero, then fail. * * Else, we call the system-dependent get_dir() function. Each call * provides a directory to look in. * * For each directory, append the filename (perhaps inserting the * PATH_SEP). If that fails, try again after appending SUF_STR. * * When we run out of directories, we fail. */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#if HAVE_ALLOCA_H#include <alloca.h>#endif#ifdef UNIX#define HAS_ENV#define exists(f) (access(f, 0) == 0)#define IS_ABS(f) (*f == '/')#define SUF_STR ".cfg"#define PATH_SEP '/'#define PATH_STR "/"#define LIST_SEP ':'#endif#ifdef MSDOS#define HAS_ENV#include <io.h>#define exists(f) (access(f, 0) == 0)#define IS_ABS(f) (f[1] == ':' || strchr(PATH_STR, *f))#define SUF_STR ".cfg"#define PATH_SEP '/'#define PATH_STR "/\\:"#define LIST_SEP ';'#endif#ifdef VMS /* VMS is really different */#define IS_ABS(f) (strchr(f, ':') || strchr(PATH_STR, *f))#define SUF_STR ".cfg"#define PATH_SEP '.'#define PATH_STR "[.]"#endif#ifdef AMIGA#define IS_ABS(f) (strchr(f, ':') || *f == '/')#define SUF_STR ".cfg"#define PATH_SEP '/'#define PATH_STR "/"#endif/* If user specified no operating system, be very pessimistic. * Don't do anything beyond adding the `.cfg. suffix. */#ifndef SUF_STR#define IS_ABS 1#define SUF_STR ".cfg"#undef PATH_SEP#undef PATH_STR#undef HAS_ENV#endif/* If we don't have an exists(), then we'll just use fopen. */#ifndef exists#define exists(f) (descriptor = fopen(f, "rt"))#endif#ifdef HAS_ENV/* We search a handful of environment variables */const char *envlist[] = { "PATH", "DPATH", "WP2XDIR", NULL };char *get_dir(void){ static const char **nextenv = envlist; static char *nextpath = NULL; char *s; /* get the next environment variable */ while (nextpath == NULL || *nextpath == '\0') { if (*nextenv == NULL) return NULL; /* out of ideas */ nextpath = getenv(*nextenv++); if(nextpath) { nextpath=strdup(nextpath); } } s=nextpath; while (*nextpath && *nextpath != LIST_SEP) nextpath++; if (*nextpath) { *nextpath='\0'; nextpath++; } return s; /* return pointer to start of string */}#else/* On non-UNIX systems, we don't have environment variables. *//* We might have other things, though, so insert your local version here */char *get_dir(void) { return NULL; }#endif/* s is where to copy the filename, and f is the filename to try. */FILE *try_directory(char *dir, const char *f){ int dirlen; char *buf; FILE *d; dirlen=strlen(dir); buf=alloca(dirlen+strlen(f)+9); /* need SUF_STR too */ strcpy(buf,dir); if(buf[dirlen-1]!=PATH_SEP) { buf[dirlen++]=PATH_SEP; buf[dirlen]='\0'; } strcat(buf, f); if(exists(buf)) { d = fopen(buf, "r"); return d; } strcat(buf, SUF_STR); if(exists(buf)) { d = fopen(buf, "r"); return d; } return NULL;}FILE *dopen(const char *f){ char *s; FILE *d; /* First, try it as-is */ if ((d=try_directory("", f))!=NULL) return d;#ifdef WP2X_DIR if ((d=try_directory(WP2X_DIR, f))!=NULL) return d;#endif /* Skip if an absolute path */ if (!IS_ABS(f)) { /* Iterate through the possible directories */ while (s = get_dir()) { if ((d=try_directory(s, f))!=NULL) return d; } } error(NULL, "Cannot find file %s\n", f); return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -