OSDN Git Service

Nazghul-0.7.1
[nazghul-jp/nazghul-jp.git] / src / cfg.c
1 /* $Id: cfg.c,v 1.4 2010/08/26 05:56:20 gmcnutt Exp $
2  *
3  * Copyright (C) 2006 Gordon McNutt
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Foundation, Inc., 59 Temple Place,
17  * Suite 330, Boston, MA 02111-1307 USA
18  */
19
20 #include "cfg.h"
21 #include "repstr.h"
22
23 #include <assert.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #define CFG_HASH_SIZE 31
28
29 struct cfg_entry {
30         struct cfg_entry *next;
31         char *key, *val;        
32 } *cfg_hash[CFG_HASH_SIZE];
33
34 static struct cfg_entry *cfg_entry_new(const char *key, const char *val)
35 {
36         struct cfg_entry *entry = (struct cfg_entry*)malloc(sizeof(*entry));
37         assert(entry);
38         entry->next = 0;
39         entry->key = strdup(key);
40         assert(entry->key);
41         if (val) {
42                 entry->val = strdup(val);
43                 assert(entry->val);
44         } else {
45                 entry->val = 0;
46         }
47         return entry;
48 }
49
50 static int hashfn(const char *key)
51 {
52         unsigned int hashed = 0; 
53         const char *c; 
54         static const int bits_per_int = sizeof(unsigned int)*8; 
55
56         for (c = key; *c; c++) { 
57                 /* letters have about 5 bits in them */ 
58                 hashed = (hashed<<5) | (hashed>>(bits_per_int-5)); 
59                 hashed ^= *c; 
60         } 
61         return hashed % CFG_HASH_SIZE;
62 }
63
64 int cfg_init()
65 {
66         memset(cfg_hash, 0, sizeof(cfg_hash));
67         return 0;
68 }
69
70 void cfg_set(const char *key, const char *val)
71 {
72         int hashkey = hashfn(key);
73         struct cfg_entry *entry = cfg_hash[hashkey];
74         if (! entry) {
75                 cfg_hash[hashkey] = cfg_entry_new(key, val);
76         } else {
77                 int match = !strcmp(entry->key, key);
78                 while (! match
79                        && entry->next) {
80                         entry = entry->next;
81                         match = !strcmp(entry->key, key);
82                 }
83                 if (match) {
84                         repstr(&entry->val, val);
85                 } else {
86                         entry->next = cfg_entry_new(key, val);
87                 }
88         }
89 }
90
91 char *cfg_get(const char *key)
92 {
93         int hashkey = hashfn(key);
94         struct cfg_entry *entry = cfg_hash[hashkey];
95         if (! entry) {
96                 return 0;
97         } else {
98                 int match = !strcmp(entry->key, key);
99                 while (! match
100                        && entry->next) {
101                         entry = entry->next;
102                         match = !strcmp(entry->key, key);
103                 }
104                 if (match) {
105                         return entry->val;
106                 } else {
107                         return 0;
108                 }
109         }
110 }