summaryrefslogtreecommitdiff
path: root/module
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2008-11-11 05:09:51 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2008-11-11 05:09:51 +0000
commit42de9db2762a63f69321fc4e89ea81e16a5a206a (patch)
treefbff2a9f70f8a2792d134f5a9dc60d11b2ee0a08 /module
parentb5aa13a47b66955a5198da1f88e1f93f09306a84 (diff)
downloadiconv-42de9db2762a63f69321fc4e89ea81e16a5a206a.tar.gz
iconv-42de9db2762a63f69321fc4e89ea81e16a5a206a.tar.bz2
Integrate module sources into build system.
Various hackery to get it to build for non-RO platforms. A bunch of const-correctness fixes. Hack around strict aliasing warning. Don't expect the menu code to work on 64bit platforms. Sprinkling a bit of intptr_t around may well be some kind of solution. svn path=/trunk/iconv/; revision=5680
Diffstat (limited to 'module')
-rw-r--r--module/Makefile103
-rw-r--r--module/header.h126
-rw-r--r--module/kernel.h19
-rw-r--r--module/menu.c62
-rw-r--r--module/module.c40
-rw-r--r--module/module.h14
-rw-r--r--module/wrapper.c34
7 files changed, 341 insertions, 57 deletions
diff --git a/module/Makefile b/module/Makefile
new file mode 100644
index 0000000..a57f240
--- /dev/null
+++ b/module/Makefile
@@ -0,0 +1,103 @@
+# Child makefile fragment
+#
+# Toolchain is provided by top-level makefile
+#
+# Variables provided by top-level makefile
+#
+# COMPONENT The name of the component
+# EXPORT The location of the export directory
+# TOP The location of the source tree root
+# RELEASEDIR The place to put release objects
+# DEBUGDIR The place to put debug objects
+#
+# do_include Canned command sequence to include a child makefile
+#
+# Variables provided by parent makefile:
+#
+# DIR The name of the directory we're in, relative to $(TOP)
+#
+# Variables we can manipulate:
+#
+# ITEMS_CLEAN The list of items to remove for "make clean"
+# ITEMS_DISTCLEAN The list of items to remove for "make distclean"
+# TARGET_TESTS The list of target names to run for "make test"
+#
+# SOURCES The list of sources to build for $(COMPONENT)
+#
+# Plus anything from the toolchain
+
+# Push parent directory onto the directory stack
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(DIR)
+
+# Extend toolchain settings
+CFLAGS := $(CFLAGS) -I$(TOP)/src -I$(d)
+
+# Module filename
+MODULE := Iconv$(EXEEXT)
+HEADER := $(addprefix $(d), header.o)
+
+# Sources for module
+SRCS_$(d) := module.c menu.c wrapper.c
+
+# Objects for module
+OBJS_$(d) := $(HEADER) $(addprefix $(d), $(subst .c,.o,$(SRCS_$(d))))
+
+# Items for top-level makefile to use
+ITEMS_CLEAN := $(ITEMS_CLEAN) \
+ $(OBJS_$(d)) \
+ $(addprefix $(d), $(subst .c,.d,$(SRCS_$(d))))
+
+ITEMS_DISTCLEAN := $(ITEMS_DISTCLEAN) $(MODULE)
+
+# Target for building module
+# Please excuse the sick use of wordlist to get hold of the objects to link
+# We can't use $(OBJS_$(d)), as $(d) will be different when the rule is run
+module: release $(OBJS_$(d))
+ @$(LD) -o $(MODULE) $(wordlist 2,$(words $^),$^) $(LDFLAGS) -liconv -lunicode
+
+# Target for building module header (mildly hacky)
+$(HEADER): $(addprefix $(d), header.cmhg)
+ifeq ($(TARGET),riscos)
+ @$(CMHG) $(CMHGFLAGS) $< -o $@ -d $(addprefix $(d), header.h)
+else
+ @$(TOUCH) $@
+endif
+
+DEP_$(d) :=
+
+define dep_module
+DEP_$(d) += $(2)
+$(2): $(1)
+ @$$(ECHO) $$(ECHOFLAGS) "DEP $(1)"
+ @$$(RM) $$(RMFLAGS) $(2)
+ @$$(CC) $$(DEBUGCFLAGS) -MM -MT '$(2) $(3)' -MF $(2) $(1)
+
+endef
+
+# Build rules for each module object
+define compile_module
+$(2): $(1)
+ @$$(ECHO) $$(ECHOFLAGS) "==> $(1)"
+ @$$(CC) -c $$(RELEASECFLAGS) -o $$@ $(1)
+
+endef
+
+$(eval $(foreach SOURCE,$(addprefix $(d), $(SRCS_$(d))), \
+ $(call dep_module,$(SOURCE),$(SOURCE:.c=.d),$(SOURCE:.c=.o))))
+
+ifneq ($(findstring clean,$(MAKECMDGOALS)),clean)
+-include $(sort $(DEP_$(d)))
+endif
+
+$(eval $(foreach SOURCE,$(addprefix $(d), $(SRCS_$(d))), \
+ $(call compile_module,$(SOURCE),$(SOURCE:.c=.o))))
+
+# Now include any children we may have
+MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
+$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))
+
+# Finally, pop off the directory stack
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/module/header.h b/module/header.h
new file mode 100644
index 0000000..df5ff48
--- /dev/null
+++ b/module/header.h
@@ -0,0 +1,126 @@
+/*
+ * Created by cmhg vsn 5.42 [01 Mar 2002]
+ */
+
+#ifndef __cmhg_header_h
+#define __cmhg_header_h
+
+#ifndef __kernel_h
+#include "kernel.h"
+#endif
+
+#define CMHG_VERSION 542
+
+#define Module_Title "Iconv"
+#define Module_Help "Iconv"
+#define Module_VersionString "0.08"
+#define Module_VersionNumber 8
+#ifndef Module_Date
+#define Module_Date "11 Mar 2007"
+#endif
+
+
+/*
+ * Initialisation code
+ * ===================
+ *
+ * Return NULL if your initialisation succeeds; otherwise return a pointer
+ * to an error block. cmd_tail points to the string of arguments with which
+ * the module is invoked (may be "", and is control-terminated, not zero
+ * terminated).
+ * podule_base is 0 unless the code has been invoked from a podule.
+ * pw is the 'R12' value established by module initialisation. You may
+ * assume nothing about its value (in fact it points to some RMA space
+ * claimed and used by the module veneers). All you may do is pass it back
+ * for your module veneers via an intermediary such as SWI OS_CallEvery
+ * (use _swix() to issue the SWI call).
+ */
+_kernel_oserror *mod_init(const char *cmd_tail, int podule_base, void *pw);
+
+
+/*
+ * Finalisation code
+ * =================
+ *
+ * Return NULL if your finalisation succeeds. Otherwise return a pointer to
+ * an error block if your finalisation handler does not wish to die (e.g.
+ * toolbox modules return a 'Task(s) active' error).
+ * fatal, podule and pw are the values of R10, R11 and R12 (respectively)
+ * on entry to the finalisation code.
+ */
+_kernel_oserror *mod_fini(int fatal, int podule, void *pw);
+
+
+/*
+ * Command handler
+ * ===============
+ *
+ * If cmd_no identifies a command, then arg_string gives the command tail
+ * (which you may not overwrite), and argc is the number of parameters.
+ * NB. arg_string is control terminated so it may not be a C string.
+ * Return NULL if the command has been successfully handled; otherwise
+ * return a pointer to an error block describing the failure (in this
+ * case, the veneer code will set the 'V' bit).
+ *
+ * If cmd_no identifies a *Help entry, then arg_string denotes a buffer
+ * that you can assemble your output into. cmd_handler must return
+ * NULL, an error pointer or help_PRINT_BUFFER (if help_PRINT_BUFFER)
+ * is returned, the zero-terminated buffer will be printed).
+ *
+ * If cmd_no identifies a *Configure option, then arg_string gives the
+ * command tail, and argc the number of parameters. Return NULL, an error
+ * pointer, or one of the four special values defined below. If arg_string
+ * is set to arg_CONFIGURE_SYNTAX, the user has typed *Configure with no
+ * parameter; simply print your syntax string. If arg_string is set to
+ * arg_STATUS, print your current configured status. Otherwise use
+ * arg_string and argc to set the *Configure option.
+ *
+ * pw is the private word pointer ('R12') value passed into the entry
+ * veneer
+ */
+#define help_PRINT_BUFFER ((_kernel_oserror *) arg_string)
+#define arg_CONFIGURE_SYNTAX ((char *) 0)
+#define arg_STATUS ((char *) 1)
+#define configure_BAD_OPTION ((_kernel_oserror *) -1)
+#define configure_NUMBER_NEEDED ((_kernel_oserror *) 1)
+#define configure_TOO_LARGE ((_kernel_oserror *) 2)
+#define configure_TOO_MANY_PARAMS ((_kernel_oserror *) 3)
+
+#define CMD_ReadAliases 0
+
+_kernel_oserror *command_handler(const char *arg_string, int argc, int cmd_no, void *pw);
+
+
+/*
+ * SWI handler code
+ * ================
+ *
+ * swi_offset contains the offset of the SWI into your SWI chunk.
+ * r points to the registers passed to the SWI.
+ *
+ * Return NULL if the SWI is handled successfully; otherwise return
+ * a pointer to an error block which describes the error.
+ * The veneer code sets the 'V' bit if the returned value is non-NULL.
+ * The special value error_BAD_SWI may be returned if you do not
+ * implement a SWI; the veneer will arrange for the appropriate
+ * standard internationalised error 'SWI value out of range for
+ * module Iconv' to be returned.
+ * The handler may update any of its input registers (R0-R9).
+ * pw is the private word pointer ('R12') value passed into the
+ * SWI handler entry veneer.
+ */
+#define Iconv_00 0x057540
+#ifndef Iconv_Open
+#define Iconv_Open 0x057540
+#define Iconv_Iconv 0x057541
+#define Iconv_Close 0x057542
+#define Iconv_Convert 0x057543
+#define Iconv_CreateMenu 0x057544
+#define Iconv_DecodeMenu 0x057545
+#endif
+
+#define error_BAD_SWI ((_kernel_oserror *) -1)
+
+_kernel_oserror *swi_handler(int swi_offset, _kernel_swi_regs *r, void *pw);
+
+#endif
diff --git a/module/kernel.h b/module/kernel.h
new file mode 100644
index 0000000..fa92afe
--- /dev/null
+++ b/module/kernel.h
@@ -0,0 +1,19 @@
+/* Our own, minimal, kernel.h */
+
+#ifndef iconv_myswis_h_
+#define iconv_myswis_h_
+
+#include <inttypes.h>
+
+typedef struct _kernel_oserror {
+ int errnum;
+ char errmess[252];
+} _kernel_oserror;
+
+/* Why intptr_t? Because it's got a chance of working on 64bit machines */
+typedef struct _kernel_swi_regs {
+ intptr_t r[10];
+} _kernel_swi_regs;
+
+#endif
+
diff --git a/module/menu.c b/module/menu.c
index f42f505..d83cb61 100644
--- a/module/menu.c
+++ b/module/menu.c
@@ -1,6 +1,7 @@
/* Encoding menu */
#include <ctype.h>
+#include <inttypes.h>
#ifdef MTEST
#include <stdio.h>
#endif
@@ -30,16 +31,16 @@ typedef struct _menu {
} wimp_menu;
struct menu_desc {
- char *title;
+ const char *title;
int n_entries;
const char *entries[1];
};
#define menudesc(N) \
struct { \
- char *title; \
+ const char *title; \
int n_entries; \
- char *entries[(N)]; \
+ const char *entries[(N)]; \
}
/* Menu descriptions.
@@ -262,24 +263,26 @@ static const struct sub_menu {
const struct menu_desc *desc;
const short *lut;
} sub_menus[] = {
- { "Arabic", (const struct menu_desc *)&arabic_menu,
+ { "Arabic", (const struct menu_desc *) (void *) &arabic_menu,
csmap.arabic },
- { "Chinese", (const struct menu_desc *)&chinese_menu,
+ { "Chinese", (const struct menu_desc *) (void *) &chinese_menu,
csmap.chinese },
- { "Cyrillic", (const struct menu_desc *)&cyrillic_menu,
+ { "Cyrillic", (const struct menu_desc *) (void *) &cyrillic_menu,
csmap.cyrillic },
- { "Greek", (const struct menu_desc *)&greek_menu, csmap.greek },
- { "Hebrew", (const struct menu_desc *)&hebrew_menu,
+ { "Greek", (const struct menu_desc *) (void *) &greek_menu,
+ csmap.greek },
+ { "Hebrew", (const struct menu_desc *) (void *) &hebrew_menu,
csmap.hebrew },
- { "Japanese", (const struct menu_desc *)&japanese_menu,
+ { "Japanese", (const struct menu_desc *) (void *) &japanese_menu,
csmap.japanese },
- { "Korean", (const struct menu_desc *)&korean_menu,
+ { "Korean", (const struct menu_desc *) (void *) &korean_menu,
csmap.korean },
- { "Latin", (const struct menu_desc *)&latin_menu, csmap.latin },
- { "Thai", (const struct menu_desc *)&thai_menu, csmap.thai },
- { "Universal", (const struct menu_desc *)&universal_menu,
+ { "Latin", (const struct menu_desc *) (void *) &latin_menu,
+ csmap.latin },
+ { "Thai", (const struct menu_desc *) (void *) &thai_menu, csmap.thai },
+ { "Universal", (const struct menu_desc *) (void *) &universal_menu,
csmap.universal },
- { "Vietnamese", (const struct menu_desc *)&vietnamese_menu,
+ { "Vietnamese", (const struct menu_desc *) (void *) &vietnamese_menu,
csmap.vietnamese },
};
#define SUB_MENU_COUNT (sizeof(sub_menus) / sizeof(sub_menus[0]))
@@ -309,17 +312,17 @@ static const struct sub_menu {
*/
static char *menu_op(const struct menu_desc *d, char *buf,
wimp_menu *parent, size_t which, size_t flags,
- size_t charset, const short *lut, char **data)
+ short charset, const short *lut, char **data)
{
- size_t e, top = 0;
- struct { size_t e; const char *name; } submenus[MAX_SUBMENUS];
+ int e, top = 0;
+ struct { int e; const char *name; } submenus[MAX_SUBMENUS];
char *bp = buf;
char *dp;
if (data)
dp = *data;
- if (!buf && (flags & 0x02))
+ if (!buf && (flags & MENU_CLEAR_SELECTIONS))
return buf;
if ((flags & MENU_CREATE)) {
@@ -365,9 +368,10 @@ static char *menu_op(const struct menu_desc *d, char *buf,
icon |= (1<<22);
}
- if (e == d->n_entries - 1)
+ if (e == d->n_entries - 1) {
/* last item */
menuf |= 0x80;
+ }
if (charset != 0 && lut && lut[e] == charset) {
menuf |= 0x1;
@@ -382,12 +386,12 @@ static char *menu_op(const struct menu_desc *d, char *buf,
}
if ((flags & MENU_CREATE)) {
- *((int *)bp) = menuf; bp += 4;
- *((int *)bp) = -1; bp += 4;
- *((int *)bp) = icon; bp += 4;
- *((int *)bp) = (int)(dp); bp += 4;
- *((int *)bp) = (int)(*data); bp += 4;
- *((int *)bp) = strlen(pos) + 1; bp += 4;
+ *((int *)bp) = menuf; bp += 4;
+ *((int *)bp) = -1; bp += 4;
+ *((int *)bp) = icon; bp += 4;
+ *((int *)bp) = (intptr_t)(dp); bp += 4;
+ *((int *)bp) = (intptr_t)(*data); bp += 4;
+ *((int *)bp) = strlen(pos) + 1; bp += 4;
memcpy(dp, pos, strlen(pos) + 1);
dp += strlen(pos) + 1;
@@ -454,8 +458,8 @@ size_t iconv_createmenu(size_t flags, char *buf, size_t len,
return 0;
/* get required size */
- reqlen = (int)menu_op((const struct menu_desc *)&enc_menu, 0,
- NULL, 0, MENU_COUNT_SIZE, 0, NULL, &dp);
+ reqlen = (size_t)menu_op((const struct menu_desc *) (void *) &enc_menu,
+ 0, NULL, 0, MENU_COUNT_SIZE, 0, NULL, &dp);
datalen = (size_t)dp;
@@ -486,7 +490,7 @@ size_t iconv_createmenu(size_t flags, char *buf, size_t len,
#endif
dp = data;
- bp = menu_op((const struct menu_desc *)&enc_menu, buf,
+ bp = menu_op((const struct menu_desc *) (void *) &enc_menu, buf,
NULL, 0, MENU_CREATE, sel, NULL, &dp);
(*dlen) = datalen;
@@ -560,7 +564,7 @@ size_t iconv_decodemenu(size_t flags, void *menu, int *selections,
buf[strlen(text)] = '\0';
}
- menu_op((const struct menu_desc *)&enc_menu, menu, NULL, 0,
+ menu_op((const struct menu_desc *) (void *) &enc_menu, menu, NULL, 0,
MENU_CLEAR_SELECTIONS, s->lut[selections[1]],
NULL, NULL);
diff --git a/module/module.c b/module/module.c
index ef2a5da..c58c6f7 100644
--- a/module/module.c
+++ b/module/module.c
@@ -9,13 +9,15 @@
#include <iconv/iconv.h>
-#include "swis.h"
-
#include "errors.h"
#include "header.h"
#include "module.h"
+#ifdef __riscos__
#define ALIASES_FILE "Unicode:Files.Aliases"
+#else
+#define ALIASES_FILE "Aliases"
+#endif
static _kernel_oserror ErrorGeneric = { 0x0, "" };
@@ -61,7 +63,7 @@ _kernel_oserror *mod_fini(int fatal, int podule_base, void *pw)
/* SWI handler */
_kernel_oserror *swi_handler(int swi_off, _kernel_swi_regs *regs, void *pw)
{
- unsigned int ret;
+ intptr_t ret;
UNUSED(pw);
@@ -70,38 +72,42 @@ _kernel_oserror *swi_handler(int swi_off, _kernel_swi_regs *regs, void *pw)
switch (swi_off) {
case 0: /* Iconv_Open */
- if ((ret = (unsigned int)
+ if ((ret = (intptr_t)
iconv_open((const char*)regs->r[0],
(const char*)regs->r[1])) == -1) {
- ErrorGeneric.errnum = errno;
+ ErrorGeneric.errnum =
+ errno_to_iconv_error(errno);
return &ErrorGeneric;
}
regs->r[0] = ret;
break;
case 1: /* Iconv_Iconv */
- if ((ret = (unsigned int)
+ if ((ret = (intptr_t)
iconv((iconv_t)regs->r[0],
(char**)regs->r[1],
(size_t*)regs->r[2],
(char**)regs->r[3],
(size_t*)regs->r[4])) == -1) {
- ErrorGeneric.errnum = errno;
+ ErrorGeneric.errnum =
+ errno_to_iconv_error(errno);
return &ErrorGeneric;
}
regs->r[0] = ret;
break;
case 2: /* Iconv_Close */
- if ((ret = (unsigned int)
+ if ((ret = (intptr_t)
iconv_close((iconv_t)regs->r[0])) == -1) {
- ErrorGeneric.errnum = errno;
+ ErrorGeneric.errnum =
+ errno_to_iconv_error(errno);
return &ErrorGeneric;
}
regs->r[0] = ret;
break;
case 3: /* Iconv_Convert */
- if ((ret = (unsigned int)
+ if ((ret = (intptr_t)
iconv_convert(regs)) == -1) {
- ErrorGeneric.errnum = errno;
+ ErrorGeneric.errnum =
+ errno_to_iconv_error(errno);
return &ErrorGeneric;
}
regs->r[0] = ret;
@@ -167,10 +173,10 @@ size_t iconv_convert(_kernel_swi_regs *regs)
ret = iconv((iconv_t)regs->r[0], &inbuf, &inbytesleft,
&outbuf, &outbytesleft);
- regs->r[1] = (int)inbuf;
- regs->r[2] = (int)inbytesleft;
- regs->r[3] = (int)outbuf;
- regs->r[4] = (int)outbytesleft;
+ regs->r[1] = (intptr_t) inbuf;
+ regs->r[2] = (intptr_t) inbytesleft;
+ regs->r[3] = (intptr_t) outbuf;
+ regs->r[4] = (intptr_t) outbytesleft;
return ret;
}
@@ -186,7 +192,9 @@ int errno_to_iconv_error(int num)
return ICONV_ILSEQ;
case EINVAL:
default:
- return ICONV_INVAL:
+ break;
}
+
+ return ICONV_INVAL;
}
diff --git a/module/module.h b/module/module.h
index 09dcfeb..9236ffc 100644
--- a/module/module.h
+++ b/module/module.h
@@ -1,18 +1,8 @@
#ifndef iconv_module_h_
#define iconv_module_h_
-#ifndef DEBUG
-#define LOG(x)
-#else
-#define LOG(x) (printf(__FILE__ " %s %i: ", __func__, __LINE__), printf x, fputc('\n', stdout))
-#endif
-
-#define UNUSED(x) ((x) = (x))
-
-/* In iconv library */
-extern int iconv_eightbit_number_from_name(const char *name);
-extern short mibenum_from_name(const char *alias);
-extern const char *mibenum_to_name(short mibenum);
+/* Ugh. Include libiconv internal header so we get access to aliases stuff */
+#include "internal.h"
/* in menu.c */
size_t iconv_createmenu(size_t flags, char *buf, size_t buflen,
diff --git a/module/wrapper.c b/module/wrapper.c
new file mode 100644
index 0000000..1567f0c
--- /dev/null
+++ b/module/wrapper.c
@@ -0,0 +1,34 @@
+/* Wrapper around module API so we can run/test it on non-RO machines */
+
+#ifndef __riscos__
+
+#include <stdio.h>
+
+#include "header.h"
+
+int main(int argc, char **argv)
+{
+ _kernel_oserror *error;
+
+ if (argc != 1) {
+ printf("Usage: %s\n", argv[0]);
+ return 1;
+ }
+
+ error = mod_init(NULL, 0, NULL);
+ if (error != NULL) {
+ printf("mod_init: %s (%d)\n", error->errmess, error->errnum);
+ return 1;
+ }
+
+ error = mod_fini(0, 0, NULL);
+ if (error != NULL) {
+ printf("mod_fini: %s (%d)\n", error->errmess, error->errnum);
+ return 1;
+ }
+
+ return 0;
+}
+
+#endif
+