public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] Modify strnstr.c.
@ 2017-08-30  3:04 Sichen Zhao
  2017-08-30 13:35 ` [PATCH] Add man page entry for strnstr.c Sichen Zhao
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Sichen Zhao @ 2017-08-30  3:04 UTC (permalink / raw)
  To: newlib; +Cc: gedare, joel, christian.mauderer, sebastian.huber, Sichen Zhao

---
 newlib/libc/string/strnstr.c | 65 +++++++-------------------------------------
 1 file changed, 10 insertions(+), 55 deletions(-)

diff --git a/newlib/libc/string/strnstr.c b/newlib/libc/string/strnstr.c
index da5e5bd..05d86ee 100644
--- a/newlib/libc/string/strnstr.c
+++ b/newlib/libc/string/strnstr.c
@@ -1,42 +1,5 @@
-/*-
- * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strstr.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/strnstr.c 251069 2013-05-28 20:57:40Z emaste $");
-
+#undef __STRICT_ANSI__
+#include <_ansi.h>
 #include <string.h>
 
 /*
@@ -44,22 +7,14 @@ __FBSDID("$FreeBSD: head/lib/libc/string/strnstr.c 251069 2013-05-28 20:57:40Z e
  * first slen characters of s.
  */
 char *
-strnstr(const char *s, const char *find, size_t slen)
+strnstr(const char *haystack, const char *needle, size_t haystack_len)
 {
-	char c, sc;
-	size_t len;
+  size_t needle_len = strnlen(needle, haystack_len);
 
-	if ((c = *find++) != '\0') {
-		len = strlen(find);
-		do {
-			do {
-				if (slen-- < 1 || (sc = *s++) == '\0')
-					return (NULL);
-			} while (sc != c);
-			if (len > slen)
-				return (NULL);
-		} while (strncmp(s, find, len) != 0);
-		s--;
-	}
-	return ((char *)s);
+  if (needle_len < haystack_len || !needle[needle_len]) {
+    char *x = memmem(haystack, haystack_len, needle, needle_len);
+    if (x && !memchr(haystack, 0, x - haystack))
+      return x;
+  }
+  return NULL;
 }
-- 
2.7.4



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] Add man page entry for strnstr.c.
  2017-08-30  3:04 [PATCH v2] Modify strnstr.c Sichen Zhao
@ 2017-08-30 13:35 ` Sichen Zhao
  2017-08-30 14:59   ` Craig Howland
  2017-08-30 14:19 ` [PATCH v2] Modify strnstr.c Corinna Vinschen
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Sichen Zhao @ 2017-08-30 13:35 UTC (permalink / raw)
  To: newlib; +Cc: gedare, joel, christian.mauderer, sebastian.huber, Sichen Zhao

---
 newlib/libc/string/strings.tex |  4 ++++
 newlib/libc/string/strnstr.c   | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/newlib/libc/string/strings.tex b/newlib/libc/string/strings.tex
index c619886..6aec5fe 100644
--- a/newlib/libc/string/strings.tex
+++ b/newlib/libc/string/strings.tex
@@ -40,6 +40,7 @@ managing areas of memory.  The corresponding declarations are in
 * strncat::     Concatenate strings
 * strncmp::     Character string compare
 * strncpy::     Counted copy string
+* strnstr::     Find string segment
 * strnlen::     Character string length
 * strpbrk::     Find chars in string
 * strrchr::     Reverse search for character in string
@@ -159,6 +160,9 @@ managing areas of memory.  The corresponding declarations are in
 @include string/strncpy.def
 
 @page
+@include string/strnstr.def
+
+@page
 @include string/strnlen.def
 
 @page
diff --git a/newlib/libc/string/strnstr.c b/newlib/libc/string/strnstr.c
index 05d86ee..fe3da6e 100644
--- a/newlib/libc/string/strnstr.c
+++ b/newlib/libc/string/strnstr.c
@@ -1,3 +1,42 @@
+/* 
+FUNCTION
+	<<strnstr>>---find string segment
+	
+INDEX
+	strnstr
+
+ANSI_SYNOPSIS
+	#include <string.h>
+	size_t strnstr(const char *<[s1]>, const char *<[s2]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+	#include <string.h>
+	size_t strnstr(<[s1]>, <[s2]>, <[n]>)
+	char *<[s1]>;
+        char *<[s2]>;
+	size_t <[n]>;
+
+DESCRIPTION
+	Locates the first occurrence in the string pointed to by <[s1]> of
+	the sequence of limited to the <[n]> characters in the string
+        pointed to by <[s2]>
+
+RETURNS
+	Returns a pointer to the located string segment, or a null
+	pointer if the string <[s2]> is not found. If <[s2]> points to
+	a string with zero length, <[s1]> is returned.
+
+
+PORTABILITY
+<<strnstr>> is ANSI C.
+
+<<strnstr>> requires no supporting OS subroutines.
+
+QUICKREF
+	strnstr ansi pure
+
+*/
+
 #undef __STRICT_ANSI__
 #include <_ansi.h>
 #include <string.h>
-- 
2.7.4



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] Modify strnstr.c.
  2017-08-30  3:04 [PATCH v2] Modify strnstr.c Sichen Zhao
  2017-08-30 13:35 ` [PATCH] Add man page entry for strnstr.c Sichen Zhao
@ 2017-08-30 14:19 ` Corinna Vinschen
  2017-09-04  9:04   ` Sichen Zhao
  2017-08-30 15:04 ` Craig Howland
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Corinna Vinschen @ 2017-08-30 14:19 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 384 bytes --]

On Aug 30 11:03, Sichen Zhao wrote:
> ---
>  newlib/libc/string/strnstr.c | 65 +++++++-------------------------------------
>  1 file changed, 10 insertions(+), 55 deletions(-)

Patchset pushed.

Would you mind to send patchsets as numbered git patchsets in future?
`git format-patch' is a big help.


Thanks,
Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Add man page entry for strnstr.c.
  2017-08-30 13:35 ` [PATCH] Add man page entry for strnstr.c Sichen Zhao
@ 2017-08-30 14:59   ` Craig Howland
  0 siblings, 0 replies; 8+ messages in thread
From: Craig Howland @ 2017-08-30 14:59 UTC (permalink / raw)
  To: newlib

On 08/29/2017 11:03 PM, Sichen Zhao wrote:
> ---
>   newlib/libc/string/strings.tex |  4 ++++
>   newlib/libc/string/strnstr.c   | 39 +++++++++++++++++++++++++++++++++++++++
>   2 files changed, 43 insertions(+)
>
> diff --git a/newlib/libc/string/strings.tex b/newlib/libc/string/strings.tex
> index c619886..6aec5fe 100644
> ...
>   
>   @page
> diff --git a/newlib/libc/string/strnstr.c b/newlib/libc/string/strnstr.c
> index 05d86ee..fe3da6e 100644
> --- a/newlib/libc/string/strnstr.c
> +++ b/newlib/libc/string/strnstr.c
> @@ -1,3 +1,42 @@
> ...
> +
> +TRAD_SYNOPSIS
> +	#include <string.h>
> +	size_t strnstr(<[s1]>, <[s2]>, <[n]>)
> +	char *<[s1]>;
> +        char *<[s2]>;
> +	size_t <[n]>;
You can leave out the TRAD_SYNOPSIS section, as it is has been ignored by the 
document-generation tools for years.
> +
> +DESCRIPTION
> +	Locates the first occurrence in the string pointed to by <[s1]> of
> +	the sequence of limited to the <[n]> characters in the string
> +        pointed to by <[s2]>
As I read this, is it saying that is looks for at most n characters of s2 within 
s1.  However, this disagrees with the description in the source just before the 
function, itself, which says "Find the first occurrence of find in s, where the 
search is limited to the first slen characters of s."
> +
> +RETURNS
> +	Returns a pointer to the located string segment, or a null
> +	pointer if the string <[s2]> is not found. If <[s2]> points to
> +	a string with zero length, <[s1]> is returned.
> +
> +
> +PORTABILITY
> +<<strnstr>> is ANSI C.
> +
> +<<strnstr>> requires no supporting OS subroutines.
> +
> +QUICKREF
> +	strnstr ansi pure
strnstr() is not ANSI C.  (According to the gate in the header when added, it is 
BSD.)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] Modify strnstr.c.
  2017-08-30  3:04 [PATCH v2] Modify strnstr.c Sichen Zhao
  2017-08-30 13:35 ` [PATCH] Add man page entry for strnstr.c Sichen Zhao
  2017-08-30 14:19 ` [PATCH v2] Modify strnstr.c Corinna Vinschen
@ 2017-08-30 15:04 ` Craig Howland
  2017-09-10  4:04 ` Brian Inglis
  2017-09-10  4:27 ` Brian Inglis
  4 siblings, 0 replies; 8+ messages in thread
From: Craig Howland @ 2017-08-30 15:04 UTC (permalink / raw)
  To: newlib

On 08/29/2017 11:03 PM, Sichen Zhao wrote:
>   char *
> -strnstr(const char *s, const char *find, size_t slen)
> +strnstr(const char *haystack, const char *needle, size_t haystack_len)
>
This change to the function prototype makes it mismatch the preceding comment 
which summarizes the function:
/*
  * Find the first occurrence of find in s, where the search is limited to the
  * first slen characters of s.
  */
While it obviously works either way, the former names are the more common way to 
refer to these things, so while the comment can obviously be changed to match 
the prototype, keeping the original names seems more appropriate.
Craig

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] Modify strnstr.c.
  2017-08-30 14:19 ` [PATCH v2] Modify strnstr.c Corinna Vinschen
@ 2017-09-04  9:04   ` Sichen Zhao
  0 siblings, 0 replies; 8+ messages in thread
From: Sichen Zhao @ 2017-09-04  9:04 UTC (permalink / raw)
  To: newlib

> On Aug 30 11:03, Sichen Zhao wrote:
>> ---
>>   newlib/libc/string/strnstr.c | 65 +++++++-------------------------------------
>>   1 file changed, 10 insertions(+), 55 deletions(-)
> Patchset pushed.
>
> Would you mind to send patchsets as numbered git patchsets in future?
> `git format-patch' is a big help.
Ok, got it.
>
>
> Thanks,
> Corinna
>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] Modify strnstr.c.
  2017-08-30  3:04 [PATCH v2] Modify strnstr.c Sichen Zhao
                   ` (2 preceding siblings ...)
  2017-08-30 15:04 ` Craig Howland
@ 2017-09-10  4:04 ` Brian Inglis
  2017-09-10  4:27 ` Brian Inglis
  4 siblings, 0 replies; 8+ messages in thread
From: Brian Inglis @ 2017-09-10  4:04 UTC (permalink / raw)
  To: newlib

On 2017-08-29 21:03, Sichen Zhao wrote:
> ---
>  newlib/libc/string/strnstr.c | 65 +++++++-------------------------------------
>  1 file changed, 10 insertions(+), 55 deletions(-)
> 
> diff --git a/newlib/libc/string/strnstr.c b/newlib/libc/string/strnstr.c
> index da5e5bd..05d86ee 100644
> --- a/newlib/libc/string/strnstr.c
> +++ b/newlib/libc/string/strnstr.c
> @@ -1,42 +1,5 @@
> -/*-
> - * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
> - * Copyright (c) 1990, 1993
> - *	The Regents of the University of California.  All rights reserved.
> - *
> - * This code is derived from software contributed to Berkeley by
> - * Chris Torek.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - * 1. Redistributions of source code must retain the above copyright
> - *    notice, this list of conditions and the following disclaimer.
> - * 2. Redistributions in binary form must reproduce the above copyright
> - *    notice, this list of conditions and the following disclaimer in the
> - *    documentation and/or other materials provided with the distribution.
> - * 3. Neither the name of the University nor the names of its contributors
> - *    may be used to endorse or promote products derived from this software
> - *    without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
> - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
> - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> - * SUCH DAMAGE.
> - */
> -
> -#if defined(LIBC_SCCS) && !defined(lint)
> -static char sccsid[] = "@(#)strstr.c	8.1 (Berkeley) 6/4/93";
> -#endif /* LIBC_SCCS and not lint */
> -#include <sys/cdefs.h>
> -__FBSDID("$FreeBSD: head/lib/libc/string/strnstr.c 251069 2013-05-28 20:57:40Z emaste $");
> -
> +#undef __STRICT_ANSI__
> +#include <_ansi.h>
>  #include <string.h>
>  
>  /*
> @@ -44,22 +7,14 @@ __FBSDID("$FreeBSD: head/lib/libc/string/strnstr.c 251069 2013-05-28 20:57:40Z e
>   * first slen characters of s.
>   */
>  char *
> -strnstr(const char *s, const char *find, size_t slen)
> +strnstr(const char *haystack, const char *needle, size_t haystack_len)
>  {
> -	char c, sc;
> -	size_t len;
> +  size_t needle_len = strnlen(needle, haystack_len);
>  
> -	if ((c = *find++) != '\0') {
> -		len = strlen(find);
> -		do {
> -			do {
> -				if (slen-- < 1 || (sc = *s++) == '\0')
> -					return (NULL);
> -			} while (sc != c);
> -			if (len > slen)
> -				return (NULL);
> -		} while (strncmp(s, find, len) != 0);
> -		s--;
> -	}
> -	return ((char *)s);
> +  if (needle_len < haystack_len || !needle[needle_len]) {
> +    char *x = memmem(haystack, haystack_len, needle, needle_len);
> +    if (x && !memchr(haystack, 0, x - haystack))
> +      return x;
> +  }
> +  return NULL;
>  }

Getting memmem undefined building Cygwin from git latest.

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] Modify strnstr.c.
  2017-08-30  3:04 [PATCH v2] Modify strnstr.c Sichen Zhao
                   ` (3 preceding siblings ...)
  2017-09-10  4:04 ` Brian Inglis
@ 2017-09-10  4:27 ` Brian Inglis
  4 siblings, 0 replies; 8+ messages in thread
From: Brian Inglis @ 2017-09-10  4:27 UTC (permalink / raw)
  To: newlib

On 2017-08-29 21:03, Sichen Zhao wrote:
> ---
>  newlib/libc/string/strnstr.c | 65 +++++++-------------------------------------
>  1 file changed, 10 insertions(+), 55 deletions(-)
> 
> diff --git a/newlib/libc/string/strnstr.c b/newlib/libc/string/strnstr.c
> index da5e5bd..05d86ee 100644
> --- a/newlib/libc/string/strnstr.c
> +++ b/newlib/libc/string/strnstr.c
> @@ -1,42 +1,5 @@
> -/*-
> - * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
> - * Copyright (c) 1990, 1993
> - *	The Regents of the University of California.  All rights reserved.
> - *
> - * This code is derived from software contributed to Berkeley by
> - * Chris Torek.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - * 1. Redistributions of source code must retain the above copyright
> - *    notice, this list of conditions and the following disclaimer.
> - * 2. Redistributions in binary form must reproduce the above copyright
> - *    notice, this list of conditions and the following disclaimer in the
> - *    documentation and/or other materials provided with the distribution.
> - * 3. Neither the name of the University nor the names of its contributors
> - *    may be used to endorse or promote products derived from this software
> - *    without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
> - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
> - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> - * SUCH DAMAGE.
> - */
> -
> -#if defined(LIBC_SCCS) && !defined(lint)
> -static char sccsid[] = "@(#)strstr.c	8.1 (Berkeley) 6/4/93";
> -#endif /* LIBC_SCCS and not lint */
> -#include <sys/cdefs.h>
> -__FBSDID("$FreeBSD: head/lib/libc/string/strnstr.c 251069 2013-05-28 20:57:40Z emaste $");
> -
> +#undef __STRICT_ANSI__
> +#include <_ansi.h>
>  #include <string.h>
>  
>  /*
> @@ -44,22 +7,14 @@ __FBSDID("$FreeBSD: head/lib/libc/string/strnstr.c 251069 2013-05-28 20:57:40Z e
>   * first slen characters of s.
>   */
>  char *
> -strnstr(const char *s, const char *find, size_t slen)
> +strnstr(const char *haystack, const char *needle, size_t haystack_len)
>  {
> -	char c, sc;
> -	size_t len;
> +  size_t needle_len = strnlen(needle, haystack_len);
>  
> -	if ((c = *find++) != '\0') {
> -		len = strlen(find);
> -		do {
> -			do {
> -				if (slen-- < 1 || (sc = *s++) == '\0')
> -					return (NULL);
> -			} while (sc != c);
> -			if (len > slen)
> -				return (NULL);
> -		} while (strncmp(s, find, len) != 0);
> -		s--;
> -	}
> -	return ((char *)s);
> +  if (needle_len < haystack_len || !needle[needle_len]) {
> +    char *x = memmem(haystack, haystack_len, needle, needle_len);
> +    if (x && !memchr(haystack, 0, x - haystack))
> +      return x;
> +  }
> +  return NULL;
>  }

Getting memmem undefined building Cygwin from git latest.

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-09-10  4:04 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-30  3:04 [PATCH v2] Modify strnstr.c Sichen Zhao
2017-08-30 13:35 ` [PATCH] Add man page entry for strnstr.c Sichen Zhao
2017-08-30 14:59   ` Craig Howland
2017-08-30 14:19 ` [PATCH v2] Modify strnstr.c Corinna Vinschen
2017-09-04  9:04   ` Sichen Zhao
2017-08-30 15:04 ` Craig Howland
2017-09-10  4:04 ` Brian Inglis
2017-09-10  4:27 ` Brian Inglis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).