diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2008-11-11 05:09:51 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2008-11-11 05:09:51 +0000 |
commit | 42de9db2762a63f69321fc4e89ea81e16a5a206a (patch) | |
tree | fbff2a9f70f8a2792d134f5a9dc60d11b2ee0a08 /module | |
parent | b5aa13a47b66955a5198da1f88e1f93f09306a84 (diff) | |
download | iconv-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/Makefile | 103 | ||||
-rw-r--r-- | module/header.h | 126 | ||||
-rw-r--r-- | module/kernel.h | 19 | ||||
-rw-r--r-- | module/menu.c | 62 | ||||
-rw-r--r-- | module/module.c | 40 | ||||
-rw-r--r-- | module/module.h | 14 | ||||
-rw-r--r-- | module/wrapper.c | 34 |
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 + |