1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /* utils.h
3  * originally written by: Kirk Reiser.
4  *
5  ** Copyright (C) 2002  Kirk Reiser.
6  *  Copyright (C) 2003  David Borowski.
7  */
8 
9 #include <stdio.h>
10 
11 #define MAXKEYS 512
12 #define MAXKEYVAL 160
13 #define HASHSIZE 101
14 #define is_shift -3
15 #define is_spk -2
16 #define is_input -1
17 
18 struct st_key {
19 	char *name;
20 	struct st_key *next;
21 	int value, shift;
22 };
23 
24 struct st_key key_table[MAXKEYS];
25 struct st_key *extra_keys = key_table+HASHSIZE;
26 char *def_name, *def_val;
27 FILE *infile;
28 int lc;
29 
30 char filename[256];
31 
32 static inline void open_input(const char *dir_name, const char *name)
33 {
34 	if (dir_name)
35 		snprintf(filename, sizeof(filename), "%s/%s", dir_name, name);
36 	else
37 		snprintf(filename, sizeof(filename), "%s", name);
38 	infile = fopen(filename, "r");
39 	if (infile == 0) {
40 		fprintf(stderr, "can't open %s\n", filename);
41 		exit(1);
42 	}
43 	lc = 0;
44 }
45 
46 static inline int oops(const char *msg, const char *info)
47 {
48 	if (info == NULL)
49 		info = "";
50 	fprintf(stderr, "error: file %s line %d\n", filename, lc);
51 	fprintf(stderr, "%s %s\n", msg, info);
52 	exit(1);
53 }
54 
55 static inline struct st_key *hash_name(char *name)
56 {
57 	unsigned char *pn = (unsigned char *)name;
58 	int hash = 0;
59 
60 	while (*pn) {
61 		hash = (hash * 17) & 0xfffffff;
62 		if (isupper(*pn))
63 			*pn = tolower(*pn);
64 		hash += (int)*pn;
65 		pn++;
66 	}
67 	hash %= HASHSIZE;
68 	return &key_table[hash];
69 }
70 
71 static inline struct st_key *find_key(char *name)
72 {
73 	struct st_key *this = hash_name(name);
74 
75 	while (this) {
76 		if (this->name && !strcmp(name, this->name))
77 			return this;
78 		this = this->next;
79 	}
80 	return this;
81 }
82 
83 static inline struct st_key *add_key(char *name, int value, int shift)
84 {
85 	struct st_key *this = hash_name(name);
86 
87 	if (extra_keys-key_table >= MAXKEYS)
88 		oops("out of key table space, enlarge MAXKEYS", NULL);
89 	if (this->name != NULL) {
90 		while (this->next) {
91 			if (!strcmp(name, this->name))
92 				oops("attempt to add duplicate key", name);
93 			this = this->next;
94 		}
95 		this->next = extra_keys++;
96 		this = this->next;
97 	}
98 	this->name = strdup(name);
99 	this->value = value;
100 	this->shift = shift;
101 	return this;
102 }
103