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

📄 parser.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 5 页
字号:
options_clausesets[] = {	options_clauses,	view_clauses,	zone_clauses,	NULL};static cfg_type_t cfg_type_options = {	"options", parse_map, print_map, &cfg_rep_map, options_clausesets };/* The "view" statement syntax. */static cfg_clausedef_t *view_clausesets[] = {	view_only_clauses,	namedconf_or_view_clauses,	view_clauses,	zone_clauses,	NULL};static cfg_type_t cfg_type_viewopts = {	"view", parse_map, print_map, &cfg_rep_map, view_clausesets };/* The "zone" statement syntax. */static cfg_clausedef_t *zone_clausesets[] = {	zone_only_clauses,	zone_clauses,	NULL};static cfg_type_t cfg_type_zoneopts = {	"zoneopts", parse_map, print_map, &cfg_rep_map, zone_clausesets };/* * Clauses that can be found within the 'key' statement. */static cfg_clausedef_tkey_clauses[] = {	{ "algorithm", &cfg_type_astring, 0 },	{ "secret", &cfg_type_astring, 0 },	{ NULL, NULL, 0 }};static cfg_clausedef_t *key_clausesets[] = {	key_clauses,	NULL};static cfg_type_t cfg_type_key = {	"key", parse_named_map, print_map, &cfg_rep_map, key_clausesets };/* * Clauses that can be found in a 'server' statement. */static cfg_clausedef_tserver_clauses[] = {	{ "bogus", &cfg_type_boolean, 0 },	{ "provide-ixfr", &cfg_type_boolean, 0 },	{ "request-ixfr", &cfg_type_boolean, 0 },	{ "support-ixfr", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },	{ "transfers", &cfg_type_uint32, 0 },	{ "transfer-format", &cfg_type_transferformat, 0 },	{ "keys", &cfg_type_server_key_kludge, 0 },	{ "edns", &cfg_type_boolean, 0 },	{ NULL, NULL, 0 }};static cfg_clausedef_t *server_clausesets[] = {	server_clauses,	NULL};static cfg_type_t cfg_type_server = {	"server", parse_addressed_map, print_map, &cfg_rep_map,	server_clausesets};/* * Clauses that can be found in a 'channel' clause in the * 'logging' statement. * * These have some additional constraints that need to be * checked after parsing: *  - There must exactly one of file/syslog/null/stderr * */static cfg_clausedef_tchannel_clauses[] = {	/* Destinations.  We no longer require these to be first. */	{ "file", &cfg_type_logfile, 0 },	{ "syslog", &cfg_type_optional_facility, 0 },	{ "null", &cfg_type_void, 0 },	{ "stderr", &cfg_type_void, 0 },	/* Options.  We now accept these for the null channel, too. */	{ "severity", &cfg_type_logseverity, 0 },	{ "print-time", &cfg_type_boolean, 0 },	{ "print-severity", &cfg_type_boolean, 0 },	{ "print-category", &cfg_type_boolean, 0 },	{ NULL, NULL, 0 }};static cfg_clausedef_t *channel_clausesets[] = {	channel_clauses,	NULL};static cfg_type_t cfg_type_channel = {	"channel", parse_named_map, print_map,	&cfg_rep_map, channel_clausesets};/* A list of log destination, used in the "category" clause. */static cfg_type_t cfg_type_destinationlist = {	"destinationlist", parse_bracketed_list, print_bracketed_list,	&cfg_rep_list, &cfg_type_astring };/* * Clauses that can be found in a 'logging' statement. */static cfg_clausedef_tlogging_clauses[] = {	{ "channel", &cfg_type_channel, CFG_CLAUSEFLAG_MULTI },	{ "category", &cfg_type_category, CFG_CLAUSEFLAG_MULTI },	{ NULL, NULL, 0 }};static cfg_clausedef_t *logging_clausesets[] = {	logging_clauses,	NULL};static cfg_type_t cfg_type_logging = {	"logging", parse_map, print_map, &cfg_rep_map, logging_clausesets };/* Functions. */static voidprint_obj(cfg_printer_t *pctx, cfg_obj_t *obj) {	obj->type->print(pctx, obj);}static voidprint(cfg_printer_t *pctx, const char *text, int len) {	pctx->f(pctx->closure, text, len);}static voidprint_open(cfg_printer_t *pctx) {	print(pctx, "{\n", 2);	pctx->indent++;}static voidprint_indent(cfg_printer_t *pctx) {	int indent = pctx->indent;	while (indent > 0) {		print(pctx, "\t", 1);		indent--;	}}static voidprint_close(cfg_printer_t *pctx) {	pctx->indent--;	print_indent(pctx);	print(pctx, "}", 1);}static isc_result_tparse(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	isc_result_t result;	INSIST(ret != NULL && *ret == NULL);	result = type->parse(pctx, type, ret);	if (result != ISC_R_SUCCESS)		return (result);	INSIST(*ret != NULL);	return (ISC_R_SUCCESS);}voidcfg_print(cfg_obj_t *obj,	  void (*f)(void *closure, const char *text, int textlen),	  void *closure){	cfg_printer_t pctx;	pctx.f = f;	pctx.closure = closure;	pctx.indent = 0;	obj->type->print(&pctx, obj);}/* Tuples. */  static isc_result_tcreate_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	isc_result_t result;	const cfg_tuplefielddef_t *fields = type->of;	const cfg_tuplefielddef_t *f;	cfg_obj_t *obj = NULL;	unsigned int nfields = 0;	int i;	for (f = fields; f->name != NULL; f++)		nfields++;	CHECK(create_cfgobj(pctx, type, &obj));	obj->value.tuple = isc_mem_get(pctx->mctx,				       nfields * sizeof(cfg_obj_t *));	if (obj->value.tuple == NULL) {		result = ISC_R_NOMEMORY;		goto cleanup;	}	for (f = fields, i = 0; f->name != NULL; f++, i++)		obj->value.tuple[i] = NULL;	*ret = obj;	return (ISC_R_SUCCESS); cleanup:	if (obj != NULL)		isc_mem_put(pctx->mctx, obj, sizeof(*obj));	return (result);}static isc_result_tparse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret){	isc_result_t result;	const cfg_tuplefielddef_t *fields = type->of;	const cfg_tuplefielddef_t *f;	cfg_obj_t *obj = NULL;	unsigned int i;	CHECK(create_tuple(pctx, type, &obj));	for (f = fields, i = 0; f->name != NULL; f++, i++)		CHECK(parse(pctx, f->type, &obj->value.tuple[i]));	*ret = obj;	return (ISC_R_SUCCESS); cleanup:	CLEANUP_OBJ(obj);	return (result);}static voidprint_tuple(cfg_printer_t *pctx, cfg_obj_t *obj) {	unsigned int i;	const cfg_tuplefielddef_t *fields = obj->type->of;	const cfg_tuplefielddef_t *f;	isc_boolean_t need_space = ISC_FALSE;	for (f = fields, i = 0; f->name != NULL; f++, i++) {		cfg_obj_t *fieldobj = obj->value.tuple[i];		if (need_space)			print(pctx, " ", 1);		print_obj(pctx, fieldobj);		need_space = ISC_TF(fieldobj->type->print != print_void);	}}static voidfree_tuple(cfg_parser_t *pctx, cfg_obj_t *obj) {	unsigned int i;	const cfg_tuplefielddef_t *fields = obj->type->of;	const cfg_tuplefielddef_t *f;	unsigned int nfields = 0;	if (obj->value.tuple == NULL)		return;	for (f = fields, i = 0; f->name != NULL; f++, i++) {		CLEANUP_OBJ(obj->value.tuple[i]);		nfields++;	}	isc_mem_put(pctx->mctx, obj->value.tuple,		    nfields * sizeof(cfg_obj_t *));}isc_boolean_tcfg_obj_istuple(cfg_obj_t *obj) {	REQUIRE(obj != NULL);	return (ISC_TF(obj->type->rep == &cfg_rep_tuple));}cfg_obj_t *cfg_tuple_get(cfg_obj_t *tupleobj, const char* name) {	unsigned int i;	const cfg_tuplefielddef_t *fields;	const cfg_tuplefielddef_t *f;		REQUIRE(tupleobj != NULL && tupleobj->type->rep == &cfg_rep_tuple);	fields = tupleobj->type->of;	for (f = fields, i = 0; f->name != NULL; f++, i++) {		if (strcmp(f->name, name) == 0)			return (tupleobj->value.tuple[i]);	}	INSIST(0);	return (NULL);}/* * Parse a required special character. */static isc_result_tparse_special(cfg_parser_t *pctx, int special) {        isc_result_t result;	CHECK(cfg_gettoken(pctx, 0));	if (pctx->token.type == isc_tokentype_special &&	    pctx->token.value.as_char == special)		return (ISC_R_SUCCESS);	parser_error(pctx, LOG_NEAR, "'%c' expected", special);	return (ISC_R_UNEXPECTEDTOKEN); cleanup:	return (result);}/* * Parse a required semicolon.  If it is not there, log * an error and increment the error count but continue * parsing.  Since the next token is pushed back, * care must be taken to make sure it is eventually * consumed or an infinite loop may result. */static isc_result_tparse_semicolon(cfg_parser_t *pctx) {        isc_result_t result;	CHECK(cfg_gettoken(pctx, 0));	if (pctx->token.type == isc_tokentype_special &&	    pctx->token.value.as_char == ';')		return (ISC_R_SUCCESS);	parser_error(pctx, LOG_BEFORE, "missing ';'");	cfg_ungettoken(pctx); cleanup:	return (result);}/* * Parse EOF, logging and returning an error if not there. */static isc_result_tparse_eof(cfg_parser_t *pctx) {        isc_result_t result;	CHECK(cfg_gettoken(pctx, 0));	if (pctx->token.type == isc_tokentype_eof)		return (ISC_R_SUCCESS);	parser_error(pctx, LOG_NEAR, "syntax error");	return (ISC_R_UNEXPECTEDTOKEN); cleanup:	return(result);}/* A list of files, used internally for pctx->files. */static cfg_type_t cfg_type_filelist = {	"filelist", NULL, print_list, &cfg_rep_list,	&cfg_type_qstring};isc_result_tcfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret){	isc_result_t result;	cfg_parser_t *pctx;	isc_lexspecials_t specials;	REQUIRE(mctx != NULL);	REQUIRE(ret != NULL && *ret == NULL);	pctx = isc_mem_get(mctx, sizeof(*pctx));	if (pctx == NULL)		return (ISC_R_NOMEMORY);	pctx->mctx = mctx;	pctx->lctx = lctx;	pctx->lexer = NULL;	pctx->seen_eof = ISC_FALSE;	pctx->ungotten = ISC_FALSE;	pctx->errors = 0;	pctx->warnings = 0;	pctx->open_files = NULL;	pctx->closed_files = NULL;	pctx->line = 0;	pctx->callback = NULL;	pctx->callbackarg = NULL;	pctx->token.type = isc_tokentype_unknown;	memset(specials, 0, sizeof(specials));	specials['{'] = 1;	specials['}'] = 1;	specials[';'] = 1;	specials['/'] = 1;	specials['"'] = 1;	specials['!'] = 1;	CHECK(isc_lex_create(pctx->mctx, 1024, &pctx->lexer));	isc_lex_setspecials(pctx->lexer, specials);	isc_lex_setcomments(pctx->lexer, (ISC_LEXCOMMENT_C |					 ISC_LEXCOMMENT_CPLUSPLUS |					 ISC_LEXCOMMENT_SHELL));	CHECK(create_list(pctx, &cfg_type_filelist, &pctx->open_files));	CHECK(create_list(pctx, &cfg_type_filelist, &pctx->closed_files));	*ret = pctx;	return (ISC_R_SUCCESS); cleanup:	if (pctx->lexer != NULL)		isc_lex_destroy(&pctx->lexer);	CLEANUP_OBJ(pctx->open_files);	CLEANUP_OBJ(pctx->closed_files);	isc_mem_put(mctx, pctx, sizeof(*pctx));	return (result);}static isc_result_tparser_openfile(cfg_parser_t *pctx, const char *filename) {	isc_result_t result;	cfg_listelt_t *elt = NULL;	cfg_obj_t *stringobj = NULL;	result = isc_lex_openfile(pctx->lexer, filename);	if (result != ISC_R_SUCCESS) {		parser_error(pctx, 0, "open: %s: %s",			     filename, isc_result_totext(result));		goto cleanup;	}	CHECK(create_string(pctx, filename, &cfg_type_qstring, &stringobj));	CHECK(create_listelt(pctx, &elt));	elt->obj = stringobj;	ISC_LIST_APPEND(pctx->open_files->value.list, elt, link);	return (ISC_R_SUCCESS); cleanup:	CLEANUP_OBJ(stringobj);	return (result);}voidcfg_parser_setcallback(cfg_parser_t *pctx,		       cfg_parsecallback_t callback,		       void *arg){	pctx->callback = callback;	pctx->callbackarg = arg;}/* * Parse a configuration using a pctx where a lexer has already * been set up with a source. */static isc_result_tparse2(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	isc_result_t result;	cfg_obj_t *obj = NULL;	result = parse(pctx, type, &obj);	if (pctx->errors != 0) {		/* Errors have been logged. */		if (result == ISC_R_SUCCESS)			result = ISC_R_FAILURE;		goto cleanup;	}	if (result != ISC_R_SUCCESS) {		/* Parsing failed but no errors have been logged. */		parser_error(pctx, 0, "parsing failed");		goto cleanup;	}	CHECK(parse_eof(pctx));	*ret = obj;	return (ISC_R_SUCCESS); cleanup:	CLEANUP_OBJ(obj);	return (result);}isc_result_tcfg_parse_file(cfg_parser_t *pctx, const char *filename,	       const cfg_type_t *type, cfg_obj_t **ret){	isc_result_t result;	REQUIRE(filename != NULL);	CHECK(parser_openfile(pctx, filename));

⌨️ 快捷键说明

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