diff options
author | harti <harti@FreeBSD.org> | 2005-04-28 07:55:55 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2005-04-28 07:55:55 +0000 |
commit | 6b86becddd4b3a6be5835f1d82b8f6970a09372a (patch) | |
tree | 55eac1df47743b4f456328f864ca636a89abb33b /usr.bin/make | |
parent | 5b8bbca994dae4b36b2135df5e705e8684090b1c (diff) | |
download | FreeBSD-src-6b86becddd4b3a6be5835f1d82b8f6970a09372a.zip FreeBSD-src-6b86becddd4b3a6be5835f1d82b8f6970a09372a.tar.gz |
Move the hash function for directives into its own file and add
a Makefile target to re-created this file. Note, that there is no
explicite dependency to automatically re-create the file, because this
is needed only when the directive table changes and it requires the
(yet to come) devel/mph port.
Submitted by: Max Okumoto <okumoto@ucsd.edu> (first version)
Diffstat (limited to 'usr.bin/make')
-rw-r--r-- | usr.bin/make/Makefile | 57 | ||||
-rw-r--r-- | usr.bin/make/directive_hash.c | 66 | ||||
-rw-r--r-- | usr.bin/make/directive_hash.h | 36 | ||||
-rw-r--r-- | usr.bin/make/parse.c | 68 |
4 files changed, 160 insertions, 67 deletions
diff --git a/usr.bin/make/Makefile b/usr.bin/make/Makefile index acd90e57..ee4d7b3 100644 --- a/usr.bin/make/Makefile +++ b/usr.bin/make/Makefile @@ -4,8 +4,9 @@ PROG= make CFLAGS+=-I${.CURDIR} -SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c lst.c main.c \ - make.c parse.c str.c suff.c targ.c util.c var.c var_modify.c +SRCS= arch.c buf.c compat.c cond.c dir.c directive_hash.c for.c \ + hash.c job.c lst.c main.c make.c parse.c str.c suff.c targ.c \ + util.c var.c var_modify.c NO_WERROR= WARNS?= 3 @@ -21,6 +22,58 @@ CFLAGS+=-D__FBSDID=__RCSID main.o: ${MAKEFILE} +# Directive table. We use a hash table. This hash table has been +# generated with mph which can be found on the usual GNU mirrors. +# If you change the directives (adding, deleting, reordering) you +# need to create a new table and hash function (directive_hash). +# +# The following changes have been made to the generated code: +# +# o prefix the names of the g, T0 and T1 arrays with 'directive_'. +# +# o make the type of the tables 'const [un]signed char' (if you change +# anything make sure that the numbers fit into a char). +# +# o make the hash function use the length for termination, +# not the trailing '\0', via the -l flag in emitc and some editing. + +LOCALBASE ?= /usr/local +MPH ?= ${LOCALBASE}/bin/mph +EMITC ?= ${LOCALBASE}/bin/emitc + +.PRECIOUS: hash +hash: + ( echo '/*' ; \ + echo ' * DO NOT EDIT' ; \ + echo ' * $$FreeBSD$$' ; \ + echo -n ' * auto-generated from ' ; \ + sed -nEe '/\$$FreeBSD/s/^.*\$$(.*)\$$.*$$/\1/p' \ + ${.CURDIR}/parse.c ; \ + echo ' * DO NOT EDIT' ; \ + echo ' */' ; \ + echo '#include <sys/types.h>' ; \ + echo ; \ + echo '#include "directive_hash.h"' ; \ + echo ; \ + cat ${.CURDIR}/parse.c | sed \ + -e '1,/DIRECTIVES-START-TAG/d' \ + -e '/DIRECTIVES-END-TAG/,$$d' \ + -e 's/^[^"]*"\([^"]*\)".*$$/\1/' | \ + ${MPH} -d2 -m1 | ${EMITC} -l -s | \ + sed \ + -e 's/^static int g\[\]/static const signed char directive_g[]/' \ + -e 's/^static int T0\[\]/static const u_char directive_T0[]/' \ + -e 's/^static int T1\[\]/static const u_char directive_T1[]/' \ + -e '/^#define uchar unsigned char/d' \ + -e 's/uchar/u_char/g' \ + -e 's/^hash(/directive_hash(/' \ + -e 's/; \*kp;/; kp < key + len;/' \ + -e 's/int len)/size_t len)/' \ + -e 's/= T0\[/= directive_T0\[/' \ + -e 's/= T1\[/= directive_T1\[/' \ + -e 's/g\[f/directive_g[f/g' \ + ) > ${.CURDIR}/directive_hash.c + # Set the shell which make(1) uses. Bourne is the default, but a decent # Korn shell works fine, and much faster. Using the C shell for this # will almost certainly break everything, but it's Unix tradition to diff --git a/usr.bin/make/directive_hash.c b/usr.bin/make/directive_hash.c new file mode 100644 index 0000000..9703252 --- /dev/null +++ b/usr.bin/make/directive_hash.c @@ -0,0 +1,66 @@ +/* + * DO NOT EDIT + * $FreeBSD$ + * auto-generated from FreeBSD: src/usr.bin/make/parse.c,v 1.96 2005/04/11 07:40:54 harti Exp + * DO NOT EDIT + */ +#include <sys/types.h> + +#include "directive_hash.h" + +/* + * d=2 + * n=38 + * m=18 + * c=2.09 + * maxlen=1 + * minklen=2 + * maxklen=9 + * minchar=97 + * maxchar=119 + * loop=0 + * numiter=2 + * seed= + */ + +static const signed char directive_g[] = { + 16, 0, -1, 14, 5, 2, 2, -1, 0, 0, + -1, -1, 16, 11, -1, 15, -1, 14, 7, -1, + 8, 6, 1, -1, -1, 0, 4, 6, -1, 0, + 0, 2, 0, 13, -1, 14, -1, 0, +}; + +static const u_char directive_T0[] = { + 11, 25, 14, 30, 14, 26, 23, 15, 9, 37, + 27, 32, 27, 1, 17, 27, 35, 13, 8, 22, + 8, 28, 7, +}; + +static const u_char directive_T1[] = { + 19, 20, 31, 17, 29, 2, 7, 12, 1, 31, + 11, 18, 11, 20, 10, 2, 15, 19, 4, 10, + 13, 36, 3, +}; + + +int +directive_hash(const u_char *key, size_t len) +{ + unsigned f0, f1; + const u_char *kp = key; + + if (len < 2 || len > 9) + return -1; + + for (f0=f1=0; kp < key + len; ++kp) { + if (*kp < 97 || *kp > 119) + return -1; + f0 += directive_T0[-97 + *kp]; + f1 += directive_T1[-97 + *kp]; + } + + f0 %= 38; + f1 %= 38; + + return (directive_g[f0] + directive_g[f1]) % 18; +} diff --git a/usr.bin/make/directive_hash.h b/usr.bin/make/directive_hash.h new file mode 100644 index 0000000..12bfcc0 --- /dev/null +++ b/usr.bin/make/directive_hash.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2005 Max Okumoto. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $DragonFly$ + * $FreeBSD$ + */ +#ifndef directive_hash_h_ +#define directive_hash_h_ + +#include <sys/types.h> + +int directive_hash(const u_char *, size_t); + +#endif diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index 431d854..05701b5 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include "cond.h" #include "config.h" #include "dir.h" +#include "directive_hash.h" #include "for.h" #include "globals.h" #include "GNode.h" @@ -231,58 +232,19 @@ static struct { { ".WAIT", Wait, 0 }, }; -/* - * Directive table. We use a hash table. This hash table has been generated - * with mph which can be found on the usual GNU mirrors. If you change the - * directives (adding, deleting, reordering) you need to create a new table - * and hash function (directive_hash). The command line to generate the - * table is: - * - * mph -d2 -m1 <tab | emitc -l -s - * - * Where tab is a file containing just the directive strings, one per line. - * - * While inporting the result of this the following changes have been made - * to the generated code: - * - * prefix the names of the g, T0 and T1 arrays with 'directive_'. - * - * make the type of the tables 'const [un]signed char'. - * - * make the hash function use the length for termination, - * not the trailing '\0'. - */ static void parse_include(char *, int, int); static void parse_message(char *, int, int); static void parse_undef(char *, int, int); static void parse_for(char *, int, int); static void parse_endfor(char *, int, int); -static const signed char directive_g[] = { - 16, 0, -1, 14, 5, 2, 2, -1, 0, 0, - -1, -1, 16, 11, -1, 15, -1, 14, 7, -1, - 8, 6, 1, -1, -1, 0, 4, 6, -1, 0, - 0, 2, 0, 13, -1, 14, -1, 0, -}; - -static const unsigned char directive_T0[] = { - 11, 25, 14, 30, 14, 26, 23, 15, 9, 37, - 27, 32, 27, 1, 17, 27, 35, 13, 8, 22, - 8, 28, 7, -}; - -static const unsigned char directive_T1[] = { - 19, 20, 31, 17, 29, 2, 7, 12, 1, 31, - 11, 18, 11, 20, 10, 2, 15, 19, 4, 10, - 13, 36, 3, -}; - static const struct directive { const char *name; int code; Boolean skip_flag; /* execute even when skipped */ void (*func)(char *, int, int); } directives[] = { + /* DIRECTIVES-START-TAG */ { "elif", COND_ELIF, TRUE, Cond_If }, { "elifdef", COND_ELIFDEF, TRUE, Cond_If }, { "elifmake", COND_ELIFMAKE, TRUE, Cond_If }, @@ -301,6 +263,7 @@ static const struct directive { { "include", 0, FALSE, parse_include }, { "undef", 0, FALSE, parse_undef }, { "warning", 0, FALSE, parse_message }, + /* DIRECTIVES-END-TAG */ }; #define NDIRECTS (sizeof(directives) / sizeof(directives[0])) @@ -2331,31 +2294,6 @@ parse_endfor(char *line __unused, int code __unused, int lineno __unused) } /** - * directive_hash - */ -static int -directive_hash(const u_char *key, size_t len) -{ - unsigned f0, f1; - const u_char *kp = key; - - if (len < 2 || len > 9) - return (-1); - - for (f0 = f1 = 0; kp < key + len; ++kp) { - if (*kp < 97 || *kp > 119) - return (-1); - f0 += directive_T0[-97 + *kp]; - f1 += directive_T1[-97 + *kp]; - } - - f0 %= 38; - f1 %= 38; - - return (directive_g[f0] + directive_g[f1]) % 18; -} - -/** * parse_directive * Got a line starting with a '.'. Check if this is a directive * and parse it. |