[{"id":25993,"web_url":"https://patchwork.libcamera.org/comment/25993/","msgid":"<Y4pgnhZ0odsWMDur@pendragon.ideasonboard.com>","date":"2022-12-02T20:31:26","subject":"Re: [libcamera-devel] [PATCH 2/2] libcamera: utils: Provide\n\tstrchrnul() wrapper","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Fri, Dec 02, 2022 at 05:41:45PM +0100, Jacopo Mondi via libcamera-devel wrote:\n> The strchrnul function is a GNU-specific extension to string.h and it's\n> not availalable on all C libraries (in example, Android's Bionic).\n\nIt has been added to bionic in API level 24.\n\nWhich API level are you using ? Would it be feasible to require level 24\n? It seems to have been introduced in Android 7.0, first released in\n2016. Do we need to support anything older than that ?\n\nSame question for lockf(), which also got introduce in API level 24.\n\n> Provide an implementation of the function based around the generally\n> available strchr() function and use it in the Logger class.\n> \n> Open code the same wrapper in the application's option parser, where we\n> cannot use the internal utils namespace.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n>  include/libcamera/base/utils.h |  1 +\n>  src/apps/common/options.cpp    |  5 ++++-\n>  src/libcamera/base/log.cpp     |  2 +-\n>  src/libcamera/base/utils.cpp   | 19 +++++++++++++++++++\n>  4 files changed, 25 insertions(+), 2 deletions(-)\n> \n> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> index eb7bcdf4c173..b7064ec6253b 100644\n> --- a/include/libcamera/base/utils.h\n> +++ b/include/libcamera/base/utils.h\n> @@ -36,6 +36,7 @@ namespace libcamera {\n>  namespace utils {\n>  \n>  const char *basename(const char *path);\n> +const char *strchrnul(const char *s, int c);\n>  \n>  char *secure_getenv(const char *name);\n>  std::string dirname(const std::string &path);\n> diff --git a/src/apps/common/options.cpp b/src/apps/common/options.cpp\n> index 4f7e869144c8..1bbbec7fa25c 100644\n> --- a/src/apps/common/options.cpp\n> +++ b/src/apps/common/options.cpp\n> @@ -363,7 +363,10 @@ KeyValueParser::Options KeyValueParser::parse(const char *arguments)\n>  \tOptions options;\n>  \n>  \tfor (const char *pair = arguments; *arguments != '\\0'; pair = arguments) {\n> -\t\tconst char *comma = strchrnul(arguments, ',');\n> +\t\tconst char *comma = strchr(arguments, ',');\n> +\t\tif (!comma)\n> +\t\t\tcomma = &arguments[strlen(arguments)];\n> +\n>  \t\tsize_t len = comma - pair;\n>  \n>  \t\t/* Skip over the comma. */\n> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp\n> index 55fbd7b03438..cc30681fd67f 100644\n> --- a/src/libcamera/base/log.cpp\n> +++ b/src/libcamera/base/log.cpp\n> @@ -629,7 +629,7 @@ void Logger::parseLogLevels()\n>  \t\treturn;\n>  \n>  \tfor (const char *pair = debug; *debug != '\\0'; pair = debug) {\n> -\t\tconst char *comma = strchrnul(debug, ',');\n> +\t\tconst char *comma = utils::strchrnul(debug, ',');\n>  \t\tsize_t len = comma - pair;\n>  \n>  \t\t/* Skip over the comma. */\n> diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\n> index 6a307940448e..f829a8106b76 100644\n> --- a/src/libcamera/base/utils.cpp\n> +++ b/src/libcamera/base/utils.cpp\n> @@ -39,6 +39,25 @@ const char *basename(const char *path)\n>  \treturn base ? base + 1 : path;\n>  }\n>  \n> +/**\n> + * \\brief Implement strchnul wrapper\n> + * \\param[in] s The string to seach on\n> + * \\param[in] c The character to search\n> + *\n> + * The strchrnul function is a GNU-specific extension to string.h and it's not\n> + * available on all C libraries (in example, Android's Bionic). This\n> + * implementation realizes strchrnul() on strchr() which is instead more\n> + * generally available.\n> + *\n> + * \\return A pointer to the first occurrence of \\a c in \\a s, or a pointer to\n> + * the null byte at the end of \\a s if \\a c is not found\n> + */\n> +const char *strchrnul(const char *s, int c)\n> +{\n> +\tconst char *p = strchr(s, c);\n> +\treturn p ? : s + strlen(s);\n> +}\n> +\n>  /**\n>   * \\brief Get an environment variable\n>   * \\param[in] name The name of the variable to return","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E9220BE08B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  2 Dec 2022 20:31:30 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 57BF96333F;\n\tFri,  2 Dec 2022 21:31:30 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9E87160483\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  2 Dec 2022 21:31:28 +0100 (CET)","from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi\n\t[213.243.189.158])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 08BE16E0;\n\tFri,  2 Dec 2022 21:31:27 +0100 (CET)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1670013090;\n\tbh=xf5vSWGuLUL+HYUcf6ezhQF9DPEF+RIyKgNrxwqJ25k=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=2S33llLz/0ZFcyhOjrvhOuJpOmjWIYR7LKur1urx5PlTacVeLeZt+Pt2eM/izybhT\n\tjn3OC8B9rCj1wRJJ/VMCfB01yi/3/MTLq/b8bDU1ozFNq6eF4T1R6MFsjx3NVHXm1w\n\t2OfIxyE/ZgGo8B1RI9X3iKCezz/3PyBi7k/dSTIAyCwbbnB5G93npIpjl9JdTI2m0c\n\tOoAk2K4PsnX1t7WXmgP2AKwSdMtUJT3cNITZsRhxrd8TXHgGXC41DKCnCHck5mV4sy\n\t8UFa0INmU8Ge+oOwDmQhJXi4r4ic5BTFXM8+cOLf7mJsdc/uUVj2svY354ezgqYghq\n\theeWFtsRdQdfg==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1670013088;\n\tbh=xf5vSWGuLUL+HYUcf6ezhQF9DPEF+RIyKgNrxwqJ25k=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=a5otQR99AhkrXs+JRxBmtlvcfCVpkKaEIVRpYH+DkIcBCm2ee4ZhgIpR4CA7aTMRC\n\tEO2vDzcm6MLDQai3MPRpX5XDGRCm/i4iZB2Z3caJaF9XXLtbuiI3iEWNXWZgSjB91a\n\tU1rVQXZOA9drOUZcLlnztlDRiGFkqoO2lTUkDeGM="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"a5otQR99\"; dkim-atps=neutral","Date":"Fri, 2 Dec 2022 22:31:26 +0200","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<Y4pgnhZ0odsWMDur@pendragon.ideasonboard.com>","References":"<20221202164145.30603-1-jacopo@jmondi.org>\n\t<20221202164145.30603-2-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20221202164145.30603-2-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH 2/2] libcamera: utils: Provide\n\tstrchrnul() wrapper","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":25998,"web_url":"https://patchwork.libcamera.org/comment/25998/","msgid":"<20221205084851.em27snjwevpofj7d@uno.localdomain>","date":"2022-12-05T08:48:51","subject":"Re: [libcamera-devel] [PATCH 2/2] libcamera: utils: Provide\n\tstrchrnul() wrapper","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent\n\nOn Fri, Dec 02, 2022 at 10:31:26PM +0200, Laurent Pinchart wrote:\n> Hi Jacopo,\n>\n> Thank you for the patch.\n>\n> On Fri, Dec 02, 2022 at 05:41:45PM +0100, Jacopo Mondi via libcamera-devel wrote:\n> > The strchrnul function is a GNU-specific extension to string.h and it's\n> > not availalable on all C libraries (in example, Android's Bionic).\n>\n> It has been added to bionic in API level 24.\n>\n> Which API level are you using ? Would it be feasible to require level 24\n> ? It seems to have been introduced in Android 7.0, first released in\n> 2016. Do we need to support anything older than that ?\n\nLineage OS 18.1 which is based on Android 11, API level 21.\n\nNo idea what is the Android release cycle but 11 seems to still be in\nuse ?\n\n>\n> Same question for lockf(), which also got introduce in API level 24.\n>\n> > Provide an implementation of the function based around the generally\n> > available strchr() function and use it in the Logger class.\n> >\n> > Open code the same wrapper in the application's option parser, where we\n> > cannot use the internal utils namespace.\n> >\n> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> > ---\n> >  include/libcamera/base/utils.h |  1 +\n> >  src/apps/common/options.cpp    |  5 ++++-\n> >  src/libcamera/base/log.cpp     |  2 +-\n> >  src/libcamera/base/utils.cpp   | 19 +++++++++++++++++++\n> >  4 files changed, 25 insertions(+), 2 deletions(-)\n> >\n> > diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> > index eb7bcdf4c173..b7064ec6253b 100644\n> > --- a/include/libcamera/base/utils.h\n> > +++ b/include/libcamera/base/utils.h\n> > @@ -36,6 +36,7 @@ namespace libcamera {\n> >  namespace utils {\n> >\n> >  const char *basename(const char *path);\n> > +const char *strchrnul(const char *s, int c);\n> >\n> >  char *secure_getenv(const char *name);\n> >  std::string dirname(const std::string &path);\n> > diff --git a/src/apps/common/options.cpp b/src/apps/common/options.cpp\n> > index 4f7e869144c8..1bbbec7fa25c 100644\n> > --- a/src/apps/common/options.cpp\n> > +++ b/src/apps/common/options.cpp\n> > @@ -363,7 +363,10 @@ KeyValueParser::Options KeyValueParser::parse(const char *arguments)\n> >  \tOptions options;\n> >\n> >  \tfor (const char *pair = arguments; *arguments != '\\0'; pair = arguments) {\n> > -\t\tconst char *comma = strchrnul(arguments, ',');\n> > +\t\tconst char *comma = strchr(arguments, ',');\n> > +\t\tif (!comma)\n> > +\t\t\tcomma = &arguments[strlen(arguments)];\n> > +\n> >  \t\tsize_t len = comma - pair;\n> >\n> >  \t\t/* Skip over the comma. */\n> > diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp\n> > index 55fbd7b03438..cc30681fd67f 100644\n> > --- a/src/libcamera/base/log.cpp\n> > +++ b/src/libcamera/base/log.cpp\n> > @@ -629,7 +629,7 @@ void Logger::parseLogLevels()\n> >  \t\treturn;\n> >\n> >  \tfor (const char *pair = debug; *debug != '\\0'; pair = debug) {\n> > -\t\tconst char *comma = strchrnul(debug, ',');\n> > +\t\tconst char *comma = utils::strchrnul(debug, ',');\n> >  \t\tsize_t len = comma - pair;\n> >\n> >  \t\t/* Skip over the comma. */\n> > diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\n> > index 6a307940448e..f829a8106b76 100644\n> > --- a/src/libcamera/base/utils.cpp\n> > +++ b/src/libcamera/base/utils.cpp\n> > @@ -39,6 +39,25 @@ const char *basename(const char *path)\n> >  \treturn base ? base + 1 : path;\n> >  }\n> >\n> > +/**\n> > + * \\brief Implement strchnul wrapper\n> > + * \\param[in] s The string to seach on\n> > + * \\param[in] c The character to search\n> > + *\n> > + * The strchrnul function is a GNU-specific extension to string.h and it's not\n> > + * available on all C libraries (in example, Android's Bionic). This\n> > + * implementation realizes strchrnul() on strchr() which is instead more\n> > + * generally available.\n> > + *\n> > + * \\return A pointer to the first occurrence of \\a c in \\a s, or a pointer to\n> > + * the null byte at the end of \\a s if \\a c is not found\n> > + */\n> > +const char *strchrnul(const char *s, int c)\n> > +{\n> > +\tconst char *p = strchr(s, c);\n> > +\treturn p ? : s + strlen(s);\n> > +}\n> > +\n> >  /**\n> >   * \\brief Get an environment variable\n> >   * \\param[in] name The name of the variable to return\n>\n> --\n> Regards,\n>\n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 1F3DDBE08B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  5 Dec 2022 08:48:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8734C6333F;\n\tMon,  5 Dec 2022 09:48:54 +0100 (CET)","from relay10.mail.gandi.net (relay10.mail.gandi.net\n\t[IPv6:2001:4b98:dc4:8::230])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 55CA363335\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  5 Dec 2022 09:48:53 +0100 (CET)","(Authenticated sender: jacopo@jmondi.org)\n\tby mail.gandi.net (Postfix) with ESMTPSA id BE0DE240018;\n\tMon,  5 Dec 2022 08:48:52 +0000 (UTC)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1670230134;\n\tbh=Y03yXZjTj35oFJVSckYWiy9bFCSwkyitLHemDns0pPU=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=djALO9v48rGElsnCSrx6pQxIWbbYppeJRl27wxr8XQVmm1KBn5yDITVlIT0blgi8D\n\tGuvfCWADEurNU3rJi1FsMmy+v7ReVwxZvLXZIiTJ76loMwffO9T9q701xO92MRsSpe\n\t9MHIPKXH6HCYdK6zIED8en73D/gzzhkJeELR2RX0z+GfZv5c7dKWV285VwwvasF+PX\n\tybbxw4ulc6/yoGeSMEQJoaGK8odtGfh91aeWI3fLMIvrkpf0pQTLX527IKzn/9eyai\n\tq8Pau3JWw6Qm8tgo2nY3bPAHlsUaEpsrSWapIuvlVpRv9ej+7M8WCeXMybRrUL2xqW\n\t+M24ZAPujZA5Q==","Date":"Mon, 5 Dec 2022 09:48:51 +0100","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20221205084851.em27snjwevpofj7d@uno.localdomain>","References":"<20221202164145.30603-1-jacopo@jmondi.org>\n\t<20221202164145.30603-2-jacopo@jmondi.org>\n\t<Y4pgnhZ0odsWMDur@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<Y4pgnhZ0odsWMDur@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 2/2] libcamera: utils: Provide\n\tstrchrnul() wrapper","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Jacopo Mondi via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":26000,"web_url":"https://patchwork.libcamera.org/comment/26000/","msgid":"<Y427XDwlsNvc5E7v@pendragon.ideasonboard.com>","date":"2022-12-05T09:35:24","subject":"Re: [libcamera-devel] [PATCH 2/2] libcamera: utils: Provide\n\tstrchrnul() wrapper","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Mon, Dec 05, 2022 at 09:48:51AM +0100, Jacopo Mondi wrote:\n> On Fri, Dec 02, 2022 at 10:31:26PM +0200, Laurent Pinchart wrote:\n> > On Fri, Dec 02, 2022 at 05:41:45PM +0100, Jacopo Mondi via libcamera-devel wrote:\n> > > The strchrnul function is a GNU-specific extension to string.h and it's\n> > > not availalable on all C libraries (in example, Android's Bionic).\n> >\n> > It has been added to bionic in API level 24.\n> >\n> > Which API level are you using ? Would it be feasible to require level 24\n> > ? It seems to have been introduced in Android 7.0, first released in\n> > 2016. Do we need to support anything older than that ?\n> \n> Lineage OS 18.1 which is based on Android 11, API level 21.\n> \n> No idea what is the Android release cycle but 11 seems to still be in\n> use ?\n\nAndroid 11 has shipped with API level 30. There's something odd there\nthat we need to understand better.\n\n> > Same question for lockf(), which also got introduce in API level 24.\n> >\n> > > Provide an implementation of the function based around the generally\n> > > available strchr() function and use it in the Logger class.\n> > >\n> > > Open code the same wrapper in the application's option parser, where we\n> > > cannot use the internal utils namespace.\n> > >\n> > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> > > ---\n> > >  include/libcamera/base/utils.h |  1 +\n> > >  src/apps/common/options.cpp    |  5 ++++-\n> > >  src/libcamera/base/log.cpp     |  2 +-\n> > >  src/libcamera/base/utils.cpp   | 19 +++++++++++++++++++\n> > >  4 files changed, 25 insertions(+), 2 deletions(-)\n> > >\n> > > diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> > > index eb7bcdf4c173..b7064ec6253b 100644\n> > > --- a/include/libcamera/base/utils.h\n> > > +++ b/include/libcamera/base/utils.h\n> > > @@ -36,6 +36,7 @@ namespace libcamera {\n> > >  namespace utils {\n> > >\n> > >  const char *basename(const char *path);\n> > > +const char *strchrnul(const char *s, int c);\n> > >\n> > >  char *secure_getenv(const char *name);\n> > >  std::string dirname(const std::string &path);\n> > > diff --git a/src/apps/common/options.cpp b/src/apps/common/options.cpp\n> > > index 4f7e869144c8..1bbbec7fa25c 100644\n> > > --- a/src/apps/common/options.cpp\n> > > +++ b/src/apps/common/options.cpp\n> > > @@ -363,7 +363,10 @@ KeyValueParser::Options KeyValueParser::parse(const char *arguments)\n> > >  \tOptions options;\n> > >\n> > >  \tfor (const char *pair = arguments; *arguments != '\\0'; pair = arguments) {\n> > > -\t\tconst char *comma = strchrnul(arguments, ',');\n> > > +\t\tconst char *comma = strchr(arguments, ',');\n> > > +\t\tif (!comma)\n> > > +\t\t\tcomma = &arguments[strlen(arguments)];\n> > > +\n> > >  \t\tsize_t len = comma - pair;\n> > >\n> > >  \t\t/* Skip over the comma. */\n> > > diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp\n> > > index 55fbd7b03438..cc30681fd67f 100644\n> > > --- a/src/libcamera/base/log.cpp\n> > > +++ b/src/libcamera/base/log.cpp\n> > > @@ -629,7 +629,7 @@ void Logger::parseLogLevels()\n> > >  \t\treturn;\n> > >\n> > >  \tfor (const char *pair = debug; *debug != '\\0'; pair = debug) {\n> > > -\t\tconst char *comma = strchrnul(debug, ',');\n> > > +\t\tconst char *comma = utils::strchrnul(debug, ',');\n> > >  \t\tsize_t len = comma - pair;\n> > >\n> > >  \t\t/* Skip over the comma. */\n> > > diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp\n> > > index 6a307940448e..f829a8106b76 100644\n> > > --- a/src/libcamera/base/utils.cpp\n> > > +++ b/src/libcamera/base/utils.cpp\n> > > @@ -39,6 +39,25 @@ const char *basename(const char *path)\n> > >  \treturn base ? base + 1 : path;\n> > >  }\n> > >\n> > > +/**\n> > > + * \\brief Implement strchnul wrapper\n> > > + * \\param[in] s The string to seach on\n> > > + * \\param[in] c The character to search\n> > > + *\n> > > + * The strchrnul function is a GNU-specific extension to string.h and it's not\n> > > + * available on all C libraries (in example, Android's Bionic). This\n> > > + * implementation realizes strchrnul() on strchr() which is instead more\n> > > + * generally available.\n> > > + *\n> > > + * \\return A pointer to the first occurrence of \\a c in \\a s, or a pointer to\n> > > + * the null byte at the end of \\a s if \\a c is not found\n> > > + */\n> > > +const char *strchrnul(const char *s, int c)\n> > > +{\n> > > +\tconst char *p = strchr(s, c);\n> > > +\treturn p ? : s + strlen(s);\n> > > +}\n> > > +\n> > >  /**\n> > >   * \\brief Get an environment variable\n> > >   * \\param[in] name The name of the variable to return","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 412AABE08B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  5 Dec 2022 09:35:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D51CD6333B;\n\tMon,  5 Dec 2022 10:35:27 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C803263335\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  5 Dec 2022 10:35:26 +0100 (CET)","from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi\n\t[213.243.189.158])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3F076327;\n\tMon,  5 Dec 2022 10:35:26 +0100 (CET)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1670232927;\n\tbh=Ui00DTqbDwlkucQ7vrQHz3q632VfZp4y9qBYS8nr3RI=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=KKrRos3D/5Xtp9LY6Gkq45Us2yRIevHqbl4OmFbifYzbhmAUalS3HPpQoEf/SzlMz\n\tnDtsq/kCGndNRzupx3ooVnGyV0i386gRP2BIhc0Zkeahe4hpbiG6EIXqAkHPu1O8qR\n\tTwgFxS1QNmW2SUwwjBN+4LpRarDb8i747/RkiW+VrI9Iqj8zSOccHIn4o3Tjg3At0F\n\tD36hNIlUJjImiihfFcKqAySFKufW1g0IbZAlB90D5ZwiEJ+neoTHVvMvo9ikgf0UnJ\n\tdhcm71YnT5KhLWoI2sFOfubnEF6cPLCRPqgBRIu0AzvdWhdiHhqrfjtgSb+AqtBFOY\n\t0K7IyBiZ3yabQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1670232926;\n\tbh=Ui00DTqbDwlkucQ7vrQHz3q632VfZp4y9qBYS8nr3RI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=scxXk+Lp23j6T2VocrzlHqwiBR4wNfE24U1Ge+yEQw1QlQmxjgO3G2NINmDBMHxOs\n\taJOnn6DHrwDJZADPNW4iDhedOYblLJ7NngQO+kB8FKg55hSGa5LBhgPlpY+AjJmxvA\n\tRS38xHpZDCHVLlx4CMf2x6D/gM5k3gAKUHEeuRMo="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"scxXk+Lp\"; dkim-atps=neutral","Date":"Mon, 5 Dec 2022 11:35:24 +0200","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<Y427XDwlsNvc5E7v@pendragon.ideasonboard.com>","References":"<20221202164145.30603-1-jacopo@jmondi.org>\n\t<20221202164145.30603-2-jacopo@jmondi.org>\n\t<Y4pgnhZ0odsWMDur@pendragon.ideasonboard.com>\n\t<20221205084851.em27snjwevpofj7d@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20221205084851.em27snjwevpofj7d@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH 2/2] libcamera: utils: Provide\n\tstrchrnul() wrapper","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]