| /* SPDX-License-Identifier: GPL-2.0+ */ |
| /* utils.h |
| * originally written by: Kirk Reiser. |
| * |
| ** Copyright (C) 2002 Kirk Reiser. |
| * Copyright (C) 2003 David Borowski. |
| */ |
| |
| #include <stdio.h> |
| |
| #define MAXKEYS 512 |
| #define MAXKEYVAL 160 |
| #define HASHSIZE 101 |
| #define is_shift -3 |
| #define is_spk -2 |
| #define is_input -1 |
| |
| struct st_key { |
| char *name; |
| struct st_key *next; |
| int value, shift; |
| }; |
| |
| struct st_key key_table[MAXKEYS]; |
| struct st_key *extra_keys = key_table+HASHSIZE; |
| char *def_name, *def_val; |
| FILE *infile; |
| int lc; |
| |
| char filename[256]; |
| |
| static inline void open_input(const char *dir_name, const char *name) |
| { |
| if (dir_name) |
| snprintf(filename, sizeof(filename), "%s/%s", dir_name, name); |
| else |
| snprintf(filename, sizeof(filename), "%s", name); |
| infile = fopen(filename, "r"); |
| if (infile == 0) { |
| fprintf(stderr, "can't open %s\n", filename); |
| exit(1); |
| } |
| lc = 0; |
| } |
| |
| static inline int oops(const char *msg, const char *info) |
| { |
| if (info == NULL) |
| info = ""; |
| fprintf(stderr, "error: file %s line %d\n", filename, lc); |
| fprintf(stderr, "%s %s\n", msg, info); |
| exit(1); |
| } |
| |
| static inline struct st_key *hash_name(char *name) |
| { |
| unsigned char *pn = (unsigned char *)name; |
| int hash = 0; |
| |
| while (*pn) { |
| hash = (hash * 17) & 0xfffffff; |
| if (isupper(*pn)) |
| *pn = tolower(*pn); |
| hash += (int)*pn; |
| pn++; |
| } |
| hash %= HASHSIZE; |
| return &key_table[hash]; |
| } |
| |
| static inline struct st_key *find_key(char *name) |
| { |
| struct st_key *this = hash_name(name); |
| |
| while (this) { |
| if (this->name && !strcmp(name, this->name)) |
| return this; |
| this = this->next; |
| } |
| return this; |
| } |
| |
| static inline struct st_key *add_key(char *name, int value, int shift) |
| { |
| struct st_key *this = hash_name(name); |
| |
| if (extra_keys-key_table >= MAXKEYS) |
| oops("out of key table space, enlarge MAXKEYS", NULL); |
| if (this->name != NULL) { |
| while (this->next) { |
| if (!strcmp(name, this->name)) |
| oops("attempt to add duplicate key", name); |
| this = this->next; |
| } |
| this->next = extra_keys++; |
| this = this->next; |
| } |
| this->name = strdup(name); |
| this->value = value; |
| this->shift = shift; |
| return this; |
| } |