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

📄 parse.c

📁 读写Smart卡加解密接口的程序
💻 C
字号:
/* * $Id: parse.c,v 1.10 2003/01/03 11:54:02 okir Exp $ * * Copyright (C) 2002 *  Antti Tapaninen <aet@cc.hut.fi> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include "scconf.h"#include "internal.h"#define STATE_NAME	0x01#define STATE_VALUE	0x02#define STATE_SET	0x10static scconf_item *scconf_get_last_item(scconf_block *root){	scconf_block *block = root;	scconf_item *item;	for (item = root->items; item; item = item->next) {		if (!item->next) {			return item;		}	}	return block->items;}static void scconf_parse_error(scconf_parser * parser, const char *error){	/* FIXME: save the error somewhere */	parser->error = 1;	fprintf(stderr, "Line %d: %s\n", parser->line, error);}static void scconf_parse_error_not_expect(scconf_parser * parser,					  const char *token){	/* FIXME: save the error somewhere */	parser->error = 1;	fprintf(stderr, "Line %d: not expecting '%s'\n", parser->line, token);}static void scconf_parse_warning_expect(scconf_parser * parser, const char *token){	/* FIXME: save the warnings somewhere */	parser->warnings = 1;	fprintf(stderr, "Line %d: missing '%s', ignoring\n",		parser->line, token);}static scconf_item *scconf_item_find(scconf_parser * parser, const char *key){	scconf_item *item;	for (item = parser->block->items; item; item = item->next) {		if (item->type == SCCONF_ITEM_TYPE_VALUE &&		    strcasecmp(item->key, parser->key) == 0) {			return item;		}	}	return item;}static scconf_item *scconf_item_add_internal(scconf_parser * parser, int type){	scconf_item *item;	if (type == SCCONF_ITEM_TYPE_VALUE) {		/* if item with same key already exists, use it */		item = scconf_item_find(parser, parser->key);		if (item) {			if (parser->key) {				free(parser->key);			}			parser->key = NULL;			parser->current_item = item;			return item;		}	}	item = (scconf_item *) malloc(sizeof(scconf_item));	if (!item) {		return NULL;	}	memset(item, 0, sizeof(scconf_item));	item->type = type;	item->key = parser->key;	parser->key = NULL;	if (parser->last_item) {		parser->last_item->next = item;	} else {		parser->block->items = item;	}	parser->current_item = parser->last_item = item;	return item;}scconf_item *scconf_item_add(scconf_context * config, scconf_block * block, scconf_item * item, int type, const char *key, const void *data){	scconf_parser parser;	scconf_block *dst = NULL;	if (!config && !block)		return NULL;	if (!data)		return NULL;	memset(&parser, 0, sizeof(scconf_parser));	parser.config = config ? config : NULL;	parser.key = key ? strdup(key) : NULL;	parser.block = block ? block : config->root;	parser.name = NULL;	parser.last_item = scconf_get_last_item(parser.block);	parser.current_item = item;	if (type == SCCONF_ITEM_TYPE_BLOCK) {		scconf_block_copy((const scconf_block *) data, &dst);		scconf_list_copy(dst->name, &parser.name);	}	scconf_item_add_internal(&parser, type);	switch (parser.current_item->type) {	case SCCONF_ITEM_TYPE_COMMENT:		parser.current_item->value.comment = strdup((char *) data);		break;	case SCCONF_ITEM_TYPE_BLOCK:		dst->parent = parser.block;		parser.current_item->value.block = dst;		scconf_list_destroy(parser.name);		break;	case SCCONF_ITEM_TYPE_VALUE:		scconf_list_copy((const scconf_list *) data, &parser.current_item->value.list);		break;	}	return parser.current_item;}static void scconf_block_add_internal(scconf_parser * parser){	scconf_block *block;	scconf_item *item;	item = scconf_item_add_internal(parser, SCCONF_ITEM_TYPE_BLOCK);	block = (scconf_block *) malloc(sizeof(scconf_block));	if (!block) {		return;	}	memset(block, 0, sizeof(scconf_block));	block->parent = parser->block;	item->value.block = block;	if (!parser->name) {		scconf_list_add(&parser->name, "");	}	block->name = parser->name;	parser->name = NULL;	parser->block = block;	parser->last_item = NULL;}scconf_block *scconf_block_add(scconf_context * config, scconf_block * block, const char *key, const scconf_list *name){	scconf_parser parser;	memset(&parser, 0, sizeof(scconf_parser));	parser.config = config ? config : NULL;	parser.key = key ? strdup(key) : NULL;	parser.block = block ? block : config->root;	scconf_list_copy(name, &parser.name);	parser.last_item = scconf_get_last_item(parser.block);	parser.current_item = parser.block->items;	scconf_block_add_internal(&parser);	return parser.block;}static void scconf_parse_parent(scconf_parser * parser){	parser->block = parser->block->parent;	parser->last_item = parser->block->items;	if (parser->last_item) {		while (parser->last_item->next) {			parser->last_item = parser->last_item->next;		}	}}static void scconf_parse_reset_state(scconf_parser * parser){	if (parser) {		if (parser->key) {			free(parser->key);		}		scconf_list_destroy(parser->name);		parser->key = NULL;		parser->name = NULL;		parser->state = 0;	}}void scconf_parse_token(scconf_parser * parser, int token_type, const char *token){	scconf_item *item;	int len;	if (parser->error) {		/* fatal error */		return;	}	switch (token_type) {	case TOKEN_TYPE_NEWLINE:		parser->line++;		if (parser->last_token_type != TOKEN_TYPE_NEWLINE) {			break;		}		/* fall through - treat empty lines as comments */	case TOKEN_TYPE_COMMENT:		item = scconf_item_add_internal(parser, SCCONF_ITEM_TYPE_COMMENT);		item->value.comment = token ? strdup(token) : NULL;		break;	case TOKEN_TYPE_STRING:		{			char *stoken = NULL;			if ((parser->state & (STATE_VALUE | STATE_SET)) ==			    (STATE_VALUE | STATE_SET)) {				scconf_parse_warning_expect(parser, ";");				scconf_parse_reset_state(parser);			}			if (*token == '"') {				/* quoted string, remove them */				token++;				len = strlen(token);				if (len < 1 || token[len - 1] != '"') {					scconf_parse_warning_expect(parser, "\"");				} else {					/* stoken */					stoken = token ? strdup(token) : NULL;					if (stoken) {						stoken[len - 1] = '\0';					}				}			}			if (!stoken) {				stoken = token ? strdup(token) : NULL;			}			if (parser->state == 0) {				/* key */				parser->key = stoken ? strdup(stoken) : NULL;				parser->state = STATE_NAME;			} else if (parser->state == STATE_NAME) {				/* name */				parser->state |= STATE_SET;				scconf_list_add(&parser->name, stoken);			} else if (parser->state == STATE_VALUE) {				/* value */				parser->state |= STATE_SET;				scconf_list_add(&parser->current_item->value.list,						      stoken);			} else {				/* error */				scconf_parse_error_not_expect(parser, stoken);			}			if (stoken) {				free(stoken);			}			stoken = NULL;		}		break;	case TOKEN_TYPE_PUNCT:		switch (*token) {		case '{':			if ((parser->state & STATE_NAME) == 0) {				scconf_parse_error_not_expect(parser, "{");				break;			}			scconf_block_add_internal(parser);			scconf_parse_reset_state(parser);			break;		case '}':			if (parser->state != 0) {				if ((parser->state & STATE_VALUE) == 0 ||				    (parser->state & STATE_SET) == 0) {					scconf_parse_error_not_expect(parser,								      "}");					break;				}				/* foo = bar } */				scconf_parse_warning_expect(parser, ";");				scconf_parse_reset_state(parser);			}			if (!parser->block->parent) {				/* too many '}' */				scconf_parse_error(parser,						   "missing matching '{'");				break;			}			scconf_parse_parent(parser);			break;		case ',':			if ((parser->state & (STATE_NAME | STATE_VALUE)) == 0) {				scconf_parse_error_not_expect(parser, ",");			}			parser->state &= ~STATE_SET;			break;		case '=':			if ((parser->state & STATE_NAME) == 0) {				scconf_parse_error_not_expect(parser, "=");				break;			}			scconf_item_add_internal(parser, SCCONF_ITEM_TYPE_VALUE);			parser->state = STATE_VALUE;			break;		case ';':			if ((parser->state & STATE_VALUE) == 0 ||			    (parser->state & STATE_SET) == 0) {				scconf_parse_error_not_expect(parser, ";");				break;			}			scconf_parse_reset_state(parser);			break;		default:			fprintf(stderr, "scconf_parse_token: shouldn't happen\n");		}		break;	}	parser->last_token_type = token_type;}int scconf_parse(scconf_context * config){	scconf_parser p;	memset(&p, 0, sizeof(p));	p.config = config;	p.block = config->root;	p.line = 1;	if (!scconf_lex_parse(&p, config->filename)) {		return -1;	}	return p.error ? 0 : 1;}int scconf_parse_string(scconf_context * config, const char *string){	scconf_parser p;	memset(&p, 0, sizeof(p));	p.config = config;	p.block = config->root;	p.line = 1;	if (!scconf_lex_parse_string(&p, string)) {		return -1;	}	return p.error ? 0 : 1;}

⌨️ 快捷键说明

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