| /* 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) { | |
| 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; | |
| } |