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

📄 ini.c

📁 一个LINUX下的ini文件解析程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************File Description****************************
* Main Functions:
* Author: shaoying@nfs-china.com
* Modification Record:
*		Version		name			content
*		V1.0	  yangshaoying		create this file
* Note:
*************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "ini.h"


char CFG_SSL = '[';  /* 项标志符Section Symbol --可根据特殊需要进行定义更改,如 { }等*/
char CFG_SSR = ']';  /* 项标志符Section Symbol --可根据特殊需要进行定义更改,如 { }等*/char CFG_NIS = ':';  /* name 与 index 之间的分隔符 */char CFG_NTS = '#';  /* 注释符*/static s8 * ini_str_trim_r(s8 * buf);

static s8 * ini_str_trim_l(s8 * buf);
static s32 ini_file_get_line(FILE *fp, s8 *buffer, s32 maxlen); 
static s32 ini_split_key_value(s8 *buf, s8 **key, s8 **val); 
static s32 ini_file_copy(FILE *source_fp, s8 *dest_file); 
static s32 ini_find_key(s8 *filename, s8 * section, s8 * key, struct ini_key_location *location);


/*************************************************************
Function: 设置key的值
Input: s8 *filename 文件;s8 *section 项值;
 	   s8 *key 键值;     s8 *value key的值
Output: 
Return: 0		SUCCESS
		-1		未找到section
		-2		未找到key
		-10		文件打开失败
		-11		创建文件错误
		-12		读取文件失败
		-13     写入文件错误
		-14		文件格式错误
		-22		超出缓冲区大小 
Note: 
*************************************************************/
s32 ini_set_key(s8 *filename, s8 * section, s8 * key, s8 * value)
{
	FILE *fp1, *fp2; 
	s8 buf1[MAX_CFG_BUF + 1]; 
	s32  line_no, line_no1, n, ret, ret2; 
//	s8 tmpfname[30]; 
	struct ini_key_location location;
	
	ret = ini_find_key(filename, (s8 *)section, (s8 *)key, &location); 

	if(ret <= CFG_ERR && ret != CFG_ERR_OPEN_FILE) 
		return ret; 

	if(ret == CFG_ERR_OPEN_FILE || ret == CFG_SECTION_NOT_FOUND) { 		
		if((fp1 = fopen((s8 *)filename, "a")) == NULL) 			
			return CFG_ERR_CREATE_FILE; 
		
		if(fprintf(fp1, "%c%s%c\n", CFG_SSL, section, CFG_SSR) == EOF) { 
			fclose(fp1); 
			return CFG_ERR_WRITE_FILE; 
		} 
		if(fprintf(fp1, "%s=%s\n", key, value) == EOF) { 
			fclose(fp1); 
			return CFG_ERR_WRITE_FILE; 
		} 
		fclose(fp1); 
		return CFG_OK; 
	} 

//	strcpy(tmpfname,"/tmp/rpms_tmpXXXXXX");//	if(mktemp(tmpfname) == NULL) 
//		return CFG_ERR_CREATE_FILE; 
	
//	if((fp2 = fopen(tmpfname, "w")) == NULL) 		
//		return CFG_ERR_CREATE_FILE; 
	if((fp2 = tmpfile())==NULL)		return CFG_ERR_CREATE_FILE;
	ret2 = CFG_ERR_OPEN_FILE; 	
	if((fp1 = fopen(filename, "rb")) == NULL) 
		goto w_cfg_end; 
	
	if(ret == CFG_KEY_NOT_FOUND) 
		line_no1 = location.ini_section_line_no; 
	else /* ret = CFG_OK */ 
		line_no1 = location.ini_key_line_no - 1; 

	for(line_no = 0; line_no < line_no1; line_no++) { 
		ret2 = CFG_ERR_READ_FILE; 
		n = ini_file_get_line(fp1, buf1, MAX_CFG_BUF); 
		if(n < 0) 
			goto w_cfg_end; 
		ret2 = CFG_ERR_WRITE_FILE; 
		if(fprintf(fp2, "%s\n", buf1) == EOF) 
			goto w_cfg_end; 
	} 

	if(ret != CFG_KEY_NOT_FOUND) 
		for( ; line_no < line_no1+location.ini_key_lines; line_no++) { 
			ret2 = CFG_ERR_READ_FILE; 
			n = ini_file_get_line(fp1, buf1, MAX_CFG_BUF); 
			if(n < 0) 
				goto w_cfg_end; 
		} 
		ret2 = CFG_ERR_WRITE_FILE; 
		if(fprintf(fp2, "%s=%s\n", key, value) == EOF) goto w_cfg_end; 
		while(1) { 
			ret2 = CFG_ERR_READ_FILE; 
			n = ini_file_get_line(fp1, buf1, MAX_CFG_BUF); 
			if(n < -1) 
				goto w_cfg_end; 
			if(n < 0) 
				break; 
			ret2 = CFG_ERR_WRITE_FILE; 
			if(fprintf(fp2, "%s\n", buf1) == EOF) 
				goto w_cfg_end; 
		} 

		ret2 = CFG_OK; 
w_cfg_end: 
		if(ret2 == CFG_OK) { 
			ret = ini_file_copy(fp2, filename); 
			if(ret != 0) 
				return CFG_ERR_CREATE_FILE; 
		} 
		if(fp1 != NULL) fclose(fp1); 
		if(fp2 != NULL) fclose(fp2); 
//		unlink(tmpfname); 
		return ret2; 
} 
/*************************************************************
Function: 获得key的值
Input: s8 * filename 文件;s8 * section 项值;s8 * key 键值
Output: s8 * value key的值
Return: 0		SUCCESS
		-1		未找到section
		-2		未找到key
		-10		文件打开失败
		-12		读取文件失败
		-14		文件格式错误
		-22		超出缓冲区大小
Note: 
*************************************************************/
s32 ini_get_key(s8 *filename, s8 * section, s8 * key, s8 * value)
{
	FILE *fp; 
	s8 buf1[MAX_CFG_BUF + 1], buf2[MAX_CFG_BUF + 1]; 
	s8 *key_ptr, *val_ptr; 
	s32  n, ret; 
	
	*value='\0';
	if((fp = fopen(filename, "rb")) == NULL) 
		return CFG_ERR_OPEN_FILE; 
	
	while(1) { /* 搜找项section */ 	
		ret = CFG_ERR_READ_FILE; 
		n = ini_file_get_line(fp, buf1, MAX_CFG_BUF); 
		if(n < -1) 
			goto r_cfg_end; 
		ret = CFG_SECTION_NOT_FOUND; 
		if(n < 0) 
			goto r_cfg_end; /* 文件尾,未发现 */ 

		n = strlen(ini_str_trim_l(ini_str_trim_r(buf1))); 
		if(n == 0 || buf1[0] == CFG_NTS) 
			continue;       /* 空行 或 注释行 */ 

		ret = CFG_ERR_FILE_FORMAT; 
		if(n > 2 && ((buf1[0] == CFG_SSL && buf1[n-1] != CFG_SSR))) 
			goto r_cfg_end; 
		if(buf1[0] == CFG_SSL) { 
			buf1[n-1] = 0x00; 
			if(strcmp(buf1+1, section) == 0) 
				break; /* 找到项section */ 
		} 
	} 

	while(1){ /* 搜找key */ 
		ret = CFG_ERR_READ_FILE; 
		n = ini_file_get_line(fp, buf1, MAX_CFG_BUF); 
		if(n < -1) 
			goto r_cfg_end; 
		ret = CFG_KEY_NOT_FOUND; 
		if(n < 0) 
			goto r_cfg_end;/* 文件尾,未发现key */ 

		n = strlen(ini_str_trim_l(ini_str_trim_r(buf1))); 
		if(n == 0 || buf1[0] == CFG_NTS) 
			continue;       /* 空行 或 注释行 */ 
		ret = CFG_KEY_NOT_FOUND; 
		if(buf1[0] == CFG_SSL) 
			goto r_cfg_end; 
		if(buf1[n-1] == '+') { /* 遇+号表示下一行继续  */ 		
			buf1[n-1] = 0x00; 
			while(1) {			
				ret = CFG_ERR_READ_FILE; 
				n = ini_file_get_line(fp, buf2, MAX_CFG_BUF); 
				if(n < -1) 
					goto r_cfg_end; 
				if(n < 0) 
					break;/* 文件结束 */ 

				n = strlen(ini_str_trim_r(buf2)); 
				ret = CFG_ERR_EXCEED_BUF_SIZE; 
				if(n > 0 && buf2[n-1] == '+'){/* 遇+号表示下一行继续 */ 
				 	buf2[n-1] = 0x00; 
					if( (strlen(buf1) + strlen(buf2)) > MAX_CFG_BUF) 
						goto r_cfg_end; 
					strcat(buf1, buf2); 
					continue; 
				} 
				if(strlen(buf1) + strlen(buf2) > MAX_CFG_BUF) 
					goto r_cfg_end; 
				strcat(buf1, buf2); 
				break; 
			} 
		} 
		ret = CFG_ERR_FILE_FORMAT; 
		if(ini_split_key_value(buf1, &key_ptr, &val_ptr) != 1) 
			goto r_cfg_end; 
		ini_str_trim_l(ini_str_trim_r(key_ptr)); 
		if(strcmp(key_ptr, key) != 0) 
			continue;                                  /* 和key值不匹配 */ 
		strcpy(value, val_ptr); 
		break; 
	} 
	ret = CFG_OK; 
r_cfg_end: 
	if(fp != NULL) fclose(fp); 
	return ret; 
} 
/*************************************************************
Function: 获得所有section
Input:  s8 *filename 文件,s32 max 最大可返回的section的个数
Output: s8 *sections[] 存放section名字
Return: 返回section个数。若出错,返回负数。
		-10			文件打开出错
		-12			文件读取错误
		-14			文件格式错误
Note: 
*************************************************************/
s32 ini_get_sections(s8 *filename, u8 * sections[], s32 max)
{
	FILE *fp; 
	s8 buf1[MAX_CFG_BUF + 1]; 
	s32 n, n_sections = 0, ret; 
	
	if((fp = fopen(filename, "rb")) == NULL) 
		return CFG_ERR_OPEN_FILE; 
	
	while(1) {/*搜找项section */ 	
		ret = CFG_ERR_READ_FILE; 
		n = ini_file_get_line(fp, buf1, MAX_CFG_BUF); 
		if(n < -1) 
			goto cfg_scts_end; 
		if(n < 0)
			break;/* 文件尾 */ 
		n = strlen(ini_str_trim_l(ini_str_trim_r(buf1))); 
		if(n == 0 || buf1[0] == CFG_NTS) 
			continue;       /* 空行 或 注释行 */ 
		ret = CFG_ERR_FILE_FORMAT; 
		if(n > 2 && ((buf1[0] == CFG_SSL && buf1[n-1] != CFG_SSR))) 
			goto cfg_scts_end; 
		if(buf1[0] == CFG_SSL) {
			if (max!=0){			
				buf1[n-1] = 0x00; 
				strcpy((s8 *)sections[n_sections], buf1+1); 
				if (n_sections>=max) 
					break;		/* 超过可返回最大个数 */
			}
			n_sections++;
		} 

	} 
	ret = n_sections; 
cfg_scts_end: 
	if(fp != NULL) 
		fclose(fp); 
	return ret; 
} 


/*************************************************************
Function: 去除字符串右边的空字符
Input:  s8 * buf 字符串指针
Output: 
Return: 字符串指针
Note: 
*************************************************************/
static s8 * ini_str_trim_r(s8 * buf)
{
	s32 len,i;
	s8 * tmp = NULL;

	len = strlen(buf);
	tmp = (s8 *)malloc(len);
	
	memset(tmp,0x00,len);
	for(i = 0;i < len;i++) {
		if (buf[i] !=' ')
			break;
	}
	if (i < len) {
		strncpy(tmp,(buf+i),(len-i));
	}
	strncpy(buf,tmp,len);
	free(tmp);
	return buf;
}

/*************************************************************
Function: 去除字符串左边的空字符
Input:  s8 * buf 字符串指针
Output: 
Return: 字符串指针
Note: 
*************************************************************/
static s8 * ini_str_trim_l(s8 * buf)
{
	s32 len,i;	
	s8 * tmp=NULL;

	len = strlen(buf);
	tmp = (s8 *)malloc(len);

	memset(tmp,0x00,len);

	for(i = 0;i < len;i++) {
		if (buf[len-i-1] !=' ')
			break;
	}

⌨️ 快捷键说明

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