16a5c94d9SSamuel Thibault /* SPDX-License-Identifier: GPL-2.0+ */
26a5c94d9SSamuel Thibault /* utils.h
36a5c94d9SSamuel Thibault  * originally written by: Kirk Reiser.
46a5c94d9SSamuel Thibault  *
56a5c94d9SSamuel Thibault  ** Copyright (C) 2002  Kirk Reiser.
66a5c94d9SSamuel Thibault  *  Copyright (C) 2003  David Borowski.
76a5c94d9SSamuel Thibault  */
86a5c94d9SSamuel Thibault 
96a5c94d9SSamuel Thibault #include <stdio.h>
106a5c94d9SSamuel Thibault 
116a5c94d9SSamuel Thibault #define MAXKEYS 512
126a5c94d9SSamuel Thibault #define MAXKEYVAL 160
136a5c94d9SSamuel Thibault #define HASHSIZE 101
146a5c94d9SSamuel Thibault #define is_shift -3
156a5c94d9SSamuel Thibault #define is_spk -2
166a5c94d9SSamuel Thibault #define is_input -1
176a5c94d9SSamuel Thibault 
186a5c94d9SSamuel Thibault struct st_key {
196a5c94d9SSamuel Thibault 	char *name;
206a5c94d9SSamuel Thibault 	struct st_key *next;
216a5c94d9SSamuel Thibault 	int value, shift;
226a5c94d9SSamuel Thibault };
236a5c94d9SSamuel Thibault 
246a5c94d9SSamuel Thibault struct st_key key_table[MAXKEYS];
256a5c94d9SSamuel Thibault struct st_key *extra_keys = key_table+HASHSIZE;
266a5c94d9SSamuel Thibault char *def_name, *def_val;
276a5c94d9SSamuel Thibault FILE *infile;
286a5c94d9SSamuel Thibault int lc;
296a5c94d9SSamuel Thibault 
306a5c94d9SSamuel Thibault char filename[256];
316a5c94d9SSamuel Thibault 
open_input(const char * dir_name,const char * name)326a5c94d9SSamuel Thibault static inline void open_input(const char *dir_name, const char *name)
336a5c94d9SSamuel Thibault {
346a5c94d9SSamuel Thibault 	if (dir_name)
356a5c94d9SSamuel Thibault 		snprintf(filename, sizeof(filename), "%s/%s", dir_name, name);
366a5c94d9SSamuel Thibault 	else
376a5c94d9SSamuel Thibault 		snprintf(filename, sizeof(filename), "%s", name);
386a5c94d9SSamuel Thibault 	infile = fopen(filename, "r");
396a5c94d9SSamuel Thibault 	if (infile == 0) {
406a5c94d9SSamuel Thibault 		fprintf(stderr, "can't open %s\n", filename);
416a5c94d9SSamuel Thibault 		exit(1);
426a5c94d9SSamuel Thibault 	}
436a5c94d9SSamuel Thibault 	lc = 0;
446a5c94d9SSamuel Thibault }
456a5c94d9SSamuel Thibault 
oops(const char * msg,const char * info)466a5c94d9SSamuel Thibault static inline int oops(const char *msg, const char *info)
476a5c94d9SSamuel Thibault {
486a5c94d9SSamuel Thibault 	if (info == NULL)
496a5c94d9SSamuel Thibault 		info = "";
506a5c94d9SSamuel Thibault 	fprintf(stderr, "error: file %s line %d\n", filename, lc);
516a5c94d9SSamuel Thibault 	fprintf(stderr, "%s %s\n", msg, info);
526a5c94d9SSamuel Thibault 	exit(1);
536a5c94d9SSamuel Thibault }
546a5c94d9SSamuel Thibault 
hash_name(char * name)556a5c94d9SSamuel Thibault static inline struct st_key *hash_name(char *name)
566a5c94d9SSamuel Thibault {
57*92ca969fSĐoàn Trần Công Danh 	unsigned char *pn = (unsigned char *)name;
586a5c94d9SSamuel Thibault 	int hash = 0;
596a5c94d9SSamuel Thibault 
606a5c94d9SSamuel Thibault 	while (*pn) {
616a5c94d9SSamuel Thibault 		hash = (hash * 17) & 0xfffffff;
626a5c94d9SSamuel Thibault 		if (isupper(*pn))
636a5c94d9SSamuel Thibault 			*pn = tolower(*pn);
646a5c94d9SSamuel Thibault 		hash += (int)*pn;
656a5c94d9SSamuel Thibault 		pn++;
666a5c94d9SSamuel Thibault 	}
676a5c94d9SSamuel Thibault 	hash %= HASHSIZE;
686a5c94d9SSamuel Thibault 	return &key_table[hash];
696a5c94d9SSamuel Thibault }
706a5c94d9SSamuel Thibault 
find_key(char * name)716a5c94d9SSamuel Thibault static inline struct st_key *find_key(char *name)
726a5c94d9SSamuel Thibault {
736a5c94d9SSamuel Thibault 	struct st_key *this = hash_name(name);
746a5c94d9SSamuel Thibault 
756a5c94d9SSamuel Thibault 	while (this) {
766a5c94d9SSamuel Thibault 		if (this->name && !strcmp(name, this->name))
776a5c94d9SSamuel Thibault 			return this;
786a5c94d9SSamuel Thibault 		this = this->next;
796a5c94d9SSamuel Thibault 	}
806a5c94d9SSamuel Thibault 	return this;
816a5c94d9SSamuel Thibault }
826a5c94d9SSamuel Thibault 
add_key(char * name,int value,int shift)836a5c94d9SSamuel Thibault static inline struct st_key *add_key(char *name, int value, int shift)
846a5c94d9SSamuel Thibault {
856a5c94d9SSamuel Thibault 	struct st_key *this = hash_name(name);
866a5c94d9SSamuel Thibault 
876a5c94d9SSamuel Thibault 	if (extra_keys-key_table >= MAXKEYS)
886a5c94d9SSamuel Thibault 		oops("out of key table space, enlarge MAXKEYS", NULL);
896a5c94d9SSamuel Thibault 	if (this->name != NULL) {
906a5c94d9SSamuel Thibault 		while (this->next) {
916a5c94d9SSamuel Thibault 			if (!strcmp(name, this->name))
926a5c94d9SSamuel Thibault 				oops("attempt to add duplicate key", name);
936a5c94d9SSamuel Thibault 			this = this->next;
946a5c94d9SSamuel Thibault 		}
956a5c94d9SSamuel Thibault 		this->next = extra_keys++;
966a5c94d9SSamuel Thibault 		this = this->next;
976a5c94d9SSamuel Thibault 	}
986a5c94d9SSamuel Thibault 	this->name = strdup(name);
996a5c94d9SSamuel Thibault 	this->value = value;
1006a5c94d9SSamuel Thibault 	this->shift = shift;
1016a5c94d9SSamuel Thibault 	return this;
1026a5c94d9SSamuel Thibault }
103