Last active
April 4, 2020 01:12
-
-
Save DaelonSuzuka/4751e264a4dadf15286f4719fda4e779 to your computer and use it in GitHub Desktop.
gperf script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "usb_json_hash.h" | |
#include "os/serial_port.h" | |
#include "os/shell/shell_command_processor.h" | |
#include <stdint.h> | |
#include <string.h> | |
/* ************************************************************************** */ | |
/* [[[cog | |
import cogutils as utils, codegen as code | |
keys = utils.search('src/usb/usb_messages.c', r'(?<={nKey, ").*?(?="})') | |
prefix = 'hash_' | |
enum = code.Enum( | |
name = 'hash_value_t', | |
values = keys, | |
prefix = prefix, | |
typedef = True, | |
explicit = True | |
) | |
struct = code.Struct( | |
'key', | |
['const char *name', f'{enum.name} value'], | |
).assemble() | |
cog.outl() | |
cog.outl(utils.Gperf([f'{k}, {prefix}{k}' for k in keys], struct).run()) | |
func = code.Function( | |
name = 'json_hash', | |
return_type = enum.name, | |
params = 'const char *string', | |
extern = True | |
) | |
code.Header( | |
name = cog.inFile.replace('.c', '.h'), | |
includes = '<stdint.h>', | |
contents = [enum.assemble(), func.assemble()] | |
).write() | |
]]] */ | |
/* ANSI-C code produced by gperf version 3.1 */ | |
/* Command-line: 'C:\\ProgramData\\chocolatey\\lib\\gperf\\tools\\gperf.exe' -m | |
* 100 -r -n strings.gperf */ | |
/* Computed positions: -k'3-4,9' */ | |
#if !( \ | |
(' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) && ('%' == 37) && \ | |
('&' == 38) && ('\'' == 39) && ('(' == 40) && (')' == 41) && \ | |
('*' == 42) && ('+' == 43) && (',' == 44) && ('-' == 45) && ('.' == 46) && \ | |
('/' == 47) && ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) && \ | |
('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) && \ | |
('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) && ('=' == 61) && \ | |
('>' == 62) && ('?' == 63) && ('A' == 65) && ('B' == 66) && ('C' == 67) && \ | |
('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) && ('H' == 72) && \ | |
('I' == 73) && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) && \ | |
('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) && ('R' == 82) && \ | |
('S' == 83) && ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) && \ | |
('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) && \ | |
('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) && \ | |
('a' == 97) && ('b' == 98) && ('c' == 99) && ('d' == 100) && \ | |
('e' == 101) && ('f' == 102) && ('g' == 103) && ('h' == 104) && \ | |
('i' == 105) && ('j' == 106) && ('k' == 107) && ('l' == 108) && \ | |
('m' == 109) && ('n' == 110) && ('o' == 111) && ('p' == 112) && \ | |
('q' == 113) && ('r' == 114) && ('s' == 115) && ('t' == 116) && \ | |
('u' == 117) && ('v' == 118) && ('w' == 119) && ('x' == 120) && \ | |
('y' == 121) && ('z' == 122) && ('{' == 123) && ('|' == 124) && \ | |
('}' == 125) && ('~' == 126)) | |
/* The character set is not based on ISO-646. */ | |
#error \ | |
"gperf generated tables don't work with this execution character set. Please report a bug to <[email protected]>." | |
#endif | |
struct key { | |
const char *name; | |
hash_value_t value; | |
}; | |
#define TOTAL_KEYWORDS 18 | |
#define MIN_WORD_LENGTH 2 | |
#define MAX_WORD_LENGTH 19 | |
#define MIN_HASH_VALUE 0 | |
#define MAX_HASH_VALUE 17 | |
/* maximum key range = 18, duplicates = 0 */ | |
#ifdef __GNUC__ | |
#else | |
#ifdef __cplusplus | |
#endif | |
#endif | |
static uint16_t hash(const char *str, uint8_t len) { | |
static const uint8_t asso_values[] = { | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 6, 18, 18, 18, 16, 7, 13, 8, 1, 18, 4, 11, 18, | |
18, 3, 0, 3, 1, 3, 5, 4, 1, 3, 4, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | |
18, 18, 18, 18}; | |
uint16_t hval = 0; | |
switch (len) { | |
default: | |
hval += asso_values[(uint8_t)str[8]]; | |
/*FALLTHROUGH*/ | |
case 8: | |
case 7: | |
case 6: | |
case 5: | |
case 4: | |
hval += asso_values[(uint8_t)str[3]]; | |
/*FALLTHROUGH*/ | |
case 3: | |
hval += asso_values[(uint8_t)str[2]]; | |
/*FALLTHROUGH*/ | |
case 2: | |
break; | |
} | |
return hval; | |
} | |
static const struct key wordlist[] = { | |
{"ok", hash_ok}, | |
{"ping", hash_ping}, | |
{"toggle", hash_toggle}, | |
{"minor", hash_minor}, | |
{"auto", hash_auto}, | |
{"compile_time", hash_compile_time}, | |
{"command", hash_command}, | |
{"set_antenna", hash_set_antenna}, | |
{"device_info", hash_device_info}, | |
{"serial", hash_serial}, | |
{"compiler_version", hash_compiler_version}, | |
{"compile_date", hash_compile_date}, | |
{"message_id", hash_message_id}, | |
{"request_device_info", hash_request_device_info}, | |
{"major", hash_major}, | |
{"software_version", hash_software_version}, | |
{"name", hash_name}, | |
{"patch", hash_patch}, | |
}; | |
const struct key *in_word_set(const char *str, uint8_t len) { | |
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { | |
uint16_t key = hash(str, len); | |
if (key <= MAX_HASH_VALUE) { | |
const char *s = wordlist[key].name; | |
if (*str == *s && !strcmp(str + 1, s + 1)) | |
return &wordlist[key]; | |
} | |
} | |
return 0; | |
} | |
/* [[[end]]] */ | |
/* ************************************************************************** */ | |
#if TOTAL_KEYWORDS != (MAX_HASH_VALUE + 1) | |
#error Gperf output is not minimal! | |
#endif | |
hash_value_t json_hash(const char *string) { | |
const struct key *result = in_word_set(string, strlen(string)); | |
return result->value; | |
} | |
/* ************************************************************************** */ | |
void sh_hash(int argc, char **argv) { | |
if (argc == 1) { | |
println("you didn't give me a string"); | |
return; | |
} | |
for (uint8_t i = 1; i < argc; i++) { | |
const struct key *result = in_word_set(argv[i], strlen(argv[i])); | |
if (!result) { | |
printf("'%s' wasn't in the word list\r\n", argv[i]); | |
} else { | |
printf("found '%s' [%d]\r\n", result->name, result->value); | |
} | |
} | |
} | |
REGISTER_SHELL_COMMAND(sh_hash, "hash"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _USB_JSON_HASH_H_ | |
#define _USB_JSON_HASH_H_ | |
#include <stdint.h> | |
/* ************************************************************************** */ | |
typedef enum { | |
hash_message_id = 0, | |
hash_serial = 1, | |
hash_major = 2, | |
hash_minor = 3, | |
hash_patch = 4, | |
hash_compiler_version = 5, | |
hash_compile_date = 6, | |
hash_compile_time = 7, | |
hash_request_device_info = 8, | |
hash_ping = 9, | |
hash_command = 10, | |
hash_set_antenna = 11, | |
hash_auto = 12, | |
hash_toggle = 13, | |
hash_device_info = 14, | |
hash_name = 15, | |
hash_software_version = 16, | |
hash_ok = 17, | |
} hash_value_t; | |
extern hash_value_t json_hash(const char *string); | |
#endif /* _USB_JSON_HASH_H_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment