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

📄 keydata.c

📁 multi-line Adjunct Communication Server
💻 C
字号:
/*** Copyright (C) 1999-2000 Open Source Telecom Corporation.**  ** 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 of the License, 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.**** As a special exception to the GNU General Public License, permission is** granted for additional uses of the text contained in its release** of ACS as noted here.**** This exception is that permission is hereby granted to link ACS with** the Pika MonteCarlo static libraries to produce a executable image** without requiring MonteCarlo itself to be supplied in source form so** long as each source file so linked contains this exclusion.**** This exception does not however invalidate any other reasons why** the resulting executable file might be covered by the GNU General** public license or invalidate the licensing requirements of any** other component or library.**** This exception applies only to the code released by OST under the** name ACS.  If you copy code from other releases into a copy of** ACS, as the General Public License permits, the exception does not** apply to the code that you add in this way.  To avoid misleading** anyone as to the status of such modified files, you must delete** this exception notice from them.**** If you write modifications of your own to ACS, it is your choice** whether to permit this exception to apply to your modifications.** If you do not wish that, delete this exception notice, at which** point the terms of your modification would be covered under the GPL** as explicitly stated in "COPYING".*/#include <string.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <stdio.h>#include "keydata.h"#ifndef	KEY_INDEXSIZE#define	KEY_INDEXSIZE	97#endif#ifdef HAVE_CONFIG_H#include "config.h"#endiftypedef struct _keyval{	struct _keyval *next;	char val[1];}	keyval_t;typedef	struct _keysym{	struct _keysym *next;	struct _keyval *data;	char **list;	short count;	char sym[1];}	keysym_t;typedef	struct{	keysym_t *hash[KEY_INDEXSIZE];}	keyidx_t;static	FILE	*fp = NULL;static	char	lastpath[257] = "";keydata_t *newkeydata(void){	keydata_t *root = (keydata_t *)malloc(sizeof(keydata_t));	if(!root)		return NULL;	root->next = NULL;	root->used = sizeof(keyidx_t);	memset(root->page, 0, sizeof(keyidx_t));	return root;}static void *getkeymem(keydata_t *root, size_t len){	void *p;	keydata_t *last = root;	while(last->next)		last = last->next;	if(!last)	{		last = root = (keydata_t *)malloc(sizeof(keydata_t));		root->next = NULL;		root->used = 0;	} 	else if((last->used + len) > (sizeof(keydata_t) - sizeof(keydata_t *) - sizeof(size_t)))	{		last->next = (keydata_t *)malloc(sizeof(keydata_t));		last = last->next;		last->next = NULL;		last->used = 0;	}	p = &last->page[last->used];	last->used += len;	return p;}		static void endkeymem(keydata_t *root){	keydata_t *next;		while(root)	{		next = root->next;		free(root);		root = next;	}}static unsigned getkeypath(char *str){	unsigned key = 0;	while(*str)		key = (key << 1) ^ *(str++);	return key % KEY_INDEXSIZE;}int	getkeyindex(keydata_t *root, char **data, int max){	int idx;	keyidx_t *keys = (keyidx_t *)root->page;	keysym_t *key;	int count = 0;	for(idx = 0; idx < KEY_INDEXSIZE; ++idx)	{		if(count >= max)			break;		key = keys->hash[idx];		while(key && count < max)		{			*(data++) = key->sym;			++count;		}	}	*data = NULL;	return count;}static keysym_t *getkeysym(keydata_t *root, char *sym, int create){	unsigned path = getkeypath(sym);	keyidx_t *keys = (keyidx_t *)root->page;	keysym_t *key = keys->hash[path];	while(key)	{		if(!stricmp(sym, key->sym))			return key;		key = key->next;	}	if(!create)		return key;		key = (keysym_t *)getkeymem(root, sizeof(keysym_t) + strlen(sym)); 	strcpy(key->sym, sym);	key->count = 0;	key->next = keys->hash[path];	keys->hash[path] = key;	key->data = NULL;	key->list = NULL;	return key;}void endkeydata(keydata_t *root){	if(fp)	{		fclose(fp);		fp = NULL;		lastpath[0] = 0;	}	if(root)		endkeymem(root);}void setkeyvalue(keydata_t *root, char *sym, char *data){	keysym_t *key = getkeysym(root, sym, 1);	keyval_t *val;	if(!data)		data = "";		val = getkeymem(root, sizeof(keyval_t) + strlen(data));	++key->count;	key->list = NULL;	val->next = key->data;	key->data = val;	strcpy(val->val, data);	}char *getkeylast(keydata_t *root, char *sym){	keysym_t *key = getkeysym(root, sym, 0);	if(!key)		return NULL;	if(!key->data)		return NULL;	return key->data->val;}	char *getkeyfirst(keydata_t *root, char *sym){	keysym_t *key = getkeysym(root, sym, 0);	keyval_t *val;	if(!key)		return NULL;	val = key->data;	if(!val)		return NULL;	while(val->next)		val = val->next;	return val->val;}int getkeycount(keydata_t *root, char *sym){	keysym_t *key = getkeysym(root, sym, 0);	if(!key)		return 0;	return key->count;}char	**getkeylist(keydata_t *root, char *sym){	int count;	keysym_t *key = getkeysym(root, sym, 0);	keyval_t *data;	if(!key)		return NULL;	count = key->count;	if(!count)		return NULL;	++count;	if(!key->list)	{		key->list = (char **)getkeymem(root, sizeof(char **) * count);		key->list[--count] = NULL;		data=key->data;		while(count && data)		{			key->list[--count] = data->val;			data=data->next;		}		while(count)			key->list[--count] = "";	}	return key->list;}void clrkeyvalue(keydata_t *root, char *sym){	keysym_t *key = getkeysym(root, sym, 0);	if(!key)		return;	key->count = 0;	key->list = NULL;	key->data = NULL;}keydata_t *addkeydata(keydata_t *root, char *keypath){	char path[512];	char seek[17];	char find[17];	char *prefix = NULL;	char *cp, *ep;	int fpos;	keysym_t *sym;	keyval_t *val;	if(*keypath == '~')	{		prefix = getenv("HOME");		strcpy(path, prefix);		strcat(path, "/.");		++keypath;	}	if(!prefix)	{		prefix = getenv("CONFIG_KEYDATA");		if(!prefix)			prefix = "/etc/";		strcpy(path, prefix);		prefix = NULL;	}	if(*keypath == '/')		++keypath;	strcat(path, keypath);	cp = strrchr(path, '/');	strncpy(seek, cp + 1, 16);	seek[16] = 0;	*cp = 0;	if(!prefix)		strcat(path, ".conf");	if(strcmp(path, lastpath))	{		endkeydata(NULL);		if(fp)			fclose(fp);		fp = fopen(path, "r");		if(!fp && !prefix)			fp = fopen(path + 5, "r");		if(!fp)				return NULL;		strcpy(lastpath, path);		}	find[0] = 0;	fseek(fp, 0l, SEEK_SET);	while(stricmp(seek, find))	{		fgets(path, sizeof(path) - 1, fp);		if(feof(fp)) 			return NULL;		cp = path;		while(*cp == ' ' || *cp == '\n' || *cp == '\t')			++cp;		if(*cp != '[')			continue;				ep = strchr(cp, ']');		if(ep)			*ep = 0;		else			continue;		strncpy(find, ++cp, 16);		find[16] = 0;	}	for(;;)	{		fgets(path, sizeof(path) - 1, fp);		if(feof(fp))			return root;		cp = path;		while(*cp == ' ' || *cp == '\t' || *cp == '\n')			++cp;		if(!*cp || *cp == '#' || *cp == ';' || *cp == '!')			continue;		if(*cp == '[')			return root;				fpos = 0;		while(*cp && *cp != '=')		{			if(*cp == ' ' || *cp == '\t')			{				++cp;				continue;			}			find[fpos] = *(cp++);			if(fpos < 16)				++fpos;		}		find[fpos] = 0;		if(*cp != '=')			continue;				++cp;		while(*cp == ' ' || *cp == '\t' || *cp == '\n')			++cp;			ep = cp + strlen(cp);		while((--ep) > cp)		{			if(*ep == ' ' || *ep == '\t' || *ep == '\n')				*ep = 0;			else				break;		}		setkeyvalue(root, find, cp);	}		}keydata_t *getkeydata(char *path){	keydata_t *root = newkeydata();	keydata_t *p;	if(root)		p = addkeydata(root, path);	if(!p)		endkeymem(root);	return p;}

⌨️ 快捷键说明

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