Okay, I've been staring at this for hours now, and I've no idea what's
going wrong. I'm pretty sure I'm doing everything right --- everything
here is pretty straightforward C89, and the algorithms are dead simple,
but it simply hangs solid using all the CPU about half-way through. It's
not just slow --- I've let it run for a while and nothing whatsoever
happens. Any suggestions?
(I should probably get my CPU fan looked at, too. It got awfully hot
during that long run. I'm sure I can smell something burning...)
#include <stdio.h>
#include <stdlib.h>
/* WARNING: Do not run this program in a virtualised or emulated
* environment! It's probably wise to turn your virtual memory off, too.
* Real hardware only! Debuggers are RIGHT OUT. YOU HAVE BEEN WARNED. */
/* Structures used to define our layout. Note the careful use of
* volatile; we don't want the compiler optimising away part of the
* invocation. */
typedef struct
{
const char name[7]; /* sigil at focus */
volatile int target; /* summoning point */
volatile char invocation; /* current char of invocation */
} focus_t;
typedef struct node
{
const char name[4]; /* name of node */
focus_t* center; /* points to the evocation focus */
struct node* cw; /* clockwise binding ring */
struct node* ccw; /* counterclockwise binding ring */
struct node* star; /* next node of star */
const char* linkname; /* name of star linkage */
volatile char chant; /* 'chant' point */
} node_t;
/* The pentacle nodes are circularly linked in both directions to form
* a binding perimeter. In addition, they are singly linked to form a
* classic 'daemon trap' five-pointed star. Each node points towards the
* evocation focus (but not the other way around!) to enforce the
* geometry we want. The design is based heavily on the Pentagram of
* Solomon. */
focus_t focus;
node_t node1, node2, node3, node4, node5;
node_t* nodes[5] = { &node1, &node2, &node3, &node4, &node5 };
node_t node1 = { "TE", &focus, &node2, &node5, &node3, "BELLONY" };
node_t node2 = { "TRA", &focus, &node3, &node1, &node4, "HALLIY" };
node_t node3 = { "GRAM", &focus, &node4, &node2, &node5, "HALLIZA" };
node_t node4 = { "MA", &focus, &node5, &node3, &node1, "ABDIA" };
node_t node5 = { "TON", &focus, &node1, &node4, &node2, "BALLATON" };
focus_t center = { "SOLUZEN", 0 };
/* Name of spirit to summon --- rot13'd for safety.
* (#65 from Crowley's translation of SHEMHAMPHORASH.) */
const char spiritname[] = "NAQERNYCUHF";
int unrot13(int c) { return 'A' + (((c - 'A') + 13) % 26); }
/* The legend around the outside of the circle. Again, this is from the
* Magical Circle of King Solomon. FIXME: should be in Hebrew character
* set. Or possibly Enochian, but Unicode doesn't have that. */
const char chant[] =
"Ehyeh Kether Metatron Chaioth Ha-Qadehs Rashith Ha-Galgalim\n"
"Iah Chokmah Ratziel Auphanim Masloth\n"
"Iehovah Eolhim, Binah Tzadquiel Aralim Shabbathai\n"
"El Chesed Tzadquiel Chaschmalim Tzedeq\n"
"Elohim Gibor Geburah Kamael Seraphim Madim\n"
"Iehovah Eloah Va-Daath Tiphereth Raphael Malakim Shemesh\n"
"Iehovah Tzabaoth Netzach Haniel Elohim Nogah\n"
"Elohim Tzabaoth Hod Michael Beni Elohim Kokav\n"
"Shaddai El Chai Iesod Gabriel Cherubim Levanah\n";
/* Place the next character of the 'chant' (the perimeter inscription)
* on the pentacle. */
static void updatechant()
{
static int chantnode = 0;
static const char* chantp = chant;
int c = *chantp++;
if (c == '\0')
{
chantp = chant;
c = *chantp++;
}
nodes[chantnode]->chant = c;
chantnode = (chantnode + 1) % 5;
}
int main(int argc, const char* argv[])
{
int i;
/* Actually perform the invocation: continually cycle the spirit's
* name into the evocation focus (while maintaining our pentacle
* integrity!) until something shows up in the target of the
* evocation focus. */
do
{
for (i = 0; i < sizeof(spiritname)-1; i++)
{
focus.invocation = rot13(spiritname[i]);
updatechant();
}
}
while (focus.target == 0);
/* Our spirit's arrived! Dismiss it immediately by using a null
* invocation. Keep going until the evocation focus remains empty.
* FIXME: a particularly mean spirit might find a way to hide. Until
* we can sort this out, only summon relatively benign ones. This is
* probably safe anyway, as when the process terminates the spirit's
* address space will be nuked. */
do
{
focus.target = 0;
for (i = 0; i < 1000; i++)
{
focus.invocation = 0;
updatechant();
}
}
while (focus.target != 0);
/* Nothing's happened for a while --- the spirit's come and gone. It
* should now be safe to exit. */
return 0;
}
--
┌─── dg@cowlark.com ─────
http://www.cowlark.com
─────
│ "I have always wished for my computer to be as easy to use as my
│ telephone; my wish has come true because I can no longer figure out
│ how to use my telephone." --- Bjarne Stroustrup
--
comp.lang.c.moderated - moderation address: clcm@[EMAIL PROTECTED]
-- you must
have an appropriate newsgroups line in your header for your mail to be
seen,
or the newsgroup name in square brackets in the subject line. Sorry.


|