· 4 years ago · Mar 16, 2021, 01:48 AM
1/*
2 * test.c
3 *
4 * Copyright 2021 Luis "Laffin" Espinoza <laffintoo at gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 *
21 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <io.h>
28#include <sys/stat.h>
29
30#define ERR (0)
31#define OK (!ERR)
32
33typedef struct st_config {
34 char *key, *val;
35} st_config;
36
37enum Configs {CFG_X64,CFG_END};
38
39st_config config[] = {
40 {"sys", "x64"}, {"efi", "no"},
41 {"cpu", "host"}, {"cores", "2"},
42 {"mem", "2G"}, {"acc", "yes"},
43 {"vga", "virtio"}, {"snd", "hda"},
44 {"boot", "c"}, {"fwd_ports", "2222:22"},
45 {"hdd_virtio", "yes"}, {"net", "virtio-net-pci"},
46 {"rng_dev", "yes"}, {"host_video_acc", "no"},
47 {"localtime", "no"}, {"headless", "no"},
48 {"vnc_pwd", ""}, {"monitor_port", "5510"},
49 {"shared",""},
50 {NULL,NULL}
51};
52/**
53 * @brief Symbols Table
54 *
55 *
56 */
57typedef struct st_symbols {
58 struct st_symbols *next; /**< Link List Next Element */
59 long hash; /**< Hash Value*/
60 char *key, /**< Symbol Name */
61 *val; /**< Symbol Value */
62} st_symbols;
63
64/**
65 * @brief Hash Table
66 *
67 *
68 */
69typedef struct st_hashmap {
70 long hash; /**< Hash Value*/
71 st_symbols *symbol; /**< Pointer to Symbol */
72} st_hashmap;
73
74/**
75 * @brief Holds symbol & hashmap pointers
76 *
77 *
78 *
79 */
80typedef struct st_syminfo {
81 int count; /**< Number of elements in Symbol Table */
82 st_symbols *symbols; /**< Pointer to symbols link list*/
83 st_hashmap *hashmap; /**< Pointer to hashmap */
84} st_syminfo;
85
86/**
87 * @brief Detects whether fpath exisrs and type
88 * @param fpath File or Directory path
89 * @return 0 Failure
90 * @return 1 File
91 * @return 2 Directory
92 *
93 */
94int filetype(const char *fpath) {
95 struct stat sb;
96 int ret;
97 if(ret=(access (fpath,0) == 0)) {
98 stat(fpath,&sb);
99 ret+=(sb.st_mode&S_IFREG)>0; // If not file must be directory
100 }
101 return ret;
102}
103
104
105/**
106 * @brief Keeps track of symbol info, creates if necessary
107 * @returns symbol info
108 *
109 *
110 */
111st_symbols *sym_base(void)
112{
113 static st_syminfo *base=NULL;
114 if(base==NULL) {
115 base=calloc(1,sizeof(st_syminfo));
116 }
117 return base;
118}
119
120/**
121 * @brief Find a symbol by its hash
122 * @param hash - symbol hash we looking for
123 * @return - pointer to symbol
124 * @return - NULL if not found
125 *
126 *
127 */
128st_symbols *sym_find_hash(long hash)
129{
130 int count=0;
131 st_syminfo *si;
132 st_symbols *sym=NULL;
133
134 si=sym_base();
135 while(count<si->count) {
136 if(si->hashmap[count].hash==hash)
137 sym=si->hashmap[count].symbol;
138 break;
139 }
140 return sym;
141}
142
143/**
144 * @brief Generate a hash based on string characters
145 * @param str - string to generare hash from
146 * @returns - hash value
147 *
148 *
149 */
150long sym_hash_generate(char *str,int exists)
151{
152 int pos;
153 long hash=0xCAFEBABE;
154 for(;;) {
155 pos=0;
156 while(str[pos]) {
157 hash=-
158 (((((hash&0xFF)^str[pos])<<5)|
159 (((hash>>26)&0x1f)^(pos&31)))|
160 (hash<<18));
161 pos++;
162 }
163 if(!hash || (!exists && sym_find_hash(hash)))
164 continue;
165 else if(exists)
166 hash=sym_find_hash(hash)?hash:0;
167 break;
168 }
169 return hash;
170}
171
172
173st_symbols *sym_find_name(char *name)
174{
175 long hash;
176
177 hash=sym_hash_generate(name,1);
178
179 return hash?sym_find_hash(hash):NULL;
180}
181
182int sym_add(char *key,char *val)
183{
184 long hash;
185 st_syminfo *si;
186 st_symbols *sym;
187
188 si=sym_base();
189 hash=sym_hash_generate(key,0);
190 if(!si->count) {
191 sym=si->symbols=calloc(1,sizeof(st_symbols));
192 if(sym)
193 si->hashmap=calloc(1,sizeof(st_hashmap));
194 } else {
195 sym=si->hashmap[si->count-1].symbol;
196 sym=sym->next=calloc(1,sizeof(st_symbols));
197 if(sym) {
198 si->hashmap=realloc(si->hashmap,sizeof(st_hashmap)*(si->count+1));
199 if(!si->hashmap) {
200 free(sym);
201 sym=sym->next=NULL;
202 }
203 }
204 }
205 if(!sym) return ERR;
206 si->hashmap[si->count].symbol=sym;
207 sym->hash=si->hashmap[si->count].hash=hash;
208 sym->key=strdup(key);
209 sym->val=strdup(val);
210 si->count++;
211 return OK;
212}
213
214int sym_set(char *key,char *val)
215{
216 int ret=OK;
217
218 st_symbols *sym;
219 if(sym=sym_find_name(key)) {
220 if(sym->val)
221 free(sym->val);
222 sym->val=strdup(val);
223 } else {
224 ret=sym_add(key,val);
225 }
226 return ret;
227}
228
229char *sym_get(char *key)
230{
231 st_symbols *sym;
232 sym=sym_find_name(key);
233 return sym->val;
234}
235
236
237void cfg_set_default(int profile)
238{
239 st_config *dflt;
240
241 dflt=config;
242 while(dflt->key) {
243 sym_set(dflt->key,dflt->val);
244 dflt++;
245 }
246}
247
248int main(int argc, char **argv)
249{
250 st_syminfo *si;
251 st_symbols *sym;
252
253 si=sym_base();
254 cfg_set_default(CFG_X64);
255 sym=si->symbols;
256 while(sym) {
257 printf("(%8X) %s = '%s' \n",sym->hash,sym->key,sym->val);
258 sym=sym->next;
259 }
260 return 0;
261}