* [...]
*/
+#include <assert.h>
+#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
}
}
-int main(int argc, char *argv[])
+void bedstead (void)
{
-
- /* FIXME: output a complete rule file rather than a heap of
- * fragments requiring manual assembly */
-
- /* Bedbugs step 1: output smoothing rules as a Golly rule
- * table mapping from (0,1) to an expanded set of states that
- * we can hang icons from. (The smoothing algorithm requires
- * a 3x3 neighbourhood, which is fortuitous.) */
+ /* Output smoothing rules as a Golly rule table mapping from
+ * (0,1) to an expanded set of states that we can hang icons
+ * from. (The smoothing algorithm requires a 3x3 neighbourhood,
+ * which is fortuitous.) */
/* Index into small bitmap */
#define GETPIX(x,y) (!!(iter & 1u<<((y)*3+(x))))
/* Off states are 2..17 */
state = 2 + (bl | br<<1 | tr<<2 | tl<<3);
}
+ if (iter == 0) {
+ /* Special case: we don't want to try to
+ * flip all of infinite empty space between
+ * 0 and 2 every step (this has odd effects
+ * on Golly) */
+ assert(state == 2);
+ state = 0;
+ }
/* Output rule in Golly rule format
* (FIXME completely unoptimised) */
printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
GETPIX(x,y),U,UR,R,DR,D,DL,L,UL,state);
}
+}
- /* Bedbugs step 2: icons. In each size supported by Golly,
+void icons(void)
+{
+ /* Bedbugs icons. In each size supported by Golly,
* draw one icon per state, in the XPM format Golly wants.
- * This does not actually depend on step 1 at all.
+ * This does not actually depend on bedstead() at all.
* (FIXME: but it could. Some of the states we generate icons
* and rules for are not actually reachable. We could spot
* unused states above and avoid generating icons or rules for
}
}
}
- return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ while (!feof(stdin)) {
+ char l[100]; /* bleah */
+ if (!fgets(l, sizeof(l), stdin)) {
+ break;
+ }
+ if (strlen(l) == sizeof(l)-1) {
+ fprintf(stderr, "Long input line; possible truncation; I suck\n");
+ exit(1);
+ }
+ if (strlen(l) >= 2 && l[0] == '@' && l[1] == '@') {
+ size_t n = strcspn(l+2, "\n");
+ if (strncmp(l+2, "BEDSTEAD", n) == 0) {
+ bedstead();
+ } else if (strncmp(l+2, "ICONS", n) == 0) {
+ icons();
+ } else {
+ /* Bodily insert named file on stdout. */
+ FILE *f;
+ l[n+2]='\0';
+ if (!(f = fopen(l+2, "r"))) {
+ fprintf(stderr, "Couldn't open '%s': %s\n", l+2,
+ strerror(errno));
+ exit(1);
+ } else {
+ do {
+ char buf[2048]; /* also bleah */
+ size_t n = fread(buf, 1, sizeof(buf), f);
+ fwrite(buf, 1, n, stdout);
+ } while (!feof(f) && !ferror(f));
+ if (ferror(f)) {
+ fprintf(stderr, "Error reading '%s': %s\n", l+2,
+ strerror(errno));
+ exit(1);
+ }
+ fclose(f);
+ }
+ }
+ } else {
+ printf("%s", l);
+ }
+ }
+ return 0;
}