diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | card2ord.c | 79 | ||||
-rw-r--r-- | common.h | 10 | ||||
-rw-r--r-- | numtext-strip.c | 2 | ||||
-rw-r--r-- | numtext.c | 68 | ||||
-rw-r--r-- | swedish.c | 4 |
7 files changed, 159 insertions, 6 deletions
@@ -17,6 +17,7 @@ LANG =\ swedish CMD =\ + card2ord\ numtext-strip LIB_OBJ =\ @@ -1,5 +1,4 @@ Add [libnumtext_]text2num: text to numerals, with analysis (possible flags from num2text), use support mixed in numerals -Add card2ord: conversion utility that wraps libnumtext_card2ord Add num2text: conversion utility that wraps libnumtext_num2text Add opposite of libnumtext_remove_separators and numtext-strip Add man pages and README diff --git a/card2ord.c b/card2ord.c new file mode 100644 index 0000000..632e6a1 --- /dev/null +++ b/card2ord.c @@ -0,0 +1,79 @@ +/* See LICENSE file for copyright and license details. */ +#define LIBSIMPLY_CONFIG_MULTICALL_BINARY +#include "common.h" +#include <libsimple-arg.h> + +USAGE("-l language [-o options ...] [cardinal ...]"); + + +static enum libnumtext_language lang; +static uint32_t flags = 0; + + +static struct option swedish_options[] = { + {"gender=c[ommon]|u|t", "gender=common", LIBNUMTEXT_C2O_SWEDISH_COMMON_GENDER, UINT32_C(0x00000003)}, + {NULL, "gender=c", LIBNUMTEXT_C2O_SWEDISH_COMMON_GENDER, UINT32_C(0x00000003)}, + {NULL, "gender=u", LIBNUMTEXT_C2O_SWEDISH_COMMON_GENDER, UINT32_C(0x00000003)}, + {NULL, "gender=t", LIBNUMTEXT_C2O_SWEDISH_COMMON_GENDER, UINT32_C(0x00000003)}, + {"gender=n[euter]", "gender=neuter", LIBNUMTEXT_C2O_SWEDISH_NEUTER_GENDER, UINT32_C(0x00000003)}, + {NULL, "gender=n", LIBNUMTEXT_C2O_SWEDISH_NEUTER_GENDER, UINT32_C(0x00000003)}, + {"gender=m[asculine]", "gender=masculine", LIBNUMTEXT_C2O_SWEDISH_MASCULINE_GENDER, UINT32_C(0x00000003)}, + {NULL, "gender=m", LIBNUMTEXT_C2O_SWEDISH_MASCULINE_GENDER, UINT32_C(0x00000003)}, + {"gender=f[eminine]", "gender=feminine", LIBNUMTEXT_C2O_SWEDISH_FEMININE_GENDER, UINT32_C(0x00000003)}, + {NULL, "gender=f", LIBNUMTEXT_C2O_SWEDISH_FEMININE_GENDER, UINT32_C(0x00000003)}, + {"case=l[ower]", "case=lower", LIBNUMTEXT_C2O_SWEDISH_LOWER_CASE, UINT32_C(0x00000004)}, + {NULL, "case=l", LIBNUMTEXT_C2O_SWEDISH_LOWER_CASE, UINT32_C(0x00000004)}, + {"case=u[pper]", "case=upper", LIBNUMTEXT_C2O_SWEDISH_UPPER_CASE, UINT32_C(0x00000004)}, + {NULL, "case=u", LIBNUMTEXT_C2O_SWEDISH_UPPER_CASE, UINT32_C(0x00000004)}, + {NULL, NULL, 0, 0} +}; + +static struct option *options[] = { + [LIBNUMTEXT_SWEDISH] = swedish_options +}; + + +static ssize_t +process(char *outbuf, size_t outbuf_size, const char *num, size_t num_len) +{ + ssize_t ret; + ret = libnumtext_card2ord(outbuf, outbuf_size, num, num_len, lang, flags); + if (ret < 0) + fprintf(stderr, "%s: libnumtext_card2ord %s: %s\n", argv0, num, strerror(errno)); + return ret; +} + + +int +card2ord_main(int argc, char *argv[]) +{ + int have_lang = 0; + char **optionses; + size_t n_optionses = 0; + + optionses = calloc((size_t)argc, sizeof(optionses)); + if (!optionses) { + fprintf(stderr, "%s: calloc %zu %zu: %s\n", argv0, (size_t)argc, sizeof(optionses), strerror(errno)); + return 1; + } + + ARGBEGIN { + case 'l': + if (!get_language(ARG(), &lang, &have_lang)) + usage(); + break; + case 'o': + optionses[n_optionses++] = ARG(); + break; + default: + usage(); + } ARGEND; + + if (!have_lang) + usage(); + + process_options(optionses, n_optionses, options[lang], &flags, NULL); + free(optionses); + + return run(argc, argv, process); +} @@ -49,10 +49,20 @@ struct common_num2text_params { }; +struct option { + const char *option_pattern; + const char *option; + uint32_t flag; + uint32_t mask; +}; + + int run(int argc, char *argv[], ssize_t (*callback)(char *outbuf, size_t outbuf_size, const char *num, size_t num_len)); int get_language(const char *arg, enum libnumtext_language *langp, int *have_langp); +void process_options(char **optss, size_t n_optss, struct option *options, uint32_t *flagsp, uint32_t *maskedp); int numtext_strip_main(int argc, char *argv[]); +int card2ord_main(int argc, char *argv[]); ssize_t libnumtext_num2text_swedish__(struct common_num2text_params *params, const char *num, size_t num_len, uint32_t flags); diff --git a/numtext-strip.c b/numtext-strip.c index 5ebe2ff..85719af 100644 --- a/numtext-strip.c +++ b/numtext-strip.c @@ -3,7 +3,7 @@ #include "common.h" #include <libsimple-arg.h> -USAGE("-l language"); +USAGE("-l language [number ...]"); static enum libnumtext_language lang; @@ -13,8 +13,13 @@ main(int argc, char *argv[]) return 1; } - if (!strcmp(argv[0], "numtext-strip")) + argv0 = strrchr(argv[0], '/'); + argv0 = argv0 ? &argv0[1] : argv[0]; + + if (!strcmp(argv0, "numtext-strip")) return numtext_strip_main(argc, argv); + else if (!strcmp(argv0, "card2ord")) + return card2ord_main(argc, argv); fprintf(stderr, "%s: not a recognised command for numtext multicall binary\n", argv[0]); return 1; @@ -120,10 +125,9 @@ get_language(const char *arg, enum libnumtext_language *langp, int *have_langp) *have_langp = 1; if (!strcmp(arg, "?")) { - for (i = 0; i < sizeof(languages) / sizeof(*languages); i++) { - printf("Languages:\n"); + printf("Languages:\n"); + for (i = 0; i < sizeof(languages) / sizeof(*languages); i++) printf("\t%s %s\n", languages[i].code, languages[i].name); - } exit(0); } else { for (i = 0; i < sizeof(languages) / sizeof(*languages); i++) { @@ -136,3 +140,59 @@ get_language(const char *arg, enum libnumtext_language *langp, int *have_langp) exit(1); } } + + +static char * +process_option(char *opt, struct option *options, uint32_t *flagsp, uint32_t *maskedp) +{ + size_t len; + + if (opt[0] == '?' && (!opt[1] || opt[1] == ',')) { + printf("Options:\n"); + for (; options->option; options++) + if (options->option_pattern) + printf("\t%s\n", options->option_pattern); + exit(0); + } + + for (; options->option; options++) { + len = strlen(options->option); + if (!strncmp(opt, options->option, len) && (!opt[len] || opt[len] == ',')) { + if (options->mask & *maskedp) { + fprintf(stderr, "%s: option conflicts with previously specified option: %.*s\n", argv0, (int)len, opt); + exit(1); + } + *flagsp |= options->flag; + *maskedp |= options->mask; + return &opt[len]; + } + } + + fprintf(stderr, "%s: unrecognised option for selected language, use ? to list available options: %s\n", argv0, opt); + exit(1); +} + +void +process_options(char **optss, size_t n_optss, struct option *options, uint32_t *flagsp, uint32_t *maskedp) +{ + uint32_t _masked; + char *opts; + size_t i; + + if (!maskedp) + maskedp = &_masked; + *flagsp = 0; + *maskedp = 0; + + for (i = 0; i < n_optss; i++) { + opts = optss[i]; + for (;;) { + while (*opts == ',') + opts = &opts[1]; + if (!*opts) + break; + else + opts = process_option(opts, options, flagsp, maskedp); + } + } +} @@ -639,6 +639,10 @@ libnumtext_card2ord_swedish__(char *outbuf, size_t outbuf_size, const char *num, } length += 1; + if (outbuf_size) + outbuf[length < outbuf_size ? length : outbuf_size] = '\0'; + length += 1; + return (ssize_t)length; einval: |