mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-12 09:58:36 +00:00
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)
This commit is contained in:
parent
61d596a8ff
commit
2274441da6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145612
@ -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
|
||||
|
66
usr.bin/make/directive_hash.c
Normal file
66
usr.bin/make/directive_hash.c
Normal file
@ -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;
|
||||
}
|
36
usr.bin/make/directive_hash.h
Normal file
36
usr.bin/make/directive_hash.h
Normal file
@ -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
|
@ -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]))
|
||||
|
||||
@ -2330,31 +2293,6 @@ parse_endfor(char *line __unused, int code __unused, int lineno __unused)
|
||||
Parse_Error(PARSE_FATAL, "for-less endfor");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user