X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fmake_hash.c;h=d5f941825a907f85d9d015f554c2944d9b5efc3d;hp=692113b597dd272e6eb25689f605200f006bc39b;hb=d76c9bfec68e0efa6e1b8e95b32b66caf25cfc12;hpb=3e7e5f8b5c4e8e499f682a1c414c576c16d47532 diff --git a/ncurses/tinfo/make_hash.c b/ncurses/tinfo/make_hash.c index 692113b5..d5f94182 100644 --- a/ncurses/tinfo/make_hash.c +++ b/ncurses/tinfo/make_hash.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2013,2017 Free Software Foundation, Inc. * + * Copyright (c) 1998-2018,2019 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -34,7 +34,6 @@ /* * make_hash.c --- build-time program for constructing comp_captab.c - * */ #include @@ -44,14 +43,14 @@ #include -MODULE_ID("$Id: make_hash.c,v 1.14 2017/06/23 23:53:13 tom Exp $") +MODULE_ID("$Id: make_hash.c,v 1.28 2019/07/27 23:06:54 tom Exp $") /* * _nc_make_hash_table() * * Takes the entries in table[] and hashes them into hash_table[] - * by name. There are CAPTABSIZE entries in table[] and HASHTABSIZE - * slots in hash_table[]. + * by name. There are CAPTABSIZE entries in the predefined table[] + * and HASHTABSIZE slots in hash_table[]. * */ @@ -59,6 +58,14 @@ MODULE_ID("$Id: make_hash.c,v 1.14 2017/06/23 23:53:13 tom Exp $") #define MODULE_ID(id) /*nothing */ #include +#define L_PAREN "(" +#define R_PAREN ")" +#define L_BRACE "{" +#define R_BRACE "}" + +static const char *typenames[] = +{"BOOLEAN", "NUMBER", "STRING"}; + static void failed(const char *s) { @@ -101,28 +108,29 @@ hash_function(const char *string) } static void -_nc_make_hash_table(struct name_table_entry *table, - HashValue * hash_table) +_nc_make_hash_table(struct user_table_entry *table, + HashValue * hash_table, + unsigned tablesize) { - short i; + unsigned i; int hashvalue; int collisions = 0; for (i = 0; i < HASHTABSIZE; i++) { hash_table[i] = -1; } - for (i = 0; i < CAPTABSIZE; i++) { - hashvalue = hash_function(table[i].nte_name); + for (i = 0; i < tablesize; i++) { + hashvalue = hash_function(table[i].ute_name); if (hash_table[hashvalue] >= 0) collisions++; if (hash_table[hashvalue] != 0) - table[i].nte_link = hash_table[hashvalue]; - hash_table[hashvalue] = i; + table[i].ute_link = hash_table[hashvalue]; + hash_table[hashvalue] = (HashValue) i; } - printf("/* %d collisions out of %d entries */\n", collisions, CAPTABSIZE); + printf("/* %d collisions out of %d entries */\n", collisions, tablesize); } /* @@ -156,10 +164,20 @@ parse_columns(char *buffer) int col = 0; - if (list == 0 && (list = typeCalloc(char *, (MAX_COLUMNS + 1))) == 0) - return (0); +#if NO_LEAKS + if (buffer == 0) { + free(list); + list = 0; + return 0; + } +#endif if (*buffer != '#') { + if (list == 0) { + list = typeCalloc(char *, (MAX_COLUMNS + 1)); + if (list == 0) + return (0); + } while (*buffer != '\0') { char *s; for (s = buffer; (*s != '\0') && !isspace(UChar(*s)); s++) @@ -188,21 +206,58 @@ parse_columns(char *buffer) return col ? list : 0; } +#define SetType(n,t) \ + if (is_user) \ + name_table[n].ute_type |= (int)(1 << (t)); \ + else \ + name_table[n].ute_type = (t) + +#define GetType(n) \ + (is_user \ + ? get_type(name_table[n].ute_type) \ + : typenames[name_table[n].ute_type]) + +static char * +get_type(int type_mask) +{ + static char result[80]; + unsigned n; + _nc_STRCPY(result, L_PAREN, sizeof(result)); + for (n = 0; n < 3; ++n) { + if ((1 << n) & type_mask) { + size_t want = 5 + strlen(typenames[n]); + if (want > sizeof(result)) { + fprintf(stderr, "Buffer is not large enough for %s + %s\n", + result, typenames[n]); + exit(EXIT_FAILURE); + } + if (result[1]) + _nc_STRCAT(result, "|", sizeof(result)); + _nc_STRCAT(result, "1<<", sizeof(result)); + _nc_STRCAT(result, typenames[n], sizeof(result)); + } + } + _nc_STRCAT(result, R_PAREN, sizeof(result)); + return result; +} + int main(int argc, char **argv) { - struct name_table_entry *name_table = typeCalloc(struct - name_table_entry, CAPTABSIZE); + unsigned tablesize = CAPTABSIZE; + struct user_table_entry *name_table = typeCalloc(struct + user_table_entry, tablesize); HashValue *hash_table = typeCalloc(HashValue, HASHTABSIZE); const char *root_name = ""; int column = 0; int bigstring = 0; - int n; + unsigned n; + unsigned nn; + unsigned tableused = 0; + bool is_user; + const char *table_name; char buffer[BUFSIZ]; - static const char *typenames[] = - {"BOOLEAN", "NUMBER", "STRING"}; - short BoolCount = 0; short NumCount = 0; short StrCount = 0; @@ -220,42 +275,80 @@ main(int argc, char **argv) fprintf(stderr, "usage: make_hash column root_name bigstring\n"); exit(EXIT_FAILURE); } + is_user = (*root_name == 'u'); + table_name = (is_user ? "user" : "name"); /* * Read the table into our arrays. */ - for (n = 0; (n < CAPTABSIZE) && fgets(buffer, BUFSIZ, stdin);) { - char **list, *nlp = strchr(buffer, '\n'); + for (n = 0; (n < tablesize) && fgets(buffer, BUFSIZ, stdin);) { + char **list; + char *nlp = strchr(buffer, '\n'); if (nlp) *nlp = '\0'; + else + buffer[sizeof(buffer) - 2] = '\0'; list = parse_columns(buffer); if (list == 0) /* blank or comment */ continue; - if (column > count_columns(list)) { + if (is_user) { + if (strcmp(list[0], "userdef")) + continue; + } else if (!strcmp(list[0], "userdef")) { + continue; + } + if (column < 0 || column > count_columns(list)) { fprintf(stderr, "expected %d columns, have %d:\n%s\n", column, count_columns(list), buffer); exit(EXIT_FAILURE); } - name_table[n].nte_link = -1; /* end-of-hash */ - name_table[n].nte_name = strmalloc(list[column]); + nn = tableused; + if (is_user) { + unsigned j; + for (j = 0; j < tableused; ++j) { + if (!strcmp(list[column], name_table[j].ute_name)) { + nn = j; + break; + } + } + } + if (nn == tableused) { + name_table[nn].ute_link = -1; /* end-of-hash */ + name_table[nn].ute_name = strmalloc(list[column]); + ++tableused; + } + if (!strcmp(list[2], "bool")) { - name_table[n].nte_type = BOOLEAN; - name_table[n].nte_index = BoolCount++; + SetType(nn, BOOLEAN); + name_table[nn].ute_index = BoolCount++; } else if (!strcmp(list[2], "num")) { - name_table[n].nte_type = NUMBER; - name_table[n].nte_index = NumCount++; + SetType(nn, NUMBER); + name_table[nn].ute_index = NumCount++; } else if (!strcmp(list[2], "str")) { - name_table[n].nte_type = STRING; - name_table[n].nte_index = StrCount++; + SetType(nn, STRING); + name_table[nn].ute_index = StrCount++; + if (is_user) { + if (*list[3] != '-') { + unsigned j; + name_table[nn].ute_argc = (unsigned) strlen(list[3]); + for (j = 0; j < name_table[nn].ute_argc; ++j) { + if (list[3][j] == 's') { + name_table[nn].ute_args |= (1U << j); + } + } + } + } } else { fprintf(stderr, "Unknown type: %s\n", list[2]); exit(EXIT_FAILURE); } n++; } - _nc_make_hash_table(name_table, hash_table); + if (tablesize > tableused) + tablesize = tableused; + _nc_make_hash_table(name_table, hash_table, tablesize); /* * Write the compiled tables to standard output @@ -265,72 +358,87 @@ main(int argc, char **argv) int nxt; printf("static const char %s_names_text[] = \\\n", root_name); - for (n = 0; n < CAPTABSIZE; n++) { - nxt = (int) strlen(name_table[n].nte_name) + 5; + for (n = 0; n < tablesize; n++) { + nxt = (int) strlen(name_table[n].ute_name) + 5; if (nxt + len > 72) { printf("\\\n"); len = 0; } - printf("\"%s\\0\" ", name_table[n].nte_name); + printf("\"%s\\0\" ", name_table[n].ute_name); len += nxt; } printf(";\n\n"); len = 0; - printf("static name_table_data const %s_names_data[] =\n", + printf("static %s_table_data const %s_names_data[] =\n", + table_name, root_name); - printf("{\n"); - for (n = 0; n < CAPTABSIZE; n++) { - printf("\t{ %15d,\t%10s,\t%3d, %3d }%c\n", - len, - typenames[name_table[n].nte_type], - name_table[n].nte_index, - name_table[n].nte_link, - n < CAPTABSIZE - 1 ? ',' : ' '); - len += (int) strlen(name_table[n].nte_name) + 1; + printf("%s\n", L_BRACE); + for (n = 0; n < tablesize; n++) { + printf("\t%s %15d,\t%10s,", L_BRACE, len, GetType(n)); + if (is_user) + printf("\t%d,%d,", + name_table[n].ute_argc, + name_table[n].ute_args); + printf("\t%3d, %3d %s%c\n", + name_table[n].ute_index, + name_table[n].ute_link, + R_BRACE, + n < tablesize - 1 ? ',' : ' '); + len += (int) strlen(name_table[n].ute_name) + 1; } - printf("};\n\n"); - printf("static struct name_table_entry *_nc_%s_table = 0;\n\n", root_name); + printf("%s;\n\n", R_BRACE); + printf("static struct %s_table_entry *_nc_%s_table = 0;\n\n", + table_name, + root_name); } else { - printf("static struct name_table_entry const _nc_%s_table[] =\n", + printf("static struct %s_table_entry const _nc_%s_table[] =\n", + table_name, root_name); - printf("{\n"); - for (n = 0; n < CAPTABSIZE; n++) { + printf("%s\n", L_BRACE); + for (n = 0; n < tablesize; n++) { _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) "\"%s\"", - name_table[n].nte_name); - printf("\t{ %15s,\t%10s,\t%3d, %3d }%c\n", - buffer, - typenames[name_table[n].nte_type], - name_table[n].nte_index, - name_table[n].nte_link, - n < CAPTABSIZE - 1 ? ',' : ' '); + name_table[n].ute_name); + printf("\t%s %15s,\t%10s,", L_BRACE, buffer, GetType(n)); + if (is_user) + printf("\t%d,%d,", + name_table[n].ute_argc, + name_table[n].ute_args); + printf("\t%3d, %3d %s%c\n", + name_table[n].ute_index, + name_table[n].ute_link, + R_BRACE, + n < tablesize - 1 ? ',' : ' '); } - printf("};\n\n"); + printf("%s;\n\n", R_BRACE); } printf("static const HashValue _nc_%s_hash_table[%d] =\n", root_name, HASHTABSIZE + 1); - printf("{\n"); + printf("%s\n", L_BRACE); for (n = 0; n < HASHTABSIZE; n++) { printf("\t%3d,\n", hash_table[n]); } printf("\t0\t/* base-of-table */\n"); - printf("};\n\n"); - - printf("#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n", - BoolCount, NumCount, StrCount); - printf("#error\t--> term.h and comp_captab.c disagree about the <--\n"); - printf("#error\t--> numbers of booleans, numbers and/or strings <--\n"); - printf("#endif\n\n"); + printf("%s;\n\n", R_BRACE); + + if (!is_user) { + printf("#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n", + BoolCount, NumCount, StrCount); + printf("#error\t--> term.h and comp_captab.c disagree about the <--\n"); + printf("#error\t--> numbers of booleans, numbers and/or strings <--\n"); + printf("#endif\n\n"); + } free(hash_table); #if NO_LEAKS - for (n = 0; (n < CAPTABSIZE); ++n) { - free((char *) name_table[n].nte_name); + for (n = 0; (n < tablesize); ++n) { + free((void *) name_table[n].ute_name); } free(name_table); + parse_columns(0); #endif return EXIT_SUCCESS; }