1 /* $Id: mktable.c,v 1.16 2010/12/15 10:50:24 htrb Exp $ */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "myctype.h"
5 #include "config.h"
6 #include "hash.h"
7 #include "myctype.h"
8 #include "Str.h"
9 #include <gc.h>
10 
11 /* *INDENT-OFF* */
defhash(HashItem_ss *,int,hss_i)12 defhash(HashItem_ss *, int, hss_i)
13 /* *INDENT-ON* */
14 
15 #define keycomp(x,y) ((x)==(y))
16 
17 /* XXX: we assume sizeof(unsigned long) >= sizeof(void *) */
18 static unsigned long
19 hashfunc(HashItem_ss * x)
20 {
21     return (unsigned long)x;
22 }
23 
24 /* *INDENT-OFF* */
defhashfunc(HashItem_ss *,int,hss_i)25 defhashfunc(HashItem_ss *, int, hss_i)
26 /* *INDENT-ON* */
27 
28 int
29 main(int argc, char *argv[], char **envp)
30 {
31     FILE *f;
32     Hash_ss *hash;
33     HashItem_ss **hashitems, *hi;
34     int size, n, i, j;
35     Str s, name, fbase;
36     char *p;
37     Hash_hss_i *rhash;
38 
39     GC_INIT();
40     if (argc != 3) {
41 	fprintf(stderr, "usage: %s hashsize file.tab > file.c\n", argv[0]);
42 	exit(1);
43     }
44     size = atoi(argv[1]);
45     if (size <= 0) {
46 	fprintf(stderr, "hash size should be positive\n");
47 	exit(1);
48     }
49     if ((f = fopen(argv[2], "r")) == NULL) {
50 	fprintf(stderr, "Can't open %s\n", argv[2]);
51 	exit(1);
52     }
53     p = argv[2];
54     if (strrchr(p, '/') != NULL)
55 	p = strrchr(p, '/') + 1;
56     fbase = Strnew_charp(p);
57     if (strchr(fbase->ptr, '.'))
58 	while (Strlastchar(fbase) != '.')
59 	    Strshrink(fbase, 1);
60     Strshrink(fbase, 1);
61 
62     hash = newHash_ss(size);
63     printf("#include \"hash.h\"\n");
64     for (;;) {
65 	s = Strfgets(f);
66 	if (s->length == 0)
67 	    exit(0);
68 	Strremovetrailingspaces(s);
69 	if (Strcmp_charp(s, "%%") == 0)
70 	    break;
71 	puts(s->ptr);
72     }
73     n = 0;
74     for (;;) {
75 	s = Strfgets(f);
76 	if (s->length == 0)
77 	    break;
78 	Strremovefirstspaces(s);
79 	Strremovetrailingspaces(s);
80 	name = Strnew();
81 	for (p = s->ptr; *p; p++) {
82 	    if (IS_SPACE(*p))
83 		break;
84 	    Strcat_char(name, *p);
85 	}
86 	while (*p && IS_SPACE(*p))
87 	    p++;
88 	putHash_ss(hash, name->ptr, p);
89 	n++;
90     }
91     fclose(f);
92 
93     hashitems = (HashItem_ss **) GC_malloc(sizeof(HashItem_ss *) * n);
94     rhash = newHash_hss_i(n * 2);
95     j = 0;
96     for (i = 0; i < hash->size; i++) {
97 	for (hi = hash->tab[i]; hi != NULL; hi = hi->next) {
98 	    hashitems[j] = hi;
99 	    putHash_hss_i(rhash, hi, j);
100 	    j++;
101 	}
102     }
103     printf("static HashItem_si MyHashItem[] = {\n");
104     for (i = 0; i < j; i++) {
105 	printf("    /* %d */ {\"%s\", %s, ", i,
106 	       hashitems[i]->key, hashitems[i]->value);
107 	if (hashitems[i]->next == NULL) {
108 	    printf("NULL},\n");
109 	}
110 	else {
111 	    printf("&MyHashItem[%d]},\n",
112 		   getHash_hss_i(rhash, hashitems[i]->next, -1));
113 	}
114     }
115     printf("};\n\nstatic HashItem_si *MyHashItemTbl[] = {\n");
116 
117     for (i = 0; i < hash->size; i++) {
118 	if (hash->tab[i])
119 	    printf("    &MyHashItem[%d],\n",
120 		   getHash_hss_i(rhash, hash->tab[i], -1));
121 	else
122 	    printf("    NULL,\n");
123     }
124     printf("};\n\n");
125     printf("Hash_si %s = { %d, MyHashItemTbl };\n", fbase->ptr, hash->size);
126 
127     exit(0);
128 }
129