From: fluffymormegil Date: Tue, 26 Apr 2011 23:17:06 +0000 (+0100) Subject: Added new functions emit_chebyshev_spiral and tagify (dragged in from dungeonbash... X-Git-Url: http://git.blackswordsonics.com/?a=commitdiff_plain;h=653219a9b02ae05d7f42c6d8024c8b719592fa2e;p=libmormegil Added new functions emit_chebyshev_spiral and tagify (dragged in from dungeonbash and beaten into genericity) --- diff --git a/include/libmormegil/srcgen-parts.hh b/include/libmormegil/srcgen-parts.hh new file mode 100644 index 0000000..b809a7a --- /dev/null +++ b/include/libmormegil/srcgen-parts.hh @@ -0,0 +1,22 @@ +// libmormegil/stlfgets.hh +// +// In jurisdictions where this file would be adjuged to contain copyrightable +// material, it is copyright 2011 Martin Read, and released to the public +// under the terms of the Creative Commons Public Domain Dedication (cc-0). +// It is provided without any warranty, express or implied. + +#include +#include + +namespace libmormegil +{ + std::string *tagify(const char *name, const char *prefix); + // By default, the generated path is not namespaced. Please note that this + // function has no bounds checks and no return value; it's your job to pass + // it sensible strings and FILE * objects, and to close them when you're + // done. It has default arguments for damage limitation. + void emit_chebyshev_spiral(FILE *srcfile = stdout, FILE *hdrfile = stdout, unsigned int radius = 10, + const char *macrotag = "cheby_spiral", const char *nmsp = 0); +} + +// vim:ts=8:sw=4:expandtab:fo=croq diff --git a/man/libmormegil::emit_chebyshev_spiral.3 b/man/libmormegil::emit_chebyshev_spiral.3 new file mode 100644 index 0000000..5439b60 --- /dev/null +++ b/man/libmormegil::emit_chebyshev_spiral.3 @@ -0,0 +1,39 @@ +.TH "LIBMORMEGIL::EMIT_CHEBYSHEV_SPIRAL" 3 "April 26, 2011" "libmormegil Version 2.0" "libmormegil User Manual" +.SH NAME +libmormegil::emit_chebyshev_spiral \- print out source and header files for a chebyshev-metric spiral +.SH SYNOPSIS +#include + +void libmormegil::emit_chebyshev_spiral(FILE *srcfile, FILE *hdrfile, unsigned int radius, const char *macrotag, const char *nmsp); + +.SH DESCRIPTION + +.I libmormegil::emit_chebyshev_spiral +prints a C++ source file via the \fIFILE\fP object pointed to by \fIsrcfile\fP +and a C++ header file via the \fIFILE\fP object point to by \fIhdrfile\fP. + +These output files describe the steps of a discrete spiral of radius +.I radius +under a Chebyshev metric, formatted as an array of (2 * radius + 1)^2 objects +of type \fIlibmormegil::Offset\fP. The array is named \fIcheby_spiral\fP and +can optionally be placed into a C++ namespace by passing a non-null pointer to +a non-empty C-style string as the argument \fInmsp\fP (which is null by +default). The character string pointed to by \fImacrotag\fP (default: +"cheby_spiral") is used as part of the include-guard macro string in the +emitted header file. + +.SH CAVEATS + +Does not check its inputs. The caller has responsiblity for managing the +objects pointed to by \fIsrcfile\fP and \fIhdrfile\fP, and for sanitizing the +strings passed as \fImacrotag\fP and \fInmsp\fP. + +If you find yourself wanting a spiral larger than radius 20 or so, you may want +to re-evaluate the algorithm you were going to use it with. + +.SH AUTHOR +Martin Read + +.SH SEE ALSO + +libmormegil(3) diff --git a/man/libmormegil::tagify.3 b/man/libmormegil::tagify.3 new file mode 100644 index 0000000..3398140 --- /dev/null +++ b/man/libmormegil::tagify.3 @@ -0,0 +1,44 @@ +.TH "LIBMORMEGIL::TAGIFY" 3 "April 26, 2011" "libmormegil Version 2.0" "libmormegil User Manual" +.SH NAME +libmormegil::tagify \- generate a "tag" string from a name and a prefix +.SH SYNOPSIS +#include + +std::string * libmormegil::tagify(const char *name, const char *prefix); + +.SH DESCRIPTION + +.I libmormegil::tagify +allocates a new \fIstd::string\fP object created from the C-style string +pointed to by \fIprefix\fP, then appends the characters of \fIname\fP in +order, transformed as follows: + +.IP * 4 +Values outside the range 33-126 are replaced with underscore (ASCII 0x5F) +.IP * 4 +Decimal digits are unchanged. +.IP * 4 +Lower-case 'i' (ASCII 0x69) is replaced with upper-case 'I' (ASCII 0x49) +.IP * 4 +All other characters for which \fIisalpha(3)\fP returns nonzero are replaced +the result of passing them to \fItoupper(3)\fP. +.IP * 4 +Any characters not covered by the above are replaced with underscore (ASCII +0x5F). + +.SH CAVEATS + +While this function makes a vague attempt to deal with 8-bit encodings, and to +limit backscatter from the Unicode committee's questionable decisions regarding +case transformations of the letters I and İ (which mean that if you have mixed +Turkish and non-Turkish Latin-alphabet text, you cannot safely perform case +transformations or case-insensitive comparisons!), the tags generated from +UTF-8 input will not be usable as identifiers in \fIstandards-compliant\fP C or +C++ programs, as they will contain multiple adjacent underscores. + +.SH AUTHOR +Martin Read + +.SH SEE ALSO + +libmormegil(3) diff --git a/src/srcgen-parts.cc b/src/srcgen-parts.cc new file mode 100644 index 0000000..3fc9562 --- /dev/null +++ b/src/srcgen-parts.cc @@ -0,0 +1,164 @@ +// srcgen-parts.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 +#include +#include +#include +#include +#include + +std::string *libmormegil::tagify(const char *__restrict__ name, const char *__restrict__ prefix) +{ + int i; + int len = strlen(name); + std::string *foo = new std::string(prefix); + for (i = 0; i < len; ++i) + { + if (isalpha(name[i])) + { + (*foo) += toupper(name[i]); + } + else if (isdigit(name[i])) + { + (*foo) += name[i]; + } + else + { + (*foo) += '_'; + } + } + return foo; +} + +enum Edge +{ + North_edge, East_edge, South_edge, West_edge +}; + +// This next function is used to generate a sequential lookup table for radial effects. +void libmormegil::emit_chebyshev_spiral(FILE *srcfile, FILE *hdrfile, unsigned int radius, + const char *__restrict__ macrotag, const char *__restrict__ nmsp) +{ + fputs("/* This file is automatically generated. DO NOT EDIT! */\n\n", srcfile); + fputs("/* This file is automatically generated. DO NOT EDIT! */\n\n", hdrfile); + fprintf(srcfile, "#define %s_cc\n", macrotag); + fprintf(hdrfile, "#ifndef inc_%s_hh\n#define inc_%s_hh\n#include \n", macrotag, macrotag); + if (nmsp && *nmsp) + { + fprintf(srcfile, "libmormegil::Offset %s::cheby_spiral[%d * %d] = \n{\n", nmsp, + (radius * 2 + 1), (radius * 2 + 1)); + fprintf(hdrfile, "namespace %s\n{\n ", nmsp); + } + else + { + fprintf(srcfile, "libmormegil::Offset cheby_spiral[%d * %d] = \n{\n", nmsp, + (radius * 2 + 1), (radius * 2 + 1)); + } + fprintf(hdrfile, "extern libmormegil::Offset cheby_spiral[%d * %d];\n", + (radius * 2 + 1), (radius * 2 + 1)); + int i; + int cur_radius = 0; + int cur_y = 0; + int cur_x = 0; + Edge cur_edge = North_edge; + for (i = 0; i < ((radius * 2 + 1) * (radius * 2 + 1)); ++i) + { + fprintf(srcfile, "{ %d, %d },\n", cur_y, cur_x); + switch (cur_edge) + { + case North_edge: + if (!cur_radius) + { + --cur_y; + ++cur_radius; + } + else if (cur_x == cur_radius) + { + cur_edge = East_edge; + ++cur_y; + } + else + { + ++cur_x; + if (cur_x == 0) + { + ++cur_radius; + --cur_y; + } + } + break; + case East_edge: + if (cur_y == cur_radius) + { + cur_edge = South_edge; + --cur_x; + } + else + { + ++cur_y; + } + break; + case South_edge: + if (cur_x == -cur_radius) + { + cur_edge = West_edge; + --cur_y; + } + else + { + --cur_x; + } + break; + case West_edge: + if (cur_y == -cur_radius) + { + cur_edge = North_edge; + ++cur_x; + if (cur_x == 0) + { + ++cur_radius; + --cur_y; + } + } + else + { + --cur_y; + } + break; + } + } + fprintf(srcfile, "};\n"); + if (nmsp && *nmsp) + { + fprintf(hdrfile, "}\n"); + } + fprintf(hdrfile, "#endif\n"); +} + +// vim:ts=8:sw=4:expandtab:fo=croq