[gnumeric] Funcs: add textjoin.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Funcs: add textjoin.
- Date: Thu, 4 Aug 2016 14:07:59 +0000 (UTC)
commit 6b3c92d7448cb8a4a8a0d225bd6aa8c7392ba2ae
Author: Morten Welinder <terra gnome org>
Date: Thu Aug 4 10:07:28 2016 -0400
Funcs: add textjoin.
ChangeLog | 8 +++
NEWS | 1 +
doc/C/func.defs | 11 ++++
doc/C/functions.xml | 34 +++++++++++++
plugins/fn-string/functions.c | 85 ++++++++++++++++++++++++++++++++++
plugins/fn-string/plugin.xml.in | 1 +
plugins/openoffice/openoffice-read.c | 2 +
src/collect.c | 3 +-
src/collect.h | 3 +-
src/rangefunc-strings.c | 2 +-
src/rangefunc-strings.h | 2 +-
11 files changed, 148 insertions(+), 4 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 50977d3..ef27f03 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2016-08-04 Morten Welinder <terra gnome org>
+
+ * src/rangefunc-strings.c (range_concatenate): Add (unused) user
+ pointer.
+
+ * src/collect.c (string_range_function): Add user pointer. Caller
+ changed.
+
2016-06-29 Morten Welinder <terra gnome org>
* configure.ac: Post-release bump.
diff --git a/NEWS b/NEWS
index 8dd1a88..ef6d038 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Jean:
Morten:
* Avoid gnome-common dependency.
* New function CONCAT.
+ * New function TEXTJOIN.
--------------------------------------------------------------------------
Gnumeric 1.12.31
diff --git a/doc/C/func.defs b/doc/C/func.defs
index 81afa94..98322c5 100644
--- a/doc/C/func.defs
+++ b/doc/C/func.defs
@@ -6578,6 +6578,17 @@ The distinction between half-width and full-width characters is described in htt
@SEEALSO=DOLLAR,FIXED,VALUE
@CATEGORY=String
+@FUNCTION=TEXTJOIN
+@SHORTDESC=the concatenation of the strings @{s1}, @{s2},… delimited by @del
+@SYNTAX=TEXTJOIN(del,blank,s1,s2,…)
+@ARGUMENTDESCRIPTION=@{del}: delimiter
+@{blank}: ignore blanks
+@{s1}: first string
+@{s2}: second string
+@EXCEL=This function is Excel compatible.
+@SEEALSO=CONCATENATE
+
+@CATEGORY=String
@FUNCTION=TRIM
@SHORTDESC=@{text} with only single spaces between words
@SYNTAX=TRIM(text)
diff --git a/doc/C/functions.xml b/doc/C/functions.xml
index df64d13..a659648 100644
--- a/doc/C/functions.xml
+++ b/doc/C/functions.xml
@@ -22398,6 +22398,40 @@
</para>
</refsect1>
</refentry>
+ <refentry id="gnumeric-function-TEXTJOIN">
+ <refmeta>
+ <refentrytitle>
+ <function>TEXTJOIN</function>
+ </refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>
+ <function>TEXTJOIN</function>
+ </refname>
+ <refpurpose>
+ the concatenation of the strings <parameter>s1</parameter>, <parameter>s2</parameter>,… delimited by
<parameter>del</parameter>
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+
<synopsis><function>TEXTJOIN</function>(<parameter>del</parameter>,<parameter>blank</parameter>,<parameter>s1</parameter>,<parameter>s2</parameter>,<parameter/>…)</synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments</title>
+ <para><parameter>del</parameter>: delimiter</para>
+ <para><parameter>blank</parameter>: ignore blanks</para>
+ <para><parameter>s1</parameter>: first string</para>
+ <para><parameter>s2</parameter>: second string</para>
+ </refsect1>
+ <refsect1>
+ <title>Microsoft Excel Compatibility</title>
+ <para>This function is Excel compatible.</para>
+ </refsect1>
+ <refsect1>
+ <title>See also</title>
+ <para><link linkend="gnumeric-function-CONCATENATE"><function>CONCATENATE</function></link>.
+ </para>
+ </refsect1>
+ </refentry>
<refentry id="gnumeric-function-TRIM">
<refmeta>
<refentrytitle>
diff --git a/plugins/fn-string/functions.c b/plugins/fn-string/functions.c
index c627065..575a181 100644
--- a/plugins/fn-string/functions.c
+++ b/plugins/fn-string/functions.c
@@ -616,6 +616,7 @@ gnumeric_concatenate (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv
{
return string_range_function (argc, argv, ei,
range_concatenate,
+ NULL,
COLLECT_IGNORE_BLANKS,
GNM_ERROR_VALUE);
}
@@ -639,6 +640,87 @@ gnumeric_concat (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
/***************************************************************************/
+static GnmFuncHelp const help_textjoin[] = {
+ { GNM_FUNC_HELP_NAME, F_("TEXTJOIN:the concatenation of the strings @{s1}, @{s2},\xe2\x80\xa6
delimited by @del")},
+ { GNM_FUNC_HELP_ARG, F_("del:delimiter")},
+ { GNM_FUNC_HELP_ARG, F_("blank:ignore blanks")},
+ { GNM_FUNC_HELP_ARG, F_("s1:first string")},
+ { GNM_FUNC_HELP_ARG, F_("s2:second string")},
+ { GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
+ { GNM_FUNC_HELP_EXAMPLES, "=TEXTJOIN(\"::\",FALSE,\"aa\",\"bb\")" },
+ { GNM_FUNC_HELP_SEEALSO, "CONCATENATE"},
+ { GNM_FUNC_HELP_END}
+};
+
+struct cb_textjoin {
+ char *delim;
+ gboolean ignore_blanks;
+};
+
+static int
+range_textjoin (GPtrArray *data, char **pres, gpointer user_)
+{
+ struct cb_textjoin *user = user_;
+ GString *res = g_string_new (NULL);
+ gboolean first = TRUE;
+ unsigned ui;
+
+ for (ui = 0; ui < data->len; ui++) {
+ const char *s = g_ptr_array_index (data, ui);
+
+ if (s[0] == 0 && user->ignore_blanks)
+ continue;
+
+ if (first)
+ first = FALSE;
+ else
+ g_string_append (res, user->delim);
+
+ g_string_append (res, s);
+ }
+
+ *pres = g_string_free (res, FALSE);
+ return 0;
+}
+
+static GnmValue *
+gnumeric_textjoin (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
+{
+ GnmValue *v;
+ gboolean err;
+ struct cb_textjoin data;
+
+ data.delim = NULL;
+
+ if (argc < 3)
+ return value_new_error_VALUE (ei->pos);
+
+ v = gnm_expr_eval (argv[0], ei->pos, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+ if (VALUE_IS_ERROR (v))
+ goto done;
+ data.delim = value_get_as_string (v);
+ value_release (v);
+
+ v = gnm_expr_eval (argv[1], ei->pos, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+ if (VALUE_IS_ERROR (v))
+ goto done;
+ data.ignore_blanks = value_get_as_bool (v, &err); // What about err?
+ value_release (v);
+
+ v = string_range_function (argc - 2, argv + 2, ei,
+ range_textjoin,
+ &data,
+ data.ignore_blanks ? COLLECT_IGNORE_BLANKS : 0,
+ GNM_ERROR_VALUE);
+
+done:
+ g_free (data.delim);
+
+ return v;
+}
+
+/***************************************************************************/
+
static GnmFuncHelp const help_rept[] = {
{ GNM_FUNC_HELP_NAME, F_("REPT:@{num} repetitions of string @{text}")},
{ GNM_FUNC_HELP_ARG, F_("text:string")},
@@ -1771,6 +1853,9 @@ GnmFuncDescriptor const string_functions[] = {
{ "text", "Ss", help_text,
gnumeric_text, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
+ { "textjoin", NULL, help_textjoin,
+ NULL, gnumeric_textjoin, NULL, NULL,
+ GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
{ "trim", "S", help_trim,
gnumeric_trim, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
diff --git a/plugins/fn-string/plugin.xml.in b/plugins/fn-string/plugin.xml.in
index 342822a..9a55792 100644
--- a/plugins/fn-string/plugin.xml.in
+++ b/plugins/fn-string/plugin.xml.in
@@ -42,6 +42,7 @@
<function name="substitute"/>
<function name="t"/>
<function name="text"/>
+ <function name="textjoin"/>
<function name="trim"/>
<function name="unichar"/>
<function name="unicode"/>
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 00564d2..1a9096f 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -12918,6 +12918,7 @@ oo_func_map_in (GnmConventions const *convs, Workbook *scope,
{ "CHISQ.INV","R.QCHISQ" },
{ "CHISQ.INV.RT","CHIINV" },
{ "CHISQ.TEST","CHITEST" },
+ { "CONCAT", "CONCAT" },
{ "CONFIDENCE.NORM","CONFIDENCE" },
{ "CONFIDENCE.T","CONFIDENCE.T" },
{ "COVARIANCE.P","COVAR" },
@@ -12950,6 +12951,7 @@ oo_func_map_in (GnmConventions const *convs, Workbook *scope,
{ "T.INV","R.QT" },
{ "T.INV.2T","TINV" },
{ "T.TEST","TTEST" },
+ { "TEXTJOIN", "TEXTJOIN" },
{ "VAR.S","VAR" },
{ "VAR.P","VARP" },
{ "WEIBULL.DIST","WEIBULL" },
diff --git a/src/collect.c b/src/collect.c
index 88dc8d0..381ef1e 100644
--- a/src/collect.c
+++ b/src/collect.c
@@ -1036,6 +1036,7 @@ GnmValue *
string_range_function (int argc, GnmExprConstPtr const *argv,
GnmFuncEvalInfo *ei,
string_range_function_t func,
+ gpointer user,
CollectFlags flags,
GnmStdError func_error)
{
@@ -1048,7 +1049,7 @@ string_range_function (int argc, GnmExprConstPtr const *argv,
if (!vals)
return error;
- err = func (vals, &res);
+ err = func (vals, &res, user);
collect_strings_free (vals);
diff --git a/src/collect.h b/src/collect.h
index 413f827..17f68d2 100644
--- a/src/collect.h
+++ b/src/collect.h
@@ -33,7 +33,7 @@ typedef enum {
typedef int (*float_range_function_t) (gnm_float const *xs, int n, gnm_float *res);
typedef int (*float_range_function2_t) (gnm_float const *xs, gnm_float const *ys, int n, gnm_float *res);
typedef int (*float_range_function2d_t) (gnm_float const *xs, gnm_float const *ys, int n, gnm_float *res,
gpointer data);
-typedef int (*string_range_function_t) (GPtrArray *xs, char**res);
+typedef int (*string_range_function_t) (GPtrArray *xs, char**res, gpointer user);
gnm_float *collect_floats_value (GnmValue const *val,
GnmEvalPos const *ep,
@@ -75,6 +75,7 @@ GnmValue *float_range_function2d (GnmValue const *val0, GnmValue const *val1,
GnmValue *string_range_function (int argc, GnmExprConstPtr const *argv,
GnmFuncEvalInfo *ei,
string_range_function_t func,
+ gpointer user,
CollectFlags flags,
GnmStdError func_error);
diff --git a/src/rangefunc-strings.c b/src/rangefunc-strings.c
index 5034620..86fe7d1 100644
--- a/src/rangefunc-strings.c
+++ b/src/rangefunc-strings.c
@@ -19,7 +19,7 @@
* Returns: non-zero on error.
*/
int
-range_concatenate (GPtrArray *data, char **res)
+range_concatenate (GPtrArray *data, char **res, gpointer user)
{
unsigned ui;
size_t len = 0;
diff --git a/src/rangefunc-strings.h b/src/rangefunc-strings.h
index ffbedb0..7f6f47d 100644
--- a/src/rangefunc-strings.h
+++ b/src/rangefunc-strings.h
@@ -6,7 +6,7 @@
G_BEGIN_DECLS
-int range_concatenate (GPtrArray *data, char **res);
+int range_concatenate (GPtrArray *data, char **res, gpointer user);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]