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

📄 parsecfg.c

📁 串口调试工具。非常好的串口调试助手
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************//*                                                                        *//*  parsecfg - a library for parsing a configuration file                 *//*  Copyright (C) 1999-2001 Yuuki NINOMIYA <gm@debian.or.jp>              *//*                                                                        *//*  This program 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.                                                    *//*                                                                        *//*  This program 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., 59 Temple Place - Suite 330,          *//*  Boston, MA 02111-1307, USA.                                           *//*                                                                        *//**************************************************************************//* $Id: parsecfg.c,v 1.15 2001/06/27 15:24:00 gm Exp $ *//*#ifdef HAVE_CONFIG_H#  include "config.h"#endif*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <errno.h>#include "parsecfg.h"#include "gettext.h"#include "i18n.h"/* proto type declaration of private functions */static void cfgFatalFunc(cfgErrorCode, const char *, int, const char *);static void (*cfgFatal) (cfgErrorCode, const char *, int, const char *) = cfgFatalFunc;	/* default error handler */static int parse_simple(const char *file, FILE *fp, char *ptr, cfgStruct cfg[], int *line);static int parse_values_between_braces(const char *file, FILE *fp, const char *parameter, cfgStruct cfg[], int *line, cfgFileType type, int section, const char *parameter_buf, int parameter_line);static char *parse_word(char *ptr, char **word, cfgKeywordValue word_type);static int store_value(cfgStruct cfg[], const char *parameter, const char *value, cfgFileType type, int section);static int parse_ini(const char *file, FILE *fp, char *ptr, cfgStruct cfg[], int *line, int *section);static int alloc_for_new_section(cfgStruct cfg[], int *section);static char *get_single_line_without_first_spaces(FILE *fp, char **gotstr, int *line);static char *rm_first_spaces(char *ptr);static char *dynamic_fgets(FILE *fp);static int dump_simple(FILE *fp, cfgStruct cfg[], cfgFileType type);static int dump_ini(FILE *fp, cfgStruct cfg[], cfgFileType type, int max);static void single_or_double_quote(const char *str, char *ret);static int fetch_simple(const char *file, FILE *fp, char *parameter_name, void *result_value, cfgValueType value_type);static int fetch_ini(const char *file, FILE *fp, char *parameter_name, void *result_value, cfgValueType value_type, int section_num, const char *section_name);/* static variables */static char **parsecfg_section_name = NULL;static int parsecfg_maximum_section;/*************************************************************//*                      PUBLIC FUCNCTIONS                    *//*************************************************************//* --------------------------------------------------   NAME       cfgSetFatalFunc   FUNCTION   handle new error handler   INPUT      f ... pointer to new error handler   OUTPUT     none   -------------------------------------------------- */void cfgSetFatalFunc(void (*f) (cfgErrorCode, const char *, int, const char *)){	cfgFatal = f;}/* --------------------------------------------------   NAME       cfgParse   FUNCTION   parse a configuration file (main function)   INPUT      file ... name of the configuration file   cfg .... array of possible variables   type ... type of the configuration file              + CFG_SIMPLE .. simple 1:1              + CFG_INI ..... Windows INI-like file   OUTPUT     the maximum number of sections              (if type==CFG_INI then return 0)              -1 if an error occured   -------------------------------------------------- */int cfgParse(const char *file, cfgStruct cfg[], cfgFileType type){	char *line_buf;	char *ptr;	int line = 0;	FILE *fp;	int error_code;	int max_cfg = -1;	fp = fopen(file, "r");	if (fp == NULL) {		cfgFatal(CFG_OPEN_FAIL, file, 0, NULL);		return (-1);	}	while ((ptr = get_single_line_without_first_spaces(fp, &line_buf, &line)) != NULL) {		switch (type) {		case CFG_SIMPLE:			if ((error_code = parse_simple(file, fp, ptr, cfg, &line)) != CFG_NO_ERROR) {				fclose(fp);				cfgFatal(error_code, file, line, line_buf);				return (-1);			}			break;		case CFG_INI:			if ((error_code = parse_ini(file, fp, ptr, cfg, &line, &max_cfg)) != CFG_NO_ERROR) {				fclose(fp);				cfgFatal(error_code, file, line, line_buf);				return (-1);			}			break;		default:			fclose(fp);			cfgFatal(CFG_INTERNAL_ERROR, file, 0, NULL);			return (-1);		}		free(line_buf);	}	fclose(fp);	parsecfg_maximum_section = max_cfg + 1;	return (parsecfg_maximum_section);}/* --------------------------------------------------   NAME       cfgDump   FUNCTION   write configuration data to a file   INPUT      file ... name of the configuration file              cfg .... array of possible variables              type ... type of the configuration file                          + CFG_SIMPLE .. simple 1:1                          + CFG_INI ..... Windows INI-like file              max_section ... the maximum number of sections                              (if type is CFG_INI, this arg is ignored)   OUTPUT     0 on success and -1 on error   -------------------------------------------------- */int cfgDump(const char *file, cfgStruct cfg[], cfgFileType type, int max_section){	FILE *fp;	int retcode;	fp = fopen(file, "w");	if (fp == NULL) {		cfgFatal(CFG_CREATE_FAIL, file, 0, NULL);		return (-1);	}	switch (type) {	case CFG_SIMPLE:		retcode = dump_simple(fp, cfg, type);		break;	case CFG_INI:		retcode = dump_ini(fp, cfg, type, max_section);		break;	default:		fclose(fp);		cfgFatal(CFG_INTERNAL_ERROR, file, 0, NULL);		return (-1);	}	fclose(fp);	return (retcode);}/* --------------------------------------------------   NAME       fetchVarFromCfgFile   FUNCTION   fetch specified variable from configuration file   INPUT      file ... name of the configuration file              parameter_name ... parameter name to fetch              result_value ... stored result              value_type ... type of variable              file_type ... type of the configuration file                              + CFG_SIMPLE .. simple 1:1                              + CFG_INI ..... Windows INI-like file              section_num ... section number (for file_type==CFG_INI)              section_name ... section name (use this if section_num<1)   OUTPUT     return 0 if successful, -1 otherwise   -------------------------------------------------- */int fetchVarFromCfgFile(const char *file, char *parameter_name, void *result_value, cfgValueType value_type, cfgFileType file_type, int section_num, const char *section_name){	FILE *fp;	fp = fopen(file, "r");	if (fp == NULL) {		cfgFatal(CFG_OPEN_FAIL, file, 0, NULL);		return (-1);	}	switch (file_type) {	case CFG_SIMPLE:		if (fetch_simple(file, fp, parameter_name, result_value, value_type) == 0) {			fclose(fp);			return (0);		}		break;	case CFG_INI:		if (fetch_ini(file, fp, parameter_name, result_value, value_type, section_num, section_name) == 0) {			fclose(fp);			return (0);		}		break;	default:		fclose(fp);		cfgFatal(CFG_INTERNAL_ERROR, file, 0, NULL);		return (-1);	}	fclose(fp);	return (-1);}/* --------------------------------------------------   NAME       cfgSectionNameToNumber   FUNCTION   convert section name to number   INPUT      name ... section name   OUTPUT     section number (0,1,2,...)              if no matching, return -1   -------------------------------------------------- */int cfgSectionNameToNumber(const char *name){	int i;	for (i = 0; i < parsecfg_maximum_section; i++) {		if (strcasecmp(name, parsecfg_section_name[i]) == 0) {			return (i);		}	}	return (-1);}/* --------------------------------------------------   NAME       cfgSectionNumberToName   FUNCTION   convert section number to name   INPUT      num ... section number (0,1,2,...)   OUTPUT     pointer to section name              if no section, return NULL   -------------------------------------------------- */char *cfgSectionNumberToName(int num){	if (num > parsecfg_maximum_section - 1 || num < 0) {		return (NULL);	}	return (parsecfg_section_name[num]);}/* --------------------------------------------------   NAME       cfgAllocForNewSection   FUNCTION   allocate memory for new section   INPUT      cfg ... array of possible variables              name .. name of new section   OUTPUT     the maximum number of sections              -1 if an error occured   -------------------------------------------------- */int cfgAllocForNewSection(cfgStruct cfg[], const char *name){	int result;	int section;	section = parsecfg_maximum_section - 1;	result = alloc_for_new_section(cfg, &section);	if (result != CFG_NO_ERROR) {		cfgFatalFunc(result, "unknown", 0, "");		return (-1);	}	parsecfg_maximum_section = section + 1;	parsecfg_section_name = realloc(parsecfg_section_name, sizeof(char *) * parsecfg_maximum_section);	parsecfg_section_name[parsecfg_maximum_section - 1] = strdup(name);	return (parsecfg_maximum_section);}/* --------------------------------------------------   NAME       cfgStoreValue   FUNCTION   store the value according to cfg   INPUT      cfg ......... array of possible variables              parameter ... parameter	      value ....... value	      type ........ type of the configuration file	      section ..... section number (0,1,2,...)   OUTPUT     return 0 if successful, -1 otherwise   -------------------------------------------------- */int cfgStoreValue(cfgStruct cfg[], const char *parameter, const char *value, cfgFileType type, int section){	int result;	result = store_value(cfg, parameter, value, type, section);	if (result != CFG_NO_ERROR) {		cfgFatalFunc(result, "unknown", 0, "");		return (-1);	}	return (0);}/*************************************************************//*                     PRIVATE FUCNCTIONS                    *//*************************************************************//* --------------------------------------------------   NAME       cfgFatalFunc   FUNCTION   error handler   INPUT      error_code ... reason of error              file ......... the configuration file              line ......... line number causing error              str .......... strings at above line   OUTPUT     none   -------------------------------------------------- */static void cfgFatalFunc(cfgErrorCode error_code, const char *file, int line, const char *str){	switch (error_code) {	case CFG_OPEN_FAIL:		i18n_fprintf(stderr, _("Cannot open configuration file `%s'.\n"), file);		break;	case CFG_CREATE_FAIL:		i18n_fprintf(stderr, _("Cannot create configuration file `%s'.\n"), file);		break;	case CFG_SYNTAX_ERROR:		i18n_fprintf(stderr, _("%s(%d): %s\nSyntax error\n"), file, line, str);		break;	case CFG_WRONG_PARAMETER:		i18n_fprintf(stderr, _("%s(%d): %s\nUnrecognized parameter\n"), file, line, str);		break;	case CFG_INTERNAL_ERROR:		i18n_fprintf(stderr, _("%s(%d): %s\nInternal error\n"), file, line, str);		break;	case CFG_INVALID_NUMBER:		i18n_fprintf(stderr, _("%s(%d): %s\nInvalid number\n"), file, line, str);		break;	case CFG_OUT_OF_RANGE:		i18n_fprintf(stderr, _("%s(%d): %s\nOut of range\n"), file, line, str);		break;	case CFG_MEM_ALLOC_FAIL:		i18n_fprintf(stderr, _("%s(%d): %s\nCannot allocate memory.\n"), file, line, str);		break;	case CFG_BOOL_ERROR:		i18n_fprintf(stderr, _("%s(%d): %s\nIt must be specified TRUE or FALSE.\n"), file, line, str);		break;	case CFG_USED_SECTION:		i18n_fprintf(stderr, _("%s(%d): %s\nThe section name is already used.\n"), file, line, str);		break;	case CFG_NO_CLOSING_BRACE:		i18n_fprintf(stderr, _("%s(%d)\nThere is no closing brace.\n"), file, line);		break;	case CFG_JUST_RETURN_WITHOUT_MSG:		break;	default:		i18n_fprintf(stderr, _("%s(%d): %s\nUnexplained error\n"), file, line, str);	}}/* --------------------------------------------------   NAME       parse_simple   FUNCTION   parse as simple 1:1 file   INPUT      file .. name of the configuration file              fp .... file pointer to the configuration file              ptr ... pointer of current parsing              cfg ... array of possible variables              line .. pointer to current working line   OUTPUT     error code (no error is CFG_NO_ERROR)   -------------------------------------------------- */static int parse_simple(const char *file, FILE *fp, char *ptr, cfgStruct cfg[], int *line){	char *parameter;	char *parameter_buf;	int parameter_line;	char *value;	int error_code;	parameter_buf = ptr;	parameter_line = *line;	if ((ptr = parse_word(ptr, &parameter, CFG_PARAMETER)) == NULL) {	/* malloc parameter */		return (CFG_SYNTAX_ERROR);	}	if (*ptr == '{') {		ptr = rm_first_spaces(ptr + 1);		if (*ptr != '\0' && *ptr != '#') {			free(parameter);			return (CFG_SYNTAX_ERROR);		}		if (parse_values_between_braces(file, fp, parameter, cfg, line, CFG_SIMPLE, 0, parameter_buf, parameter_line) != CFG_NO_ERROR) {			return (CFG_JUST_RETURN_WITHOUT_MSG);	/* error handling has already done */		}	} else {		if ((ptr = parse_word(ptr, &value, CFG_VALUE)) == NULL) {	/* malloc value */			free(parameter);			return (CFG_SYNTAX_ERROR);		}		if ((error_code = store_value(cfg, parameter, value, CFG_SIMPLE, 0)) != CFG_NO_ERROR) {			free(parameter);			free(value);			return (error_code);		}		free(parameter);		free(value);	}	return (CFG_NO_ERROR);}/* --------------------------------------------------   NAME       parse_word   FUNCTION   parse a word   INPUT      ptr ... pointer of current parsing              word .. pointer of pointer for parsed word                      (dynamic allocating)              word_type ... what word type parse as                            + CFG_PARAMETER ... parameter                            + CFG_VALUE ....... value                             + CFG_SECTION ..... section   OUTPUT     new current pointer (on error, return NULL)-------------------------------------------------- */static char *parse_word(char *ptr, char **word, cfgKeywordValue word_type){	int len = 0;	cfgQuote quote_flag;	switch (*ptr) {	case '\"':		quote_flag = CFG_DOUBLE_QUOTE;		ptr++;		break;	case '\'':		quote_flag = CFG_SINGLE_QUOTE;		ptr++;		break;	default:		quote_flag = CFG_NO_QUOTE;

⌨️ 快捷键说明

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