--- /dev/null
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2006 Christoph Pfisterer
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * 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.
+#
+# * Neither the name of Christoph Pfisterer nor the names of the
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+# OWNER 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.
+#
+
+#
+# mk_fsw_strfunc.py
+#
+
+# definitions
+
+types = {
+ 'ISO88591': 'fsw_u8',
+ 'UTF8': 'fsw_u8',
+ 'UTF16': 'fsw_u16',
+ 'UTF16_SWAPPED': 'fsw_u16',
+}
+getnext = {
+ 'ISO88591': 'VARC = *VARP++;',
+ 'UTF8': """VARC = *VARP++;
+if ((VARC & 0xe0) == 0xc0) {
+ VARC = ((VARC & 0x1f) << 6) | (*VARP++ & 0x3f);
+} else if ((VARC & 0xf0) == 0xe0) {
+ VARC = ((VARC & 0x0f) << 12) | ((*VARP++ & 0x3f) << 6);
+ VARC |= (*VARP++ & 0x3f);
+} else if ((VARC & 0xf8) == 0xf0) {
+ VARC = ((VARC & 0x07) << 18) | ((*VARP++ & 0x3f) << 12);
+ VARC |= ((*VARP++ & 0x3f) << 6);
+ VARC |= (*VARP++ & 0x3f);
+}""",
+ 'UTF16': 'VARC = *VARP++;',
+ 'UTF16_SWAPPED': 'VARC = *VARP++; VARC = FSW_SWAPVALUE_U16(VARC);',
+}
+
+combos = ( ('ISO88591', 'UTF8'), ('ISO88591', 'UTF16'), ('ISO88591', 'UTF16_SWAPPED'),
+ ('UTF8', 'UTF16'), ('UTF8', 'UTF16_SWAPPED'),
+ ('UTF16', 'UTF16_SWAPPED') )
+
+coerce_combos = {}
+for combo in combos:
+ coerce_combos.setdefault(combo[0], []).append(combo[1])
+ coerce_combos.setdefault(combo[1], []).append(combo[0])
+
+# generate functions
+
+output = """/* fsw_strfunc.h generated by mk_fsw_strfunc.py */
+"""
+
+# generate streq functions (symmetric)
+
+for combo in combos:
+ (enc1, enc2) = combo
+ type1 = types[enc1]
+ type2 = types[enc2]
+ getnext1 = getnext[enc1].replace('VARC', 'c1').replace('VARP', 'p1').replace("\n", "\n ")
+ getnext2 = getnext[enc2].replace('VARC', 'c2').replace('VARP', 'p2').replace("\n", "\n ")
+
+ output += """
+static int fsw_streq_%(enc1)s_%(enc2)s(void *s1data, void *s2data, int len)
+{
+ int i;
+ %(type1)s *p1 = (%(type1)s *)s1data;
+ %(type2)s *p2 = (%(type2)s *)s2data;
+ fsw_u32 c1, c2;
+
+ for (i = 0; i < len; i++) {
+ %(getnext1)s
+ %(getnext2)s
+ if (c1 != c2)
+ return 0;
+ }
+ return 1;
+}
+""" % locals()
+
+# generate strcoerce functions (asymmetric, destination-specific)
+
+for enc2 in ('ISO88591', 'UTF16'):
+ for enc1 in coerce_combos[enc2]:
+ type1 = types[enc1]
+ type2 = types[enc2]
+ getnext1 = getnext[enc1].replace('VARC', 'c').replace('VARP', 'sp').replace("\n", "\n ")
+ output += """
+static fsw_status_t fsw_strcoerce_%(enc1)s_%(enc2)s(void *srcdata, int srclen, struct fsw_string *dest)
+{
+ fsw_status_t status;
+ int i;
+ %(type1)s *sp;
+ %(type2)s *dp;
+ fsw_u32 c;
+
+ dest->type = FSW_STRING_TYPE_%(enc2)s;
+ dest->len = srclen;
+ dest->size = srclen * sizeof(%(type2)s);
+ status = fsw_alloc(dest->size, &dest->data);
+ if (status)
+ return status;
+
+ sp = (%(type1)s *)srcdata;
+ dp = (%(type2)s *)dest->data;
+ for (i = 0; i < srclen; i++) {
+ %(getnext1)s
+ *dp++ = c;
+ }
+ return FSW_SUCCESS;
+}
+""" % locals()
+
+for enc2 in ('UTF8',):
+ for enc1 in coerce_combos[enc2]:
+ type1 = types[enc1]
+ type2 = types[enc2]
+ getnext1 = getnext[enc1].replace('VARC', 'c').replace('VARP', 'sp').replace("\n", "\n ")
+ output += """
+static fsw_status_t fsw_strcoerce_%(enc1)s_%(enc2)s(void *srcdata, int srclen, struct fsw_string *dest)
+{
+ fsw_status_t status;
+ int i, destsize;
+ %(type1)s *sp;
+ %(type2)s *dp;
+ fsw_u32 c;
+
+ sp = (%(type1)s *)srcdata;
+ destsize = 0;
+ for (i = 0; i < srclen; i++) {
+ %(getnext1)s
+
+ if (c < 0x000080)
+ destsize++;
+ else if (c < 0x000800)
+ destsize += 2;
+ else if (c < 0x010000)
+ destsize += 3;
+ else
+ destsize += 4;
+ }
+
+ dest->type = FSW_STRING_TYPE_%(enc2)s;
+ dest->len = srclen;
+ dest->size = destsize;
+ status = fsw_alloc(dest->size, &dest->data);
+ if (status)
+ return status;
+
+ sp = (%(type1)s *)srcdata;
+ dp = (%(type2)s *)dest->data;
+ for (i = 0; i < srclen; i++) {
+ %(getnext1)s
+
+ if (c < 0x000080) {
+ *dp++ = c;
+ } else if (c < 0x000800) {
+ *dp++ = 0xc0 | ((c >> 6) & 0x1f);
+ *dp++ = 0x80 | (c & 0x3f);
+ } else if (c < 0x010000) {
+ *dp++ = 0xe0 | ((c >> 12) & 0x0f);
+ *dp++ = 0x80 | ((c >> 6) & 0x3f);
+ *dp++ = 0x80 | (c & 0x3f);
+ } else {
+ *dp++ = 0xf0 | ((c >> 18) & 0x07);
+ *dp++ = 0x80 | ((c >> 12) & 0x3f);
+ *dp++ = 0x80 | ((c >> 6) & 0x3f);
+ *dp++ = 0x80 | (c & 0x3f);
+ }
+ }
+ return FSW_SUCCESS;
+}
+""" % locals()
+
+# coerce functions with destination UFT16_SWAPPED missing by design
+
+# write output file
+
+f = file("fsw_strfunc.h", "w")
+f.write(output)
+f.close()
+
+# EOF