chiark / gitweb /
rand/rand-x86ish.S: Hoist argument register allocation outside.
[catacomb] / math / genwheel.c
1 /* -*-c-*-
2  *
3  * Generate a prime-iteration wheel
4  *
5  * (c) 2007 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Catacomb.
11  *
12  * Catacomb is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * Catacomb is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with Catacomb; if not, write to the Free
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <ctype.h>
31 #include <errno.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include <mLib/darray.h>
37 #include <mLib/dstr.h>
38 #include <mLib/macros.h>
39 #include <mLib/mdwopt.h>
40 #include <mLib/quis.h>
41 #include <mLib/report.h>
42
43 /*----- Data structures ---------------------------------------------------*/
44
45 DA_DECL(uintv, unsigned int);
46
47 /*----- Main code ---------------------------------------------------------*/
48
49 static unsigned long gcd(unsigned long a, unsigned long b)
50 {
51   int t;
52   if (!a) return (b);
53   while (b) { t = a%b; a = b; b = t; }
54   return (a);
55 }
56
57 int main(int argc, char *argv[])
58 {
59   int np = 5;
60   const char *type = "unsigned char";
61   const char *source = "wheel.c";
62   const char *header = "wheel.h";
63   const char *name = "wheel";
64   const char *sym = 0;
65   const char *hdrbase;
66   unsigned long i, n;
67   unsigned long mod;
68   int o;
69   uintv v = DA_INIT;
70
71   ego(argv[0]);
72   for (;;) {
73     o = getopt(argc, argv, "n:c:h:s:t:i:");
74     if (o < 0)
75       break;
76     switch (o) {
77       case 'n':
78         np = atoi(optarg);
79         break;
80       case 's':
81         sym = optarg;
82         break;
83       case 'c':
84         source = optarg;
85         break;
86       case 'h':
87         header = optarg;
88         break;
89       case 't':
90         type = optarg;
91         break;
92       case 'i':
93         name = optarg;
94         break;
95       default:
96         pquis(stderr, "Usage: $ [-n nprimes] [-s source] [-h header]\n");
97         exit(EXIT_FAILURE);
98     }
99   }
100
101   if ((hdrbase = strrchr(header, '/')) == 0) hdrbase = header;
102   else hdrbase++;
103
104   for (mod = 1, i = 2, n = 0;
105        n < np;
106        i++) {
107     if (gcd(i, mod) == 1) {
108       mod *= i;
109       n++;
110     }
111   }
112
113   n = 1;
114   for (i = 2; i < mod; i++) {
115     if (gcd(mod, i) == 1) {
116       DA_PUSH(&v, i - n);
117       n = i;
118     }
119   }
120   DA_PUSH(&v, mod + 1 - n);
121
122   {
123     FILE *fp = fopen(header, "w");
124     dstr d = DSTR_INIT;
125     const char *q;
126     if (!fp)
127       die(EXIT_FAILURE, "couldn't write `%s': %s", header, strerror(errno));
128     if (!sym) {
129       for (q = header; *q; q++) {
130         int ch = (unsigned char)*q;
131         if (ISALNUM(ch))
132           ch = TOUPPER(ch);
133         else
134           ch = '_';
135         DPUTC(&d, ch);
136       }
137       DPUTZ(&d);
138       sym = d.buf;
139     }
140     fprintf(fp, "\
141 /* -*-c-*-\n\
142  *\n\
143  * Wheel for small prime iteration [generated]\n\
144  */\n\
145 \n\
146 #ifndef %s\n\
147 #define %s\n\
148 \n\
149 #define WHEELN %luu\n\
150 #define WHEELMOD %luu\n\
151 \n\
152 extern const %s %s[];\n\
153 \n\
154 #endif\n\
155 ",
156             sym, sym,
157             (unsigned long)DA_LEN(&v),
158             mod,
159             type, name);
160     dstr_destroy(&d);
161     if (fclose(fp) == EOF) {
162       remove(header);
163       die(EXIT_FAILURE, "error writing `%s': %s", header, strerror(errno));
164     }
165   }
166
167   {
168     FILE *fp = fopen(source, "w");
169     int i;
170     if (!fp)
171       die(EXIT_FAILURE, "couldn't write `%s': %s", source, strerror(errno));
172     fprintf(fp, "\
173 /* -*-c-*-\n\
174  *\n\
175  * Wheel for small prime iteration [generated]\n\
176  */\n\
177 \n\
178 #include \"%s\"\n\
179 \n\
180 const %s %s[] = {",
181             hdrbase, type, name);
182     for (i = 0; i < DA_LEN(&v); i++) {
183       if (i % 8 == 0)
184         fputs("\n  ", fp);
185       fprintf(fp, "%5u, ", DA(&v)[i]);
186     }
187     fputs("\n\
188 };\n\
189 ", fp);
190     if (fclose(fp) == EOF) {
191       remove(source);
192       die(EXIT_FAILURE, "error writing `%s': %s", source, strerror(errno));
193     }
194   }
195
196   return (0);
197 }
198
199 /*----- That's all, folks -------------------------------------------------*/