56e388e80868331c7abefc6674584b63a594180f
[u/mdw/catacomb] / genprimes.c
1 /* -*-c-*-
2 *
3 * $Id: genprimes.c,v 1.5 2004/04/01 12:50:09 mdw Exp $
4 *
5 * Generate prime number table
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: genprimes.c,v $
33 * Revision 1.5 2004/04/01 12:50:09 mdw
34 * Add cyclic group abstraction, with test code. Separate off exponentation
35 * functions for better static linking. Fix a buttload of bugs on the way.
36 * Generally ensure that negative exponents do inversion correctly. Add
37 * table of standard prime-field subgroups. (Binary field subgroups are
38 * currently unimplemented but easy to add if anyone ever finds a good one.)
39 *
40 * Revision 1.4 2001/03/04 13:08:10 mdw
41 * Use @DA_LAST@ to determine @MAXPRIME@, now that it exists.
42 *
43 * Revision 1.3 2000/08/15 21:41:58 mdw
44 * Create a new type for the small primes table elements.
45 *
46 * Revision 1.2 1999/12/22 15:48:39 mdw
47 * Rename output file. Make output constants unsigned.
48 *
49 * Revision 1.1 1999/11/19 13:19:37 mdw
50 * Generate small primes table.
51 *
52 */
53
54 /*----- Header files ------------------------------------------------------*/
55
56 #include <ctype.h>
57 #include <errno.h>
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61
62 #include <mLib/darray.h>
63 #include <mLib/dstr.h>
64 #include <mLib/mdwopt.h>
65 #include <mLib/quis.h>
66 #include <mLib/report.h>
67
68 /*----- Data structures ---------------------------------------------------*/
69
70 DA_DECL(intv, int);
71
72 /*----- Main code ---------------------------------------------------------*/
73
74 int main(int argc, char *argv[])
75 {
76 int p_max = 0, p_n = 0;
77 char *type = "unsigned int";
78 char *header = "primetab.h";
79 char *source = "primetab.c";
80 char *name = "primetab";
81 char *sym = 0;
82 intv p = DA_INIT;
83 int i;
84
85 ego(argv[0]);
86
87 for (;;) {
88 int i = getopt(argc, argv, "h:c:i:n:m:t:s:");
89 if (i < 0)
90 break;
91 switch (i) {
92 case 'h':
93 header = optarg;
94 break;
95 case 'c':
96 source = optarg;
97 break;
98 case 'i':
99 name = optarg;
100 break;
101 case 'n':
102 p_max = 0;
103 p_n = atoi(optarg);
104 break;
105 case 'm':
106 p_n = 0;
107 p_max = atoi(optarg);
108 break;
109 case 't':
110 type = optarg;
111 break;
112 case 's':
113 sym = optarg;
114 break;
115 default:
116 pquis(stderr, "Usage: $ [-n nprimes] [-m maxprime] [-t type]\n");
117 exit(EXIT_FAILURE);
118 }
119 }
120
121 if (!p_max && !p_n)
122 die(EXIT_FAILURE, "bad arguments to `-n' or `-m'");
123
124 if (p_n || p_max >= 2)
125 DA_PUSH(&p, 2);
126 for (i = 3; (!p_max && !p_n) ||
127 (p_n && DA_LEN(&p) < p_n) ||
128 (p_max && i <= p_max);
129 i += 2) {
130 int j;
131 for (j = 0; j < DA_LEN(&p); j++) {
132 if (i % DA(&p)[j] == 0)
133 goto composite;
134 }
135 DA_PUSH(&p, i);
136 composite:;
137 }
138
139 {
140 FILE *fp = fopen(header, "w");
141 dstr d = DSTR_INIT;
142 char *q;
143 if (!fp)
144 die(EXIT_FAILURE, "couldn't write `%s': %s", header, strerror(errno));
145 if (!sym) {
146 for (q = header; *q; q++) {
147 int ch = (unsigned char)*q;
148 if (isalnum(ch))
149 ch = toupper(ch);
150 else
151 ch = '_';
152 DPUTC(&d, ch);
153 }
154 DPUTZ(&d);
155 sym = d.buf;
156 }
157 fprintf(fp, "\
158 /* -*-c-*-\n\
159 *\n\
160 * Table of small prime numbers [generated]\n\
161 */\n\
162 \n\
163 #ifndef %s\n\
164 #define %s\n\
165 \n\
166 #define NPRIME %luu\n\
167 #define MAXPRIME %uu\n\
168 \n\
169 typedef %s smallprime;\n\
170 extern smallprime %s[];\n\
171 \n\
172 #endif\n\
173 ",
174 sym, sym,
175 (unsigned long)DA_LEN(&p),
176 DA_LAST(&p),
177 type, name);
178 dstr_destroy(&d);
179 if (fclose(fp) == EOF) {
180 remove(header);
181 die(EXIT_FAILURE, "error writing `%s': %s", header, strerror(errno));
182 }
183 }
184
185 {
186 FILE *fp = fopen(source, "w");
187 int i;
188 if (!fp)
189 die(EXIT_FAILURE, "couldn't write `%s': %s", source, strerror(errno));
190 fprintf(fp, "\
191 /* -*-c-*-\n\
192 *\n\
193 * Table of small prime numbers [generated]\n\
194 */\n\
195 \n\
196 #include \"%s\"\n\
197 \n\
198 %s %s[] = {",
199 header, type, name);
200 for (i = 0; i < DA_LEN(&p); i++) {
201 if (i % 8 == 0)
202 fputs("\n ", fp);
203 fprintf(fp, "%5i, ", DA(&p)[i]);
204 }
205 fputs("\n\
206 };\n\
207 ", fp);
208 if (fclose(fp) == EOF) {
209 remove(source);
210 die(EXIT_FAILURE, "error writing `%s': %s", source, strerror(errno));
211 }
212 }
213
214 return (0);
215 }
216
217 /*----- That's all, folks -------------------------------------------------*/