mirror of
https://github.com/curl/curl.git
synced 2024-12-27 06:59:43 +08:00
d6447b1bd2
This tool generates a scheme-matching table. It iterates over a number of different initial and shift values in order to find the hash algorithm that needs the smallest possible table. The generated hash function, table and table size then needs to be used by the url.c:Curl_getn_scheme_handler() function.
208 lines
6.0 KiB
C
208 lines
6.0 KiB
C
/***************************************************************************
|
|
* _ _ ____ _
|
|
* Project ___| | | | _ \| |
|
|
* / __| | | | |_) | |
|
|
* | (__| |_| | _ <| |___
|
|
* \___|\___/|_| \_\_____|
|
|
*
|
|
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
*
|
|
* This software is licensed as described in the file COPYING, which
|
|
* you should have received as part of this distribution. The terms
|
|
* are also available at https://curl.se/docs/copyright.html.
|
|
*
|
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
* copies of the Software, and permit persons to whom the Software is
|
|
* furnished to do so, under the terms of the COPYING file.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
* SPDX-License-Identifier: curl
|
|
*
|
|
***************************************************************************/
|
|
#include <stdio.h>
|
|
#include <curl/curl.h>
|
|
|
|
/*
|
|
* Use this tool to generate an updated table for the Curl_getn_scheme_handler
|
|
* function in url.c.
|
|
*/
|
|
|
|
struct detail {
|
|
const char *n;
|
|
const char *ifdef;
|
|
};
|
|
|
|
static const struct detail scheme[] = {
|
|
{"dict", "#ifndef CURL_DISABLE_DICT" },
|
|
{"file", "#ifndef CURL_DISABLE_FILE" },
|
|
{"ftp", "#ifndef CURL_DISABLE_FTP" },
|
|
{"ftps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)" },
|
|
{"gopher", "#ifndef CURL_DISABLE_GOPHER" },
|
|
{"gophers", "#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER)" },
|
|
{"http", "#ifndef CURL_DISABLE_HTTP" },
|
|
{"https", "#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)" },
|
|
{"imap", "#ifndef CURL_DISABLE_IMAP" },
|
|
{"imaps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)" },
|
|
{"ldap", "#ifndef CURL_DISABLE_LDAP" },
|
|
{"ldaps", "#if !defined(CURL_DISABLE_LDAP) && \\\n"
|
|
" !defined(CURL_DISABLE_LDAPS) && \\\n"
|
|
" ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \\\n"
|
|
" (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))" },
|
|
{"mqtt", "#ifndef CURL_DISABLE_MQTT" },
|
|
{"pop3", "#ifndef CURL_DISABLE_POP3" },
|
|
{"pop3s", "#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)" },
|
|
{"rtmp", "#ifdef USE_LIBRTMP" },
|
|
{"rtmpt", "#ifdef USE_LIBRTMP" },
|
|
{"rtmpe", "#ifdef USE_LIBRTMP" },
|
|
{"rtmpte", "#ifdef USE_LIBRTMP" },
|
|
{"rtmps", "#ifdef USE_LIBRTMP" },
|
|
{"rtmpts", "#ifdef USE_LIBRTMP" },
|
|
{"rtsp", "#ifndef CURL_DISABLE_RTSP" },
|
|
{"scp", "#if defined(USE_SSH) && !defined(USE_WOLFSSH)" },
|
|
{"sftp", "#if defined(USE_SSH)" },
|
|
{"smb", "#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \\\n"
|
|
" (SIZEOF_CURL_OFF_T > 4)" },
|
|
{"smbs", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMB) && \\\n"
|
|
" defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)" },
|
|
{"smtp", "#ifndef CURL_DISABLE_SMTP" },
|
|
{"smtps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)" },
|
|
{"telnet", "#ifndef CURL_DISABLE_TELNET" },
|
|
{"tftp", "#ifndef CURL_DISABLE_TFTP" },
|
|
{"ws", "#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)" },
|
|
{"wss", "#if defined(USE_WEBSOCKETS) && \\\n"
|
|
" defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)" },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
unsigned int calc(const char *s, int add, int shift)
|
|
{
|
|
const char *so = s;
|
|
unsigned int c = add;
|
|
while(*s) {
|
|
c <<= shift;
|
|
c += *s;
|
|
s++;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
unsigned int num[100];
|
|
unsigned int ix[100];
|
|
|
|
static void showtable(int try, int init, int shift)
|
|
{
|
|
int nulls = 0;
|
|
int i;
|
|
for(i = 0; scheme[i].n; ++i)
|
|
num[i] = calc(scheme[i].n, init, shift);
|
|
for(i = 0; scheme[i].n; ++i)
|
|
ix[i] = num[i] % try;
|
|
printf("/*\n"
|
|
" unsigned int c = %d\n"
|
|
" while(l) {\n"
|
|
" c <<= %d;\n"
|
|
" c += Curl_raw_tolower(*s);\n"
|
|
" s++;\n"
|
|
" l--;\n"
|
|
" }\n"
|
|
"*/\n", init, shift);
|
|
|
|
printf(" static const struct Curl_handler * const protocols[%d] = {", try);
|
|
|
|
/* generate table */
|
|
for(i=0; i < try; i++) {
|
|
int match = 0;
|
|
int j;
|
|
for(j=0; scheme[j].n; j++) {
|
|
if(ix[j] == i) {
|
|
printf("\n");
|
|
printf("%s\n", scheme[j].ifdef);
|
|
printf(" &Curl_handler_%s,\n", scheme[j].n);
|
|
printf("#else\n NULL,\n");
|
|
printf("#endif");
|
|
match = 1;
|
|
nulls = 0;
|
|
break;
|
|
}
|
|
}
|
|
if(!match) {
|
|
if(!nulls || (nulls>10)) {
|
|
printf("\n ");
|
|
nulls = 0;
|
|
}
|
|
printf(" NULL,", nulls);
|
|
nulls++;
|
|
}
|
|
}
|
|
printf("\n };\n");
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int i;
|
|
int try;
|
|
int besttry = 9999;
|
|
int bestadd = 0;
|
|
int bestshift = 0;
|
|
int add;
|
|
int shift;
|
|
for(shift = 0; shift < 8; shift++) {
|
|
for(add = 0; add < 999; add++) {
|
|
for(i = 0; scheme[i].n; ++i) {
|
|
unsigned int v = calc(scheme[i].n, add, shift);
|
|
int j;
|
|
int badcombo = 0;
|
|
for(j=0; j < i; j++) {
|
|
|
|
if(num[j] == v) {
|
|
/*
|
|
printf("NOPE: %u is a dupe (%s and %s)\n",
|
|
v, scheme[i], scheme[j]);
|
|
*/
|
|
badcombo = 1;
|
|
break;
|
|
}
|
|
}
|
|
if(badcombo)
|
|
break;
|
|
num[i] = v;
|
|
}
|
|
#if 0
|
|
for(i = 0; scheme[i].n; ++i) {
|
|
printf("%u - %s\n", num[i], scheme[i].n);
|
|
}
|
|
#endif
|
|
/* try different remainders to find smallest possible table */
|
|
for(try = 28; try < 199; try++) {
|
|
int good = 1;
|
|
for(i = 0; scheme[i].n; ++i) {
|
|
ix[i] = num[i] % try;
|
|
}
|
|
/* check for dupes */
|
|
for(i = 0; scheme[i].n && good; ++i) {
|
|
int j;
|
|
for(j=0; j < i; j++) {
|
|
if(ix[j] == ix[i]) {
|
|
/* printf("NOPE, try %u causes dupes (%d and %d)\n", try, j, i); */
|
|
good = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(good) {
|
|
if(try < besttry) {
|
|
besttry = try;
|
|
bestadd = add;
|
|
bestshift = shift;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
showtable(besttry, bestadd, bestshift);
|
|
}
|