/* @(#) $Revision: 1.7 $ */ /* @(#) RCS control in //prime.corp/usr/local/src/cmd/prime/src/mkprimetbl.c */ /* * mkprimetbl - make a prime table * * usage: * mkprimetbl name < primelist * * name form name.c and name.h * primelist primes in decimal ASCII, one per line * (or pipe from the primes program) ignoring * primes < 5 and the last prime is used only * to set the value of NEXT_PRIME_DIFF * * This method works for primes < 436273291. All primes < 436273291 * differ by gaps <= 250 which can be represented in a single byte. * The next prime after 436273009 is 436273291 which represents a * gap of 282. */ /* * * Copyright (C) 1997 Landon Curt Noll, all rights reserved. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose is hereby granted, provided that * the above copyright, this permission notice, and the disclaimer * below appear in all of the following: * * * supporting documentation * * source copies * * source works derived from this source * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Landon Curt Noll /\oo/\ * * chongo@{toad,sgi}.com Share and Enjoy! */ #include #define MAXLINE 16 /* max differences per line */ extern int errno; /* last error */ char *program; /* our name */ main(argc, argv) int argc; /* arg count */ char *argv[]; /* the args */ { char *name; /* base file name */ char nextbuf[BUFSIZ+1]; /* input buffer */ char buf[BUFSIZ+1]; /* full filename and current buffer */ FILE *c; /* name.c file */ FILE *h; /* name.h file */ long prev; /* previous prime */ long this; /* this prime */ long next; /* next prime */ long cnt; /* entries in prime_diff */ long linecnt; /* numbre of entries for the given line */ /* * parse args */ program = argv[0]; if (argc != 2) { fprintf(stderr, "usage: %s name < primelist\n", program); exit(1); } name = argv[1]; if (strlen(name) >= BUFSIZ-1) { fprintf(stderr, "%s: name is too long\n", program); exit(2); } /* * setup the name.c file */ buf[BUFSIZ] = '\0'; sprintf(buf, "%s.c", name); c = fopen(buf, "w"); if (c == NULL) { fprintf(stderr, "%s: unable to open %s\n", program, buf); perror(program); exit(3); } fputs("/* DO NOT EDIT -- created by mkprimetbl */\n", c); fputc('\n', c); fprintf(c, "#include \"%s.h\"\n", name); fputc('\n', c); fputs("/*\n", c); fputs(" * odd prime difference table\n", c); fputs(" *\n", c); fputs(" * Starting with 3, the first table entry says how much to\n", c); fputs(" * add to it in order to reach the next prime\n", c); fputs(" *\n", c); fputs(" * The final entry is 1.\n", c); fputs(" */\n", c); fputs("unsigned char const prime_diff[PRIME_DIFF_CNT+1] = {", c); /* * read lines until we get a prime > 2 */ prev = 0; while (fgets(buf, BUFSIZ, stdin) != NULL) { /* convert to integer */ errno = 0; prev = strtol(buf, (char **)NULL, 0); if (errno != 0) { fprintf(stderr, "%s: bad strtol of <%s>\n", program, buf); perror(program); exit(4); } /* stop if value > 2 */ if (prev >= 3) { break; } } if (prev < 3) { fprintf(stderr, "%s: input must contain at least 2 primes > 2\n", program); exit(5); } /* * read the 'this' prime */ if (fgets(buf, BUFSIZ, stdin) == NULL) { fprintf(stderr, "%s: input must have at least 2 primes > 2\n", program); exit(6); } /* convert to integer */ errno = 0; this = strtol(buf, (char **)NULL, 0); if (errno != 0) { fprintf(stderr, "%s: bad strtol of <%s>\n", program, buf); perror(program); exit(7); } /* * read the primes from stdin */ cnt = 0; linecnt = MAXLINE; /* read the next prime -- but don't use it yet */ while (fgets(buf, BUFSIZ, stdin) != NULL) { /* object if even */ if ((this&0x1) == 0) { fprintf(stderr, "%s: input value %d >=5 is even, cannot be prime\n", program, this); exit(8); } /* object if < prev+2 value */ if (this < prev+2) { fprintf(stderr, "%s: input value %d < prev value %d+2\n", program, this, prev); exit(9); } /* firewall */ if (this-prev >= 256) { /* cannot represent this gap */ break; } /* print this difference */ if (linecnt >= MAXLINE) { fprintf(c, "\n %3d,", this-prev); linecnt = 1; } else { fprintf(c, "%3d,", this-prev); ++linecnt; } ++cnt; /* prep for the next value */ errno = 0; next = strtol(buf, (char **)NULL, 0); if (errno != 0) { fprintf(stderr, "%s: bad strtol of <%s>\n", program, buf); perror(program); exit(10); } prev = this; this = next; } /* * finish the name.c file */ fputs(" 1\n", c); fputs("};", c); fputc('\n', c); fprintf(c, "/* difference for odd primes <= %d */\n", prev); fputs("/* table sentinal value is 1 */\n", c); fprintf(c, "/* first prime beyond table is %d */\n", this); fclose(c); /* * form the name.h file */ sprintf(buf, "%s.h", name); h = fopen(buf, "w"); if (h == NULL) { fprintf(stderr, "%s: unable to open %s\n", program, buf); perror(program); exit(11); } fputs("/* DO NOT EDIT -- created by mkprimetbl */\n", h); fputc('\n', h); fprintf(h, "/* difference for odd primes <= %d */\n", prev); fputs("/* table sentinal value is 1 */\n", h); fprintf(h, "/* first prime beyond table is %d */\n", this); fputc('\n', h); fprintf(h, "#define PRIME_DIFF_CNT %d\n", cnt); fprintf(h, "#define LAST_PRIME_DIFF %d\n", prev); fprintf(h, "#define NEXT_PRIME_DIFF %d\n", this); fputc('\n', h); fputs("#if !defined(NO_EXTERNS)\n", h); fputs("extern unsigned char const prime_diff[];\n", h); fputs("#endif /* !NO_EXTERNS */\n", h); fclose(h); /* * all done */ exit(0); }