|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* @file expGperf.c
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* Create a perfect hash function program and use it to compute
|
|
Packit Service |
96b5d3 |
* index values for a list of provided names. It also documents how
|
|
Packit Service |
96b5d3 |
* to incorporate that hashing function into a generated C program.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @addtogroup autogen
|
|
Packit Service |
96b5d3 |
* @{
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* This file is part of AutoGen.
|
|
Packit Service |
96b5d3 |
* Copyright (C) 1992-2016 Bruce Korb - all rights reserved
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* AutoGen is free software: you can redistribute it and/or modify it
|
|
Packit Service |
96b5d3 |
* under the terms of the GNU General Public License as published by the
|
|
Packit Service |
96b5d3 |
* Free Software Foundation, either version 3 of the License, or
|
|
Packit Service |
96b5d3 |
* (at your option) any later version.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* AutoGen is distributed in the hope that it will be useful, but
|
|
Packit Service |
96b5d3 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
96b5d3 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit Service |
96b5d3 |
* See the GNU General Public License for more details.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* You should have received a copy of the GNU General Public License along
|
|
Packit Service |
96b5d3 |
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
#ifndef SHELL_ENABLED
|
|
Packit Service |
96b5d3 |
HIDE_FN(SCM ag_scm_make_gperf(SCM name, SCM hlist))
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
return SCM_UNDEFINED;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
HIDE_FN(SCM ag_scm_gperf(SCM name, SCM str))
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
return SCM_UNDEFINED;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
#else
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*=gfunc make_gperf
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* what: build a perfect hash function program
|
|
Packit Service |
96b5d3 |
* general_use:
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* exparg: name , name of hash list
|
|
Packit Service |
96b5d3 |
* exparg: strings , list of strings to hash ,, list
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* doc: Build a program to perform perfect hashes of a known list of input
|
|
Packit Service |
96b5d3 |
* strings. This function produces no output, but prepares a program
|
|
Packit Service |
96b5d3 |
* named, @file{gperf_<name>} for use by the gperf function
|
|
Packit Service |
96b5d3 |
* @xref{SCM gperf}.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* This program will be obliterated as AutoGen exits.
|
|
Packit Service |
96b5d3 |
* However, you may incorporate the generated hashing function
|
|
Packit Service |
96b5d3 |
* into your C program with commands something like the following:
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @example
|
|
Packit Service |
96b5d3 |
* [+ (shellf "sed '/^int main(/,$d;/^#line/d' $@{gpdir@}/%s.c"
|
|
Packit Service |
96b5d3 |
* name ) +]
|
|
Packit Service |
96b5d3 |
* @end example
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* where @code{name} matches the name provided to this @code{make-perf}
|
|
Packit Service |
96b5d3 |
* function. @code{gpdir} is the variable used to store the name of the
|
|
Packit Service |
96b5d3 |
* temporary directory used to stash all the files.
|
|
Packit Service |
96b5d3 |
=*/
|
|
Packit Service |
96b5d3 |
SCM
|
|
Packit Service |
96b5d3 |
ag_scm_make_gperf(SCM name, SCM hlist)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
static bool do_cleanup = true;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
char const * gp_nam = ag_scm2zchars(name, "gp nm");
|
|
Packit Service |
96b5d3 |
char const * h_list;
|
|
Packit Service |
96b5d3 |
SCM nl_scm = scm_from_latin1_stringn(NEWLINE, (size_t)1);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (! scm_is_string(name))
|
|
Packit Service |
96b5d3 |
return SCM_UNDEFINED;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Construct the newline separated list of values
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
hlist = ag_scm_join(nl_scm, hlist);
|
|
Packit Service |
96b5d3 |
h_list = ag_scm2zchars(hlist, "hash list");
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Stash the concatenated list somewhere, hopefully without an alloc.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char * cmd = aprf(MK_GPERF_SCRIPT, make_prog, gp_nam, h_list);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Run the command and ignore the results.
|
|
Packit Service |
96b5d3 |
* In theory, the program should be ready.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
h_list = shell_cmd(cmd);
|
|
Packit Service |
96b5d3 |
AGFREE(cmd);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (h_list != NULL)
|
|
Packit Service |
96b5d3 |
free(VOIDP(h_list));
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (do_cleanup) {
|
|
Packit Service |
96b5d3 |
SCM_EVAL_CONST(MAKE_GPERF_CLEANUP);
|
|
Packit Service |
96b5d3 |
do_cleanup = false;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
return SCM_BOOL_T;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*=gfunc gperf
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* what: perform a perfect hash function
|
|
Packit Service |
96b5d3 |
* general_use:
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* exparg: name , name of hash list
|
|
Packit Service |
96b5d3 |
* exparg: str , string to hash
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* doc: Perform the perfect hash on the input string. This is only useful if
|
|
Packit Service |
96b5d3 |
* you have previously created a gperf program with the @code{make-gperf}
|
|
Packit Service |
96b5d3 |
* function @xref{SCM make-gperf}. The @code{name} you supply here must
|
|
Packit Service |
96b5d3 |
* match the name used to create the program and the string to hash must
|
|
Packit Service |
96b5d3 |
* be one of the strings supplied in the @code{make-gperf} string list.
|
|
Packit Service |
96b5d3 |
* The result will be a perfect hash index.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* See the documentation for @command{gperf(1GNU)} for more details.
|
|
Packit Service |
96b5d3 |
=*/
|
|
Packit Service |
96b5d3 |
SCM
|
|
Packit Service |
96b5d3 |
ag_scm_gperf(SCM name, SCM str)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char const * cmd;
|
|
Packit Service |
96b5d3 |
char const * key2hash = ag_scm2zchars(str, "key-to-hash");
|
|
Packit Service |
96b5d3 |
char const * gp_name = ag_scm2zchars(name, "gperf name");
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Format the gperf command and check the result. If it fits in
|
|
Packit Service |
96b5d3 |
* scribble space, use that.
|
|
Packit Service |
96b5d3 |
* (If it does fit, then the test string fits already).
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
cmd = aprf(RUN_GPERF_CMD, gp_name, key2hash);
|
|
Packit Service |
96b5d3 |
key2hash = shell_cmd(cmd);
|
|
Packit Service |
96b5d3 |
if (*key2hash == NUL)
|
|
Packit Service |
96b5d3 |
str = SCM_UNDEFINED;
|
|
Packit Service |
96b5d3 |
else
|
|
Packit Service |
96b5d3 |
str = scm_from_latin1_string(key2hash);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
AGFREE(cmd);
|
|
Packit Service |
96b5d3 |
AGFREE(key2hash);
|
|
Packit Service |
96b5d3 |
return str;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
#endif
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* @}
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* Local Variables:
|
|
Packit Service |
96b5d3 |
* mode: C
|
|
Packit Service |
96b5d3 |
* c-file-style: "stroustrup"
|
|
Packit Service |
96b5d3 |
* indent-tabs-mode: nil
|
|
Packit Service |
96b5d3 |
* End:
|
|
Packit Service |
96b5d3 |
* end of agen5/expGperf.c */
|