⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conf.c

📁 代码检索工具GLOBAL源码。可用来浏览分析LINUX源码。
💻 C
字号:
/* * Copyright (c) 1998, 1999, 2000, 2001, 2002, 2005 *	Tama Communications Corporation * * This file is part of GNU GLOBAL. * * GNU GLOBAL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GNU GLOBAL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <assert.h>#include <ctype.h>#ifdef STDC_HEADERS#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include "gparam.h"#include "conf.h"#include "die.h"#include "env.h"#include "langmap.h"#include "locatestring.h"#include "makepath.h"#include "path.h"#include "strbuf.h"#include "strlimcpy.h"#include "strmake.h"#include "test.h"#include "usable.h"static FILE *fp;static STRBUF *ib;static char *confline;/* * 8 level nested tc= or include= is allowed. */static int allowed_nest_level = 8;static int opened;static void trim(char *);static const char *readrecord(const char *);static void includelabel(STRBUF *, const char *, int);#ifndef isblank#define isblank(c)	((c) == ' ' || (c) == '\t')#endif/* * trim: trim string. * * : var1=a b : *	| *	v * :var1=a b : */static voidtrim(l)	char *l;{	char *f, *b;	int colon = 0;	/*	 * delete blanks.	 */	for (f = b = l; *f; f++) {		if (colon && isblank(*f))			continue;		colon = 0;		if ((*b++ = *f) == ':')			colon = 1;	}	*b = 0;	/*	 * delete duplicate semi colons.	 */	for (f = b = l; *f;) {		if ((*b++ = *f++) == ':') {			while (*f == ':')				f++;		}	}	*b = 0;}/* * readrecord: read recoed indexed by label. * *	i)	label	label in config file *	r)		record * * Jobs: * o skip comment. * o append following line. * o format check. */static const char *readrecord(label)	const char *label;{	char *p;	int flag = STRBUF_NOCRLF;	int count = 0;	rewind(fp);	while ((p = strbuf_fgets(ib, fp, flag)) != NULL) {		count++;		/*		 * ignore \<new line>.		 */		flag &= ~STRBUF_APPEND;		if (*p == '#' || *p == '\0')			continue;		if (strbuf_unputc(ib, '\\')) {			flag |= STRBUF_APPEND;			continue;		}		trim(p);		for (;;) {			const char *candidate;			/*			 * pick up candidate.			 */			if ((candidate = strmake(p, "|:")) == NULL)				die("invalid config file format (line %d).", count);			if (!strcmp(label, candidate)) {				if (!(p = locatestring(p, ":", MATCH_FIRST)))					die("invalid config file format (line %d).", count);				p = strdup(p);				if (!p)					die("short of memory.");				return p;			}			/*			 * locate next candidate.			 */			p += strlen(candidate);			if (*p == ':')				break;			else if (*p == '|')				p++;			else				die("invalid config file format (line %d).", count);		}	}	/*	 * config line not found.	 */	return NULL;}/* * includelabel: procedure for tc= (or include=) * *	o)	sb	string buffer *	i)	label	record label *	i)	level	nest level for check */static voidincludelabel(sb, label, level)	STRBUF	*sb;	const char *label;	int	level;{	const char *savep, *p, *q;	if (++level > allowed_nest_level)		die("nested include= (or tc=) over flow.");	if (!(savep = p = readrecord(label)))		die("label '%s' not found.", label);	while ((q = locatestring(p, ":include=", MATCH_FIRST)) || (q = locatestring(p, ":tc=", MATCH_FIRST))) {		STRBUF *inc = strbuf_open(0);		strbuf_nputs(sb, p, q - p);		q = locatestring(q, "=", MATCH_FIRST) + 1;		for (; *q && *q != ':'; q++)			strbuf_putc(inc, *q);		includelabel(sb, strbuf_value(inc), level);		p = q;		strbuf_close(inc);	}	strbuf_puts(sb, p);	free((void *)savep);}/* * configpath: get path of configuration file. */static char *configpath(void){	STATIC_STRBUF(sb);	const char *p;	strbuf_clear(sb);	/*	 * at first, check environment variable GTAGSCONF.	 */	if (getenv("GTAGSCONF") != NULL)		strbuf_puts(sb, getenv("GTAGSCONF"));	/*	 * if GTAGSCONF not set then check standard config files.	 */	else if ((p = get_home_directory()) && test("r", makepath(p, GTAGSRC, NULL)))		strbuf_puts(sb, makepath(p, GTAGSRC, NULL));#ifdef __DJGPP__	else if ((p = get_home_directory()) && test("r", makepath(p, DOS_GTAGSRC, NULL)))		strbuf_puts(sb, makepath(p, DOS_GTAGSRC, NULL));#endif	else if (test("r", GTAGSCONF))		strbuf_puts(sb, GTAGSCONF);	else if (test("r", OLD_GTAGSCONF))		strbuf_puts(sb, OLD_GTAGSCONF);	else if (test("r", DEBIANCONF))		strbuf_puts(sb, DEBIANCONF);	else if (test("r", OLD_DEBIANCONF))		strbuf_puts(sb, OLD_DEBIANCONF);	else		return NULL;	return strbuf_value(sb);}/* * openconf: load configuration file. * *	go)	line	specified entry */voidopenconf(void){	STRBUF *sb;	const char *config;	extern int vflag;	assert(opened == 0);	opened = 1;	/*	 * if config file not found then return default value.	 */	if (!(config = configpath())) {		if (vflag)			fprintf(stderr, " Using default configuration.\n");		confline = strdup("");		if (!confline)			die("short of memory.");	}	/*	 * if it is not an absolute path then assumed config value itself.	 */	else if (!isabspath(config)) {		confline = strdup(config);		if (!confline)			die("short of memory.");		if (!locatestring(confline, ":", MATCH_FIRST))			die("GTAGSCONF must be absolute path name.");	}	/*	 * else load value from config file.	 */	else {		const char *label;		if (test("d", config))			die("config file '%s' is a directory.", config);		if (!test("f", config))			die("config file '%s' not found.", config);		if (!test("r", config))			die("config file '%s' is not readable.", config);		if ((label = getenv("GTAGSLABEL")) == NULL)			label = "default";			if (!(fp = fopen(config, "r")))			die("cannot open '%s'.", config);		if (vflag)			fprintf(stderr, " Using config file '%s'.\n", config);		ib = strbuf_open(MAXBUFLEN);		sb = strbuf_open(0);		includelabel(sb, label, 0);		confline = strdup(strbuf_value(sb));		if (!confline)			die("short of memory.");		strbuf_close(ib);		strbuf_close(sb);		fclose(fp);	}	/*	 * make up lacked variables.	 */	sb = strbuf_open(0);	strbuf_puts(sb, confline);	strbuf_unputc(sb, ':');	if (!getconfs("suffixes", NULL)) {		STRBUF *tmp = strbuf_open(0);		const char *langmap = NULL;		/*		 * Variable 'suffixes' is obsoleted. But it is generated		 * internally from the value of variable 'langmap'.		 */		if (getconfs("langmap", tmp))			langmap = strbuf_value(tmp);		else			langmap = DEFAULTLANGMAP;		strbuf_puts(sb, ":suffixes=");		make_suffixes(langmap, sb);		strbuf_close(tmp);	}	if (!getconfs("skip", NULL)) {		strbuf_puts(sb, ":skip=");		strbuf_puts(sb, DEFAULTSKIP);	}	/*	 * GTAGS, GRTAGS and GSYMS have no default values but non of them	 * specified then use default values.	 * (Otherwise, nothing to do for gtags.)	 */	if (!getconfs("GTAGS", NULL) && !getconfs("GRTAGS", NULL) && !getconfs("GSYMS", NULL)) {		const char *path;		/*		 * usable search in BINDIR at first.		 */#if defined(_WIN32)		path = "gtags-parser.exe";#elif defined(__DJGPP__)		path = usable("gtags-parser") ? "gtags-parser.exe" : "gtags-~1.exe";#else		path = usable("gtags-parser");		if (!path)			path = "gtags-parser";#endif /* _WIN32 */		strbuf_puts(sb, ":GTAGS=");		strbuf_puts(sb, path);		strbuf_puts(sb, " -dt %s");		strbuf_puts(sb, ":GRTAGS=");		strbuf_puts(sb, path);		strbuf_puts(sb, " -dtr %s");		strbuf_puts(sb, ":GSYMS=");		strbuf_puts(sb, path);		strbuf_puts(sb, " -dts %s");	}	strbuf_unputc(sb, ':');	strbuf_putc(sb, ':');	confline = strdup(strbuf_value(sb));	if (!confline)		die("short of memory.");	strbuf_close(sb);	trim(confline);	return;}/* * getconfn: get property number * *	i)	name	property name *	o)	num	value (if not NULL) *	r)		1: found, 0: not found */intgetconfn(name, num)	const char *name;	int *num;{	const char *p;	char buf[MAXPROPLEN+1];	if (!opened)		openconf();	snprintf(buf, sizeof(buf), ":%s#", name);	if ((p = locatestring(confline, buf, MATCH_FIRST)) != NULL) {		p += strlen(buf);		if (num != NULL)			*num = atoi(p);		return 1;	}	return 0;}/* * getconfs: get property string * *	i)	name	property name *	o)	sb	string buffer (if not NULL) *	r)		1: found, 0: not found */intgetconfs(name, sb)	const char *name;	STRBUF *sb;{	const char *p;	char buf[MAXPROPLEN+1];	int all = 0;	int exist = 0;	if (!opened)		openconf();	if (!strcmp(name, "suffixes") || !strcmp(name, "skip"))		all = 1;	snprintf(buf, sizeof(buf), ":%s=", name);	p = confline;	while ((p = locatestring(p, buf, MATCH_FIRST)) != NULL) {		if (exist && sb)			strbuf_putc(sb, ',');				exist = 1;		for (p += strlen(buf); *p && *p != ':'; p++) {			if (*p == '\\')	/* quoted character */				p++;			if (sb)				strbuf_putc(sb, *p);		}		if (!all)			break;	}	/*	 * If 'bindir' and 'datadir' are not defined then	 * return system configuration value.	 */	if (!exist) {		if (!strcmp(name, "bindir")) {			strbuf_puts(sb, BINDIR);			exist = 1;		} else if (!strcmp(name, "datadir")) {			strbuf_puts(sb, DATADIR);			exist = 1;		}	}	return exist;}/* * getconfb: get property bool value * *	i)	name	property name *	r)		1: TRUE, 0: FALSE */intgetconfb(name)	const char *name;{	char buf[MAXPROPLEN+1];	if (!opened)		openconf();	snprintf(buf, sizeof(buf), ":%s:", name);	if (locatestring(confline, buf, MATCH_FIRST) != NULL)		return 1;	return 0;}/* * getconfline: print loaded config entry. */const char *getconfline(void){	if (!opened)		openconf();	return confline;}voidcloseconf(void){	if (!opened)		return;	free(confline);	confline = NULL;	opened = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -