summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-09-10 17:33:40 +0200
committerMattias Andrée <maandree@kth.se>2021-09-10 17:33:52 +0200
commit9279dbb2741de7bc599699a95728b1b7c2b6790a (patch)
treec09d02cdaeff78be8f6a89d49014a3640bec870c
parentAdd multicall binary (diff)
downloadlibnumtext-9279dbb2741de7bc599699a95728b1b7c2b6790a.tar.gz
libnumtext-9279dbb2741de7bc599699a95728b1b7c2b6790a.tar.bz2
libnumtext-9279dbb2741de7bc599699a95728b1b7c2b6790a.tar.xz
m + add card2ord
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile1
-rw-r--r--TODO1
-rw-r--r--card2ord.c79
-rw-r--r--common.h10
-rw-r--r--numtext-strip.c2
-rw-r--r--numtext.c68
-rw-r--r--swedish.c4
7 files changed, 159 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index b1a70f6..eb187ed 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ LANG =\
swedish
CMD =\
+ card2ord\
numtext-strip
LIB_OBJ =\
diff --git a/TODO b/TODO
index 2b07738..8e94350 100644
--- a/TODO
+++ b/TODO
@@ -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);
+}
diff --git a/common.h b/common.h
index 978103a..1404b35 100644
--- a/common.h
+++ b/common.h
@@ -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;
diff --git a/numtext.c b/numtext.c
index cd07e63..3b78756 100644
--- a/numtext.c
+++ b/numtext.c
@@ -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);
+ }
+ }
+}
diff --git a/swedish.c b/swedish.c
index 4fec515..b4b1207 100644
--- a/swedish.c
+++ b/swedish.c
@@ -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: