More delicious source code
authorMartin Read <mpread@chiark.greenend.org.uk>
Wed, 6 Apr 2011 18:15:29 +0000 (19:15 +0100)
committerMartin Read <mpread@chiark.greenend.org.uk>
Wed, 6 Apr 2011 18:15:29 +0000 (19:15 +0100)
src/Appcfg.cc [new file with mode: 0644]
src/namegen.cc [new file with mode: 0644]
src/ordinaldate.cc [new file with mode: 0644]

diff --git a/src/Appcfg.cc b/src/Appcfg.cc
new file mode 100644 (file)
index 0000000..b74f0fb
--- /dev/null
@@ -0,0 +1,137 @@
+// Appcfg.cc
+//
+// Copyright 2011 Martin Read. All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the author nor the names of any other contributors
+//    may be used to endorse or promote products derived from this software
+//    without their specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#include <stdint.h>
+#include <string.h>
+#include <libmormegil/Appcfg.hh>
+
+bool libmormegil::Appcfg::register_bool(const std::string& name, bool defval)
+{
+    if (data.find(name) != data.end())
+    {
+        return false;
+    }
+    libmormegil::Appcfg::Entry e;
+    e.bval = defval;
+    e.t = Appcfg_boolean;
+    data[name] = e;
+    return true;
+}
+
+bool libmormegil::Appcfg::register_integer(const std::string& name, int64_t defval)
+{
+    if (data.find(name) != data.end())
+    {
+        return false;
+    }
+    libmormegil::Appcfg::Entry e;
+    e.ival = defval;
+    e.t = Appcfg_integer;
+    data[name] = e;
+}
+
+bool libmormegil::Appcfg::register_string(const std::string& name, const std::string& defval)
+{
+    if (data.find(name) != data.end())
+    {
+        return false;
+    }
+    libmormegil::Appcfg::Entry e;
+    e.sval = defval;
+    e.t = Appcfg_string;
+    data[name] = e;
+}
+
+bool libmormegil::Appcfg::get(const std::string& name, int64_t& val)
+{
+    data_iterator iter = data.find(name);
+    if ((iter != data.end()) && (iter->second.t == Appcfg_integer))
+    {
+        val = iter->second.ival;
+        return true;
+    }
+    return false;
+}
+
+bool libmormegil::Appcfg::get(const std::string& name, std::string& val)
+{
+    data_iterator iter = data.find(name);
+    if ((iter != data.end()) && (iter->second.t == Appcfg_string))
+    {
+        val = iter->second.sval;
+        return true;
+    }
+    return false;
+}
+
+bool libmormegil::Appcfg::get(const std::string& name, bool& val) const
+{
+    data_iterator iter = data.find(name);
+    if ((iter != data.end()) && (iter->second.t == Appcfg_boolean))
+    {
+        val = iter->second.bval;
+        return true;
+    }
+    return false;
+}
+
+bool libmormegil::Appcfg::set(const std::string& name, int64_t val)
+{
+    data_iterator iter = data.find(name);
+    if ((iter != data.end()) && (iter->second.t == Appcfg_integer))
+    {
+        iter->second.ival = val;
+        return true;
+    }
+    return false;
+}
+
+bool libmormegil::Appcfg::set(const std::string& name, const std::string& val)
+{
+    data_iterator iter = data.find(name);
+    if ((iter != data.end()) && (iter->second.t == Appcfg_string))
+    {
+        iter->second.sval = val;
+        return true;
+    }
+    return false;
+}
+
+bool libmormegil::Appcfg::set(const std::string& name, bool val)
+{
+    data_iterator iter = data.find(name);
+    if ((iter != data.end()) && (iter->second.t == Appcfg_boolean))
+    {
+        iter->second.bval = val;
+        return true;
+    }
+    return false;
+}
+
+// vim:ts=8:sw=4:expandtab:fo=cq
+
diff --git a/src/namegen.cc b/src/namegen.cc
new file mode 100644 (file)
index 0000000..331e33c
--- /dev/null
@@ -0,0 +1,386 @@
+// namegen.cc - phonotactic name generators
+// 
+// Copyright 2011 Martin Read
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <string>
+#include <string.h>
+#include <ctype.h>
+
+namespace libmormegil {
+    // This file is derived from Martin's Dungeon Bash's misc.cc.
+
+    // The "dark angel" name generator uses a pseudo-Semitic structure for the
+    // words it generates.
+
+    Phoneme dark_angel_phonemes[] =
+    {
+        // Five vowels, like Hebrew (and incidentally, Latin).
+        { Vowel, Vow_open | Vow_unrounded | Vow_backness_unspecified, "a", "A" },
+        { Vowel, Vow_mid | Vow_unrounded | Vow_front, "e", "E" },
+        { Vowel, Vow_mid | Vow_rounded | Vow_back, "o", "O" },
+        { Vowel, Vow_close | Vow_unrounded | Vow_front, "i", "I" },
+        { Vowel, Vow_close | Vow_rounded | Vow_back, "u", "U" },
+    };
+
+    void name_dark_angel(std::string& dest)
+    {
+    }
+}
+
+/*
+ * Phonotactic dark angel name generator
+ * =====================================
+ * Dark angels are named using different phonotactics to demons.
+ *
+ * Name structure consists of 3-5 consonants; if more than three, the terminal
+ * is restricted to /l/ /h/ /(theta)/
+ * 
+ * Phonemes are:
+ *    Glottal: voiceless fricative, stop.
+ *    Velar: voiceless fricative, ejective, voiceless plosive
+ *    Alveolar: plosive (modal, ten.), ejective, fricative (modal, ten.)
+ *    Labial: voiced plosive
+ *    Vowels: /a/ /e/ /i/ /o/ /u/
+ *    and a homorganic (naturally coronal) nasal
+ *
+ * ASCII notation is:
+ *    h `
+ *    x k' k
+ *    n t d t' s z
+ *    th dh
+ *    b
+ *    
+ */
+
+
+/******************************************************************************
+ *
+ * Phonotactic demon name generator
+ * ================================
+ *
+ * Syllable structure is (C)CVC, with a null onset permissible in the
+ * word-initial position.
+ *
+ * Phonemes are:
+ *    Uvular: tenuis plosive, tenuis fricative, trill
+ *    Velar: plosive (ten + modal), fric. (ten + modal), labio approx.
+ *    Palatal: approx.
+ *    Alveolar: plosive (ten + modal), fric. (ten + modal)
+ *    Dental: fric. (ten + modal)
+ *    Labial: modal plosive, modal fricative.
+ *    Vowels: /a/ /i/ /u/
+ * 
+ * Dorsal fricatives only occur in the coda.  Uvular trill appears only in
+ * word-initial onset.
+ */
+
+/* A D_ptac_state variable is used to track what category the last letter was.
+ * Akvudnik uses CVC syllables (with possible null onset at word-initial).
+ */
+enum D_ptac_state
+{
+    D_ptac_start, D_ptac_null_onset, D_ptac_dorsal_onset, D_ptac_coronal_onset,
+    D_ptac_labial_onset, D_ptac_w_onset, D_ptac_j_onset,
+    D_ptac_low_nucleus, D_ptac_high_nucleus, D_ptac_coda,
+    D_ptac_end
+};
+
+struct D_ptac_transition
+{
+    int weight;
+    const char *fragment;
+    D_ptac_state newstate;
+};
+
+D_ptac_state demon_extend_word(std::string *word, D_ptac_state current);
+
+#define PTAC_FENCEPOST { 0, 0, D_ptac_end }
+
+D_ptac_transition demon_start[] =
+{
+    { 5, "", D_ptac_null_onset },
+    { 3, "q", D_ptac_dorsal_onset },
+    { 3, "r", D_ptac_dorsal_onset },
+    { 12, "k", D_ptac_dorsal_onset },
+    { 3, "g", D_ptac_dorsal_onset },
+    { 1, "w", D_ptac_w_onset },
+    { 1, "j", D_ptac_j_onset },
+    { 8, "t", D_ptac_coronal_onset },
+    { 2, "d", D_ptac_coronal_onset },
+    { 6, "s", D_ptac_coronal_onset },
+    { 2, "z", D_ptac_coronal_onset },
+    { 4, "th", D_ptac_coronal_onset },
+    { 1, "dh", D_ptac_coronal_onset },
+    { 8, "b", D_ptac_labial_onset },
+    { 4, "v", D_ptac_labial_onset },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_null_onset[] =
+{
+    { 10, "u", D_ptac_high_nucleus },
+    { 10, "i", D_ptac_high_nucleus },
+    { 10, "a", D_ptac_low_nucleus },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_dorsal_onset[] =
+{
+    { 20, "u", D_ptac_high_nucleus },
+    { 10, "i", D_ptac_high_nucleus },
+    { 10, "a", D_ptac_low_nucleus },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_j_onset[] =
+{
+    { 10, "u", D_ptac_high_nucleus },
+    { 30, "a", D_ptac_low_nucleus },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_w_onset[] =
+{
+    { 10, "i", D_ptac_high_nucleus },
+    { 30, "a", D_ptac_low_nucleus },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_labial_onset[] =
+{
+    { 14, "u", D_ptac_high_nucleus },
+    { 10, "i", D_ptac_high_nucleus },
+    { 14, "a", D_ptac_low_nucleus },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_coronal_onset[] =
+{
+    { 10, "u", D_ptac_high_nucleus },
+    { 30, "i", D_ptac_high_nucleus },
+    { 10, "a", D_ptac_low_nucleus },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_low_nucleus[] =
+{
+    { 3, "q", D_ptac_coda },
+    { 3, "qh", D_ptac_coda },
+    { 10, "k", D_ptac_coda },
+    { 3, "g", D_ptac_coda },
+    { 3, "x", D_ptac_coda },
+    { 1, "gh", D_ptac_coda },
+    { 1, "w", D_ptac_coda },
+    { 1, "j", D_ptac_coda },
+    { 8, "t", D_ptac_coda },
+    { 2, "d", D_ptac_coda },
+    { 6, "s", D_ptac_coda },
+    { 2, "z", D_ptac_coda },
+    { 4, "th", D_ptac_coda },
+    { 1, "dh", D_ptac_coda },
+    { 8, "b", D_ptac_coda },
+    { 4, "v", D_ptac_coda },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_high_nucleus[] =
+{
+    { 3, "q", D_ptac_coda },
+    { 3, "qh", D_ptac_coda },
+    { 10, "k", D_ptac_coda },
+    { 3, "g", D_ptac_coda },
+    { 3, "x", D_ptac_coda },
+    { 1, "gh", D_ptac_coda },
+    { 8, "t", D_ptac_coda },
+    { 2, "d", D_ptac_coda },
+    { 6, "s", D_ptac_coda },
+    { 2, "z", D_ptac_coda },
+    { 4, "th", D_ptac_coda },
+    { 1, "dh", D_ptac_coda },
+    { 8, "b", D_ptac_coda },
+    { 4, "v", D_ptac_coda },
+    PTAC_FENCEPOST
+};
+
+D_ptac_transition demon_coda[] =
+{
+    { 3, "q", D_ptac_dorsal_onset },
+    { 12, "k", D_ptac_dorsal_onset },
+    { 3, "g", D_ptac_dorsal_onset },
+    { 1, "w", D_ptac_w_onset },
+    { 1, "j", D_ptac_j_onset },
+    { 8, "t", D_ptac_coronal_onset },
+    { 2, "d", D_ptac_coronal_onset },
+    { 5, "s", D_ptac_coronal_onset },
+    { 2, "z", D_ptac_coronal_onset },
+    { 4, "th", D_ptac_coronal_onset },
+    { 1, "dh", D_ptac_coronal_onset },
+    { 8, "b", D_ptac_labial_onset },
+    { 4, "v", D_ptac_labial_onset },
+    PTAC_FENCEPOST
+};
+
+int demon_start_sum;
+int demon_low_nucleus_sum;
+int demon_high_nucleus_sum;
+int demon_null_onset_sum;
+int demon_dorsal_onset_sum;
+int demon_coronal_onset_sum;
+int demon_labial_onset_sum;
+int demon_j_onset_sum;
+int demon_w_onset_sum;
+int demon_coda_sum;
+
+void ptac_init(void)
+{
+    int i;
+    for (i = 0; demon_start[i].fragment != 0; ++i)
+    {
+        demon_start_sum += demon_start[i].weight;
+    }
+    for (i = 0; demon_null_onset[i].fragment != 0; ++i)
+    {
+        demon_null_onset_sum += demon_null_onset[i].weight;
+    }
+    for (i = 0; demon_labial_onset[i].fragment != 0; ++i)
+    {
+        demon_labial_onset_sum += demon_labial_onset[i].weight;
+    }
+    for (i = 0; demon_coronal_onset[i].fragment != 0; ++i)
+    {
+        demon_coronal_onset_sum += demon_coronal_onset[i].weight;
+    }
+    for (i = 0; demon_dorsal_onset[i].fragment != 0; ++i)
+    {
+        demon_dorsal_onset_sum += demon_dorsal_onset[i].weight;
+    }
+    for (i = 0; demon_j_onset[i].fragment != 0; ++i)
+    {
+        demon_j_onset_sum += demon_j_onset[i].weight;
+    }
+    for (i = 0; demon_w_onset[i].fragment != 0; ++i)
+    {
+        demon_w_onset_sum += demon_w_onset[i].weight;
+    }
+    for (i = 0; demon_coda[i].fragment != 0; ++i)
+    {
+        demon_coda_sum += demon_coda[i].weight;
+    }
+    for (i = 0; demon_high_nucleus[i].fragment != 0; ++i)
+    {
+        demon_high_nucleus_sum += demon_high_nucleus[i].weight;
+    }
+    for (i = 0; demon_low_nucleus[i].fragment != 0; ++i)
+    {
+        demon_low_nucleus_sum += demon_low_nucleus[i].weight;
+    }
+}
+
+char *demon_get_name(void)
+{
+    std::string working_copy;
+    D_ptac_state current = D_ptac_start;
+    int syllables = 1;
+    do
+    {
+        current = demon_extend_word(&working_copy, current);
+        if (current == D_ptac_coda)
+        {
+            if (zero_die(6) < (syllables - 1))
+            {
+                current = D_ptac_end;
+            }
+            ++syllables;
+        }
+    } while (current != D_ptac_end);
+    char *s = strdup(working_copy.c_str());
+    s[0] = toupper(s[0]);
+    return s;
+}
+
+D_ptac_state demon_extend_word(std::string *word, D_ptac_state current)
+{
+    D_ptac_transition const *arr = 0;
+    int dieroll = 0;
+    int idx;
+    switch (current)
+    {
+    case D_ptac_start:
+        dieroll = zero_die(demon_start_sum);
+        arr = demon_start;
+        break;
+    case D_ptac_dorsal_onset:
+        dieroll = zero_die(demon_dorsal_onset_sum);
+        arr = demon_dorsal_onset;
+        break;
+    case D_ptac_coronal_onset:
+        dieroll = zero_die(demon_coronal_onset_sum);
+        arr = demon_coronal_onset;
+        break;
+    case D_ptac_labial_onset:
+        dieroll = zero_die(demon_labial_onset_sum);
+        arr = demon_labial_onset;
+        break;
+    case D_ptac_w_onset:
+        dieroll = zero_die(demon_w_onset_sum);
+        arr = demon_w_onset;
+        break;
+    case D_ptac_j_onset:
+        dieroll = zero_die(demon_j_onset_sum);
+        arr = demon_j_onset;
+        break;
+    case D_ptac_null_onset:
+        dieroll = zero_die(demon_null_onset_sum);
+        arr = demon_null_onset;
+        break;
+    case D_ptac_coda:
+        dieroll = zero_die(demon_coda_sum);
+        arr = demon_coda;
+        break;
+    case D_ptac_high_nucleus:
+        dieroll = zero_die(demon_high_nucleus_sum);
+        arr = demon_high_nucleus;
+        break;
+    case D_ptac_low_nucleus:
+        dieroll = zero_die(demon_low_nucleus_sum);
+        arr = demon_low_nucleus;
+        break;
+    case D_ptac_end:
+        print_msg(MSGCHAN_INTERROR, "Attempt to extend name in an end state?!");
+        return D_ptac_end;
+    }
+    for (idx = 0; ; ++idx)
+    {
+        if (dieroll < arr[idx].weight)
+        {
+            break;
+        }
+        dieroll -= arr[idx].weight;
+    }
+    (*word) += arr[idx].fragment;
+    return arr[idx].newstate;
+}
+
+// namegen.cc
diff --git a/src/ordinaldate.cc b/src/ordinaldate.cc
new file mode 100644 (file)
index 0000000..18ecfe7
--- /dev/null
@@ -0,0 +1,63 @@
+// ordinaldate.cc
+//
+// Copyright 2011 Martin Read. All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the author nor the names of any other contributors
+//    may be used to endorse or promote products derived from this software
+//    without their specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#include <string>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <libmormegil/isotime.h>
+
+extern "C" int get_iso_8601_time(char *buf, int bufsz)
+{
+    time_t t;
+    char tmpbuf[128];
+    tm tdat;
+    int bufreq;
+    time(&t);
+    gmtime_r(&t, &tdat);
+    bufreq = snprintf(tmpbuf, 128, "%d-%3.3dT%2.2d%2.2d%2.2dZ", tdat.tm_year + 1900, tdat.tm_yday, tdat.tm_hour, tdat.tm_min, tdat.tm_sec);
+    if (bufreq < bufsz)
+    {
+        strncpy(buf, tmpbuf, bufsz);
+    }
+    return bufreq;
+}
+
+void libmormegil::get_iso_8601_time(std::string& dest)
+{
+    time_t t;
+    char buf[128];
+    tm tdat;
+    time(&t);
+    gmtime_r(&t, &tdat);
+    snprintf(buf, 128, "%d-%3.3dT%2.2d%2.2d%2.2dZ", tdat.tm_year + 1900, tdat.tm_yday, tdat.tm_hour, tdat.tm_min, tdat.tm_sec);
+    dest = buf;
+    return;
+}
+
+// ordinaldate.cc