1#!/bin/sh
2##############################################################################
3# Copyright 2019,2020 Thomas E. Dickey                                       #
4# Copyright 2007-2010,2011 Free Software Foundation, Inc.                    #
5#                                                                            #
6# Permission is hereby granted, free of charge, to any person obtaining a    #
7# copy of this software and associated documentation files (the "Software"), #
8# to deal in the Software without restriction, including without limitation  #
9# the rights to use, copy, modify, merge, publish, distribute, distribute    #
10# with modifications, sublicense, and/or sell copies of the Software, and to #
11# permit persons to whom the Software is furnished to do so, subject to the  #
12# following conditions:                                                      #
13#                                                                            #
14# The above copyright notice and this permission notice shall be included in #
15# all copies or substantial portions of the Software.                        #
16#                                                                            #
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
20# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
23# DEALINGS IN THE SOFTWARE.                                                  #
24#                                                                            #
25# Except as contained in this notice, the name(s) of the above copyright     #
26# holders shall not be used in advertising or otherwise to promote the sale, #
27# use or other dealings in this Software without prior written               #
28# authorization.                                                             #
29##############################################################################
30# $Id: MKcaptab.sh,v 1.19 2020/02/02 23:34:34 tom Exp $
31
32if test $# != 0
33then
34	AWK="$1"; shift 1
35else
36	AWK=awk
37fi
38
39if test $# != 0
40then
41	OPT1="$1"; shift 1
42else
43	OPT1="-0"
44fi
45
46if test $# != 0
47then
48	OPT2="$1"; shift 1
49else
50	OPT2="tinfo/MKcaptab.awk"
51fi
52
53cat <<EOF
54/*
55 * generated by $0
56 */
57
58EOF
59
60cat <<'EOF'
61/*
62 *	comp_captab.c -- The names of the capabilities indexed via a hash
63 *		         table for the compiler.
64 *
65 */
66
67#include <curses.priv.h>
68#include <tic.h>
69#include <hashsize.h>
70
71/* *INDENT-OFF* */
72EOF
73
74cat "$@" |./make_hash 1 info $OPT1
75cat "$@" |./make_hash 3 cap  $OPT1
76
77cat "$@" |$AWK -f $OPT2 bigstrings=$OPT1 tablename=capalias
78
79cat "$@" |$AWK -f $OPT2 bigstrings=$OPT1 tablename=infoalias
80
81cat <<EOF
82/* *INDENT-ON* */
83
84#if $OPT1
85static void
86next_string(const char *strings, unsigned *offset)
87{
88    *offset += (unsigned) strlen(strings + *offset) + 1;
89}
90
91static const struct name_table_entry *
92_nc_build_names(struct name_table_entry **actual,
93		const name_table_data * source,
94		const char *strings)
95{
96    if (*actual == 0) {
97	*actual = typeCalloc(struct name_table_entry, CAPTABSIZE);
98	if (*actual != 0) {
99	    unsigned n;
100	    unsigned len = 0;
101	    for (n = 0; n < CAPTABSIZE; ++n) {
102		(*actual)[n].nte_name = strings + len;
103		(*actual)[n].nte_type = source[n].nte_type;
104		(*actual)[n].nte_index = source[n].nte_index;
105		(*actual)[n].nte_link = source[n].nte_link;
106		next_string(strings, &len);
107	    }
108	}
109    }
110    return *actual;
111}
112
113#define add_alias(field) \\
114	if (source[n].field >= 0) { \\
115		(*actual)[n].field = strings + source[n].field; \\
116	}
117
118static const struct alias *
119_nc_build_alias(struct alias **actual,
120		const alias_table_data * source,
121		const char *strings,
122		size_t tablesize)
123{
124    if (*actual == 0) {
125	*actual = typeCalloc(struct alias, tablesize + 1);
126	if (*actual != 0) {
127	    size_t n;
128	    for (n = 0; n < tablesize; ++n) {
129		add_alias(from);
130		add_alias(to);
131		add_alias(source);
132	    }
133	}
134    }
135    return *actual;
136}
137
138#define build_names(root) _nc_build_names(&_nc_##root##_table, \\
139					  root##_names_data, \\
140					  root##_names_text)
141#define build_alias(root) _nc_build_alias(&_nc_##root##alias_table, \\
142					  root##alias_data, \\
143					  root##alias_text, \\
144					  SIZEOF(root##alias_data))
145#else
146#define build_names(root) _nc_ ## root ## _table
147#define build_alias(root) _nc_ ## root ## alias_table
148#endif
149
150NCURSES_EXPORT(const struct name_table_entry *)
151_nc_get_table(bool termcap)
152{
153    return termcap ? build_names(cap) : build_names(info);
154}
155
156/* entrypoint used by tack 1.07 */
157NCURSES_EXPORT(const HashValue *)
158_nc_get_hash_table(bool termcap)
159{
160    return termcap ? _nc_cap_hash_table : _nc_info_hash_table;
161}
162
163NCURSES_EXPORT(const struct alias *)
164_nc_get_alias_table(bool termcap)
165{
166    return termcap ? build_alias(cap) : build_alias(info);
167}
168
169static HashValue
170info_hash(const char *string)
171{
172    long sum = 0;
173
174    DEBUG(9, ("hashing %s", string));
175    while (*string) {
176	sum += (long) (UChar(*string) + (UChar(*(string + 1)) << 8));
177	string++;
178    }
179
180    DEBUG(9, ("sum is %ld", sum));
181    return (HashValue) (sum % HASHTABSIZE);
182}
183
184#define TCAP_LEN 2		/* only 1- or 2-character names are used */
185
186static HashValue
187tcap_hash(const char *string)
188{
189    char temp[TCAP_LEN + 1];
190    int limit = 0;
191
192    while (*string) {
193	temp[limit++] = *string++;
194	if (limit >= TCAP_LEN)
195	    break;
196    }
197    temp[limit] = '\0';
198    return info_hash(temp);
199}
200
201static int
202compare_tcap_names(const char *a, const char *b)
203{
204    return !strncmp(a, b, (size_t) TCAP_LEN);
205}
206
207static int
208compare_info_names(const char *a, const char *b)
209{
210    return !strcmp(a, b);
211}
212
213static const HashData hash_data[2] =
214{
215    {HASHTABSIZE, _nc_info_hash_table, info_hash, compare_info_names},
216    {HASHTABSIZE, _nc_cap_hash_table, tcap_hash, compare_tcap_names}
217};
218
219NCURSES_EXPORT(const HashData *)
220_nc_get_hash_info(bool termcap)
221{
222    return &hash_data[(termcap != FALSE)];
223}
224
225#if NO_LEAKS
226NCURSES_EXPORT(void)
227_nc_comp_captab_leaks(void)
228{
229#if $OPT1
230    FreeIfNeeded(_nc_cap_table);
231    FreeIfNeeded(_nc_info_table);
232    FreeIfNeeded(_nc_capalias_table);
233    FreeIfNeeded(_nc_infoalias_table);
234#endif
235}
236#endif /* NO_LEAKS */
237EOF
238