Compare commits
16 Commits
backport-1
...
backport-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88714148cb | ||
|
|
b0683aba74 | ||
|
|
53f18035d5 | ||
|
|
26f00561a9 | ||
|
|
5206f493b9 | ||
|
|
06e38d511c | ||
|
|
cbd2cea099 | ||
|
|
316cf05463 | ||
|
|
59e779d9ed | ||
|
|
fd649f17f0 | ||
|
|
e0a24d3471 | ||
|
|
1ff7fbbaa2 | ||
|
|
ee992eb6a8 | ||
|
|
ef1b2dfd56 | ||
|
|
cde22a3191 | ||
|
|
6173a3cb3e |
@@ -83,7 +83,7 @@ of i.MX NETC.
|
||||
.phy_mode = NETC_PHY_MODE(port), \
|
||||
}; \
|
||||
struct dsa_port_config dsa_##n##_##port##_config = { \
|
||||
.use_random_mac_addr = DT_NODE_HAS_PROP(port, zephyr_random_mac_address), \
|
||||
.use_random_mac_addr = DT_PROP(port, zephyr_random_mac_address), \
|
||||
.mac_addr = DT_PROP_OR(port, local_mac_address, {0}), \
|
||||
.port_idx = DT_REG_ADDR(port), \
|
||||
.phy_dev = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(port, phy_handle)), \
|
||||
|
||||
@@ -136,16 +136,39 @@ Keeping Zephyr updated
|
||||
To update the Zephyr project source code, you need to get the latest
|
||||
changes via ``git``. Afterwards, run ``west update`` as mentioned in
|
||||
the previous paragraph.
|
||||
Additionally, in the case of updated or added Python dependencies, running
|
||||
``west packages pip --install`` will make sure these are up-to-date.
|
||||
Additionally, check for updated or added Python dependencies.
|
||||
|
||||
.. code-block:: console
|
||||
.. tabs::
|
||||
|
||||
# replace zephyrproject with the path you gave west init
|
||||
cd zephyrproject/zephyr
|
||||
git pull
|
||||
west update
|
||||
west packages pip --install
|
||||
.. group-tab:: Linux/macOS
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# replace zephyrproject with the path you gave west init
|
||||
cd zephyrproject/zephyr
|
||||
git pull
|
||||
west update
|
||||
west packages pip --install
|
||||
|
||||
.. group-tab:: Windows
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: bat
|
||||
|
||||
:: replace zephyrproject with the path you gave west init
|
||||
cd zephyrproject\zephyr
|
||||
git pull
|
||||
west update
|
||||
cmd /c scripts\utils\west-packages-pip-install.cmd
|
||||
|
||||
.. code-tab:: powershell
|
||||
|
||||
# replace zephyrproject with the path you gave west init
|
||||
cd zephyrproject\zephyr
|
||||
git pull
|
||||
west update
|
||||
python -m pip install @((west packages pip) -split ' ')
|
||||
|
||||
Export Zephyr CMake package
|
||||
***************************
|
||||
|
||||
@@ -266,6 +266,10 @@ chosen. You'll also install Zephyr's additional Python dependencies in a
|
||||
|
||||
west packages pip --install
|
||||
|
||||
.. note::
|
||||
|
||||
This could downgrade or upgrade west itself.
|
||||
|
||||
.. group-tab:: macOS
|
||||
|
||||
#. Create a new virtual environment:
|
||||
@@ -317,6 +321,10 @@ chosen. You'll also install Zephyr's additional Python dependencies in a
|
||||
|
||||
west packages pip --install
|
||||
|
||||
.. note::
|
||||
|
||||
This could downgrade or upgrade west itself.
|
||||
|
||||
.. group-tab:: Windows
|
||||
|
||||
#. Open a ``cmd.exe`` or PowerShell terminal window **as a regular user**
|
||||
@@ -389,9 +397,19 @@ chosen. You'll also install Zephyr's additional Python dependencies in a
|
||||
|
||||
#. Install Python dependencies using ``west packages``.
|
||||
|
||||
.. code-block:: bat
|
||||
.. tabs::
|
||||
|
||||
west packages pip --install
|
||||
.. code-tab:: bat
|
||||
|
||||
cmd /c scripts\utils\west-packages-pip-install.cmd
|
||||
|
||||
.. code-tab:: powershell
|
||||
|
||||
python -m pip install @((west packages pip) -split ' ')
|
||||
|
||||
.. note::
|
||||
|
||||
This could downgrade or upgrade west itself.
|
||||
|
||||
Install the Zephyr SDK
|
||||
**********************
|
||||
|
||||
@@ -451,7 +451,7 @@ static struct dsa_api dsa_netc_api = {
|
||||
.phy_mode = NETC_PHY_MODE(port), \
|
||||
}; \
|
||||
struct dsa_port_config dsa_##n##_##port##_config = { \
|
||||
.use_random_mac_addr = DT_NODE_HAS_PROP(port, zephyr_random_mac_address), \
|
||||
.use_random_mac_addr = DT_PROP(port, zephyr_random_mac_address), \
|
||||
.mac_addr = DT_PROP_OR(port, local_mac_address, {0}), \
|
||||
.port_idx = DT_REG_ADDR(port), \
|
||||
.phy_dev = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(port, phy_handle)), \
|
||||
@@ -482,6 +482,6 @@ static struct dsa_api dsa_netc_api = {
|
||||
POST_KERNEL, \
|
||||
CONFIG_ETH_INIT_PRIORITY, \
|
||||
NULL); \
|
||||
DSA_SWITCH_INST_INIT(n, &dsa_netc_api, &dsa_netc_data_##n, DSA_NETC_PORT_INST_INIT); \
|
||||
DSA_SWITCH_INST_INIT(n, &dsa_netc_api, &dsa_netc_data_##n, DSA_NETC_PORT_INST_INIT);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(DSA_NETC_DEVICE);
|
||||
|
||||
@@ -568,6 +568,15 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data,
|
||||
flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ(
|
||||
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR,
|
||||
kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1);
|
||||
flexspi_lut[SCRATCH_CMD][1] = FLEXSPI_LUT_SEQ(
|
||||
kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2,
|
||||
kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2);
|
||||
flexspi_lut[SCRATCH_CMD][2] = FLEXSPI_LUT_SEQ(
|
||||
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR2,
|
||||
kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1);
|
||||
flexspi_lut[SCRATCH_CMD][3] = FLEXSPI_LUT_SEQ(
|
||||
kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0,
|
||||
kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0);
|
||||
flexspi_lut[SCRATCH_CMD2][0] = FLEXSPI_LUT_SEQ(
|
||||
kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WRSR,
|
||||
kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x1);
|
||||
|
||||
@@ -108,6 +108,7 @@ struct mcux_flexcomm_data {
|
||||
bool pm_policy_state_lock;
|
||||
struct k_work pm_lock_work;
|
||||
#endif
|
||||
uint32_t usart_intenset;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
|
||||
@@ -1205,10 +1206,10 @@ static void mcux_flexcomm_pm_restore_wake(const struct device *dev,
|
||||
}
|
||||
#endif /* FC_UART_IS_WAKEUP */
|
||||
|
||||
static uint32_t usart_intenset;
|
||||
static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_action action)
|
||||
{
|
||||
const struct mcux_flexcomm_config *config = dev->config;
|
||||
struct mcux_flexcomm_data *data = dev->data;
|
||||
int ret;
|
||||
|
||||
switch (action) {
|
||||
@@ -1217,14 +1218,14 @@ static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_acti
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
break;
|
||||
case PM_DEVICE_ACTION_TURN_OFF:
|
||||
usart_intenset = USART_GetEnabledInterrupts(config->base);
|
||||
data->usart_intenset = USART_GetEnabledInterrupts(config->base);
|
||||
break;
|
||||
case PM_DEVICE_ACTION_TURN_ON:
|
||||
ret = mcux_flexcomm_init_common(dev);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
USART_EnableInterrupts(config->base, usart_intenset);
|
||||
USART_EnableInterrupts(config->base, data->usart_intenset);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
@@ -196,7 +196,7 @@ static void gop_eagain_retry(int cmd, struct gnttab_map_grant_ref *gref)
|
||||
|
||||
void *gnttab_get_pages(unsigned int npages)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
void *page_addr;
|
||||
unsigned int removed;
|
||||
xen_pfn_t gfn;
|
||||
|
||||
@@ -15,63 +15,82 @@ extern "C" {
|
||||
|
||||
static inline int isupper(int a)
|
||||
{
|
||||
return (int)(((unsigned)(a)-(unsigned)'A') < 26U);
|
||||
return (('A' <= a) && (a <= 'Z'));
|
||||
}
|
||||
|
||||
static inline int isalpha(int c)
|
||||
{
|
||||
return (int)((((unsigned)c|32u)-(unsigned)'a') < 26U);
|
||||
/* force to lowercase */
|
||||
c |= 32;
|
||||
|
||||
return (('a' <= c) && (c <= 'z'));
|
||||
}
|
||||
|
||||
static inline int isblank(int c)
|
||||
{
|
||||
return ((c == ' ') || (c == '\t'));
|
||||
}
|
||||
|
||||
static inline int isspace(int c)
|
||||
{
|
||||
return (int)(c == (int)' ' || ((unsigned)c-(unsigned)'\t') < 5U);
|
||||
return ((c == ' ') || (('\t' <= c) && (c <= '\r')));
|
||||
}
|
||||
|
||||
static inline int isgraph(int c)
|
||||
{
|
||||
return (int)((((unsigned)c) > ' ') &&
|
||||
(((unsigned)c) <= (unsigned)'~'));
|
||||
return ((' ' < c) && (c <= '~'));
|
||||
}
|
||||
|
||||
static inline int isprint(int c)
|
||||
{
|
||||
return (int)((((unsigned)c) >= ' ') &&
|
||||
(((unsigned)c) <= (unsigned)'~'));
|
||||
return ((' ' <= c) && (c <= '~'));
|
||||
}
|
||||
|
||||
static inline int isdigit(int a)
|
||||
{
|
||||
return (int)(((unsigned)(a)-(unsigned)'0') < 10U);
|
||||
return (('0' <= a) && (a <= '9'));
|
||||
}
|
||||
|
||||
static inline int islower(int c)
|
||||
{
|
||||
return (('a' <= c) && (c <= 'z'));
|
||||
}
|
||||
|
||||
static inline int isxdigit(int a)
|
||||
{
|
||||
unsigned int ua = (unsigned int)a;
|
||||
if (isdigit(a) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (int)(((ua - (unsigned)'0') < 10U) ||
|
||||
((ua | 32U) - (unsigned)'a' < 6U));
|
||||
/* force to lowercase */
|
||||
a |= 32;
|
||||
|
||||
return (('a' <= a) && (a <= 'f'));
|
||||
}
|
||||
|
||||
static inline int tolower(int chr)
|
||||
{
|
||||
return (chr >= (int)'A' && chr <= (int)'Z') ? (chr + 32) : (chr);
|
||||
return (chr >= 'A' && chr <= 'Z') ? (chr + 32) : (chr);
|
||||
}
|
||||
|
||||
static inline int toupper(int chr)
|
||||
{
|
||||
return (int)((chr >= (int)'a' && chr <=
|
||||
(int)'z') ? (chr - 32) : (chr));
|
||||
return ((chr >= 'a' && chr <= 'z') ? (chr - 32) : (chr));
|
||||
}
|
||||
|
||||
static inline int isalnum(int chr)
|
||||
{
|
||||
return (int)(isalpha(chr) || isdigit(chr));
|
||||
return (isalpha(chr) || isdigit(chr));
|
||||
}
|
||||
|
||||
static inline int ispunct(int c)
|
||||
{
|
||||
return (isgraph(c) && !isalnum(c));
|
||||
}
|
||||
|
||||
static inline int iscntrl(int c)
|
||||
{
|
||||
return (int)((((unsigned int)c) <= 31U) || (((unsigned int)c) == 127U));
|
||||
return ((((unsigned int)c) <= 31U) || (((unsigned int)c) == 127U));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Guido van Rossum.
|
||||
*
|
||||
* Copyright (c) 2011 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
* Portions of this software were developed by David Chisnall
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -48,26 +53,121 @@
|
||||
|
||||
#define EOS '\0'
|
||||
|
||||
#ifndef FNM_NORES
|
||||
#define FNM_NORES 3
|
||||
#endif
|
||||
|
||||
#ifndef FNM_LEADING_DIR
|
||||
#define FNM_LEADING_DIR 0x08
|
||||
#endif
|
||||
|
||||
#ifndef FNM_CASEFOLD
|
||||
#define FNM_CASEFOLD 0x10
|
||||
#endif
|
||||
|
||||
#define FOLDCASE(ch, flags) foldcase((unsigned char)(ch), (flags))
|
||||
|
||||
#define RANGE_ERROR (-1)
|
||||
#define RANGE_NOMATCH 1
|
||||
#define RANGE_MATCH 0
|
||||
|
||||
/* POSIX character class matching was missing from the BSD version. This was added in 2025 */
|
||||
static int rangematch_cc(const char **pattern, int ch)
|
||||
{
|
||||
typedef unsigned long long ull;
|
||||
|
||||
/*
|
||||
* [:alnum:] et al are 9 characters. [:xdigits:] is 10.
|
||||
* If we first check for the leading "[:", then we have at most 8 remaining characters to
|
||||
* compare. Rather than using string comparison, encode the 8 characters into an integer and
|
||||
* compare to a precomputed constants. This likely only works for the "C" locale.
|
||||
*/
|
||||
#define FNM_CC5(a, b, c, d, e) \
|
||||
(((ull)(a) << 48) | ((ull)(b) << 40) | ((ull)(c) << 32) | ((ull)(d) << 24) | \
|
||||
((ull)(e) << 16) | ((ull)':' << 8) | ((ull)']' << 0))
|
||||
#define FNM_CC6(a, b, c, d, e, f) \
|
||||
(((ull)(a) << 56) | ((ull)(b) << 48) | ((ull)(c) << 40) | ((ull)(d) << 32) | \
|
||||
((ull)(e) << 24) | ((ull)(f) << 16) | ((ull)':' << 8) | ((ull)']' << 0))
|
||||
|
||||
ull key;
|
||||
int ret;
|
||||
const char *p = *pattern;
|
||||
|
||||
/* check the leading "[:" */
|
||||
if ((p[0] != '[') || (p[1] != ':')) {
|
||||
return RANGE_ERROR;
|
||||
}
|
||||
|
||||
/* encode the remaining characters into a 64-bit integer */
|
||||
for (p += 2, key = 0; *p != EOS; ++p) {
|
||||
if (*(p - 1) == ']') {
|
||||
break;
|
||||
}
|
||||
|
||||
key <<= 8;
|
||||
key |= (unsigned char)(*p);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case FNM_CC5('a', 'l', 'n', 'u', 'm'):
|
||||
ret = !isalnum(ch);
|
||||
break;
|
||||
case FNM_CC5('a', 'l', 'p', 'h', 'a'):
|
||||
ret = !isalpha(ch);
|
||||
break;
|
||||
case FNM_CC5('b', 'l', 'a', 'n', 'k'):
|
||||
ret = !isblank(ch);
|
||||
break;
|
||||
case FNM_CC5('c', 'n', 't', 'r', 'l'):
|
||||
ret = !iscntrl(ch);
|
||||
break;
|
||||
case FNM_CC5('d', 'i', 'g', 'i', 't'):
|
||||
ret = !isdigit(ch);
|
||||
break;
|
||||
case FNM_CC5('g', 'r', 'a', 'p', 'h'):
|
||||
ret = !isgraph(ch);
|
||||
break;
|
||||
case FNM_CC5('l', 'o', 'w', 'e', 'r'):
|
||||
ret = !islower(ch);
|
||||
break;
|
||||
case FNM_CC5('p', 'r', 'i', 'n', 't'):
|
||||
ret = !isprint(ch);
|
||||
break;
|
||||
case FNM_CC5('p', 'u', 'n', 'c', 't'):
|
||||
ret = !ispunct(ch);
|
||||
break;
|
||||
case FNM_CC5('s', 'p', 'a', 'c', 'e'):
|
||||
ret = !isspace(ch);
|
||||
break;
|
||||
case FNM_CC5('u', 'p', 'p', 'e', 'r'):
|
||||
ret = !isupper(ch);
|
||||
break;
|
||||
case FNM_CC6('x', 'd', 'i', 'g', 'i', 't'):
|
||||
ret = !isxdigit(ch);
|
||||
break;
|
||||
default:
|
||||
return RANGE_ERROR;
|
||||
}
|
||||
|
||||
*pattern = p;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int foldcase(int ch, int flags)
|
||||
{
|
||||
|
||||
if ((flags & FNM_CASEFOLD) != 0 && isupper(ch)) {
|
||||
if (((flags & FNM_CASEFOLD) != 0) && isupper(ch)) {
|
||||
return tolower(ch);
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
#define FOLDCASE(ch, flags) foldcase((unsigned char)(ch), (flags))
|
||||
|
||||
static const char *rangematch(const char *pattern, int test, int flags)
|
||||
static int rangematch(const char **pattern, char test, int flags)
|
||||
{
|
||||
bool negate, ok, need;
|
||||
char c, c2;
|
||||
|
||||
if (pattern == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
int negate, ok;
|
||||
const char *origpat;
|
||||
const char *pat = *pattern;
|
||||
|
||||
/*
|
||||
* A bracket expression starting with an unquoted circumflex
|
||||
@@ -76,90 +176,113 @@ static const char *rangematch(const char *pattern, int test, int flags)
|
||||
* consistency with the regular expression syntax.
|
||||
* J.T. Conklin (conklin@ngai.kaleida.com)
|
||||
*/
|
||||
negate = *pattern == '!' || *pattern == '^';
|
||||
negate = (*pat == '!' || *pat == '^');
|
||||
if (negate) {
|
||||
++pattern;
|
||||
++pat;
|
||||
}
|
||||
|
||||
for (need = true, ok = false, c = FOLDCASE(*pattern++, flags); c != ']' || need;
|
||||
c = FOLDCASE(*pattern++, flags)) {
|
||||
need = false;
|
||||
test = FOLDCASE(test, flags);
|
||||
|
||||
if (c == '/' && (flags & FNM_PATHNAME)) {
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE)) {
|
||||
if (*pattern != ']' && *pattern != EOS) {
|
||||
c = FOLDCASE(*pattern++, flags);
|
||||
/*
|
||||
* A right bracket shall lose its special meaning and represent
|
||||
* itself in a bracket expression if it occurs first in the list.
|
||||
* -- POSIX.2 2.8.3.2
|
||||
*/
|
||||
ok = 0;
|
||||
origpat = pat;
|
||||
for (;;) {
|
||||
if (*pat == ']' && pat > origpat) {
|
||||
pat++;
|
||||
break;
|
||||
} else if (*pat == '\0') {
|
||||
return RANGE_ERROR;
|
||||
} else if (*pat == '/' && (flags & FNM_PATHNAME)) {
|
||||
return RANGE_NOMATCH;
|
||||
} else if (*pat == '\\' && !(flags & FNM_NOESCAPE)) {
|
||||
pat++;
|
||||
} else {
|
||||
switch (rangematch_cc(&pat, test)) {
|
||||
case RANGE_ERROR:
|
||||
/* not a character class, proceed below */
|
||||
break;
|
||||
case RANGE_MATCH:
|
||||
/* a valid character class that was matched */
|
||||
ok = 1;
|
||||
continue;
|
||||
case RANGE_NOMATCH:
|
||||
/* a valid character class that was not matched */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == EOS) {
|
||||
return NULL;
|
||||
}
|
||||
c = FOLDCASE(*pat++, flags);
|
||||
|
||||
if (*pattern == '-') {
|
||||
c2 = FOLDCASE(*(pattern + 1), flags);
|
||||
if (c2 != EOS && c2 != ']') {
|
||||
pattern += 2;
|
||||
if (c2 == '\\' && !(flags & FNM_NOESCAPE)) {
|
||||
c2 = FOLDCASE(*pattern++, flags);
|
||||
if (*pat == '-' && *(pat + 1) != EOS && *(pat + 1) != ']') {
|
||||
if (*++pat == '\\' && !(flags & FNM_NOESCAPE)) {
|
||||
if (*pat != EOS) {
|
||||
pat++;
|
||||
}
|
||||
}
|
||||
c2 = FOLDCASE(*pat, flags);
|
||||
pat++;
|
||||
if (c2 == EOS) {
|
||||
return RANGE_ERROR;
|
||||
}
|
||||
|
||||
if (c2 == EOS) {
|
||||
return NULL;
|
||||
}
|
||||
if (flags & FNM_CASEFOLD) {
|
||||
c2 = tolower((int)c2);
|
||||
}
|
||||
|
||||
if (c <= test && test <= c2) {
|
||||
ok = true;
|
||||
}
|
||||
if (c <= test && test <= c2) {
|
||||
ok = 1;
|
||||
}
|
||||
} else if (c == test) {
|
||||
ok = true;
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ok == negate ? NULL : pattern;
|
||||
if (ok != negate) {
|
||||
*pattern = pat;
|
||||
return RANGE_MATCH;
|
||||
}
|
||||
|
||||
return RANGE_NOMATCH;
|
||||
}
|
||||
|
||||
static int fnmatchx(const char *pattern, const char *string, int flags, size_t recursion)
|
||||
static int fnmatchx(const char *pattern, const char *string, const char *stringstart, int flags,
|
||||
size_t recursion)
|
||||
{
|
||||
const char *stringstart, *r;
|
||||
char c, test;
|
||||
|
||||
if (pattern == NULL || string == NULL) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
char c;
|
||||
char pc, sc;
|
||||
|
||||
if (recursion-- == 0) {
|
||||
return FNM_NORES;
|
||||
}
|
||||
|
||||
for (stringstart = string;;) {
|
||||
c = FOLDCASE(*pattern++, flags);
|
||||
switch (c) {
|
||||
while (true) {
|
||||
pc = FOLDCASE(*pattern++, flags);
|
||||
sc = FOLDCASE(*string, flags);
|
||||
switch (pc) {
|
||||
case EOS:
|
||||
if ((flags & FNM_LEADING_DIR) && *string == '/') {
|
||||
if (((flags & FNM_LEADING_DIR) != 0) && (sc == '/')) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *string == EOS ? 0 : FNM_NOMATCH;
|
||||
if (sc == EOS) {
|
||||
return 0;
|
||||
}
|
||||
return FNM_NOMATCH;
|
||||
case '?':
|
||||
if (*string == EOS) {
|
||||
if (sc == EOS) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
if (*string == '/' && (flags & FNM_PATHNAME)) {
|
||||
if ((sc == '/') && ((flags & FNM_PATHNAME) != 0)) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
|
||||
if ((sc == '.') && ((flags & FNM_PERIOD) != 0) &&
|
||||
((string == stringstart) ||
|
||||
(((flags & FNM_PATHNAME) != 0) && (*(string - 1) == '/')))) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++string;
|
||||
break;
|
||||
case '*':
|
||||
@@ -169,107 +292,85 @@ static int fnmatchx(const char *pattern, const char *string, int flags, size_t r
|
||||
c = FOLDCASE(*++pattern, flags);
|
||||
}
|
||||
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
|
||||
if ((sc == '.') && ((flags & FNM_PERIOD) != 0) &&
|
||||
((string == stringstart) ||
|
||||
(((flags & FNM_PATHNAME) != 0) && (*(string - 1) == '/')))) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
/* Optimize for pattern with * at end or before /. */
|
||||
if (c == EOS) {
|
||||
if (flags & FNM_PATHNAME) {
|
||||
return (flags & FNM_LEADING_DIR) ||
|
||||
strchr(string, '/') == NULL
|
||||
? 0
|
||||
: FNM_NOMATCH;
|
||||
} else {
|
||||
if ((flags & FNM_PATHNAME) == 0) {
|
||||
return 0;
|
||||
}
|
||||
} else if (c == '/' && flags & FNM_PATHNAME) {
|
||||
|
||||
if (((flags & FNM_LEADING_DIR) != 0) ||
|
||||
(strchr(string, '/') == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return FNM_NOMATCH;
|
||||
} else if ((c == '/') && ((flags & FNM_PATHNAME) != 0)) {
|
||||
string = strchr(string, '/');
|
||||
if (string == NULL) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* General case, use recursion. */
|
||||
do {
|
||||
test = FOLDCASE(*string, flags);
|
||||
if (test == EOS) {
|
||||
while (sc != EOS) {
|
||||
if (fnmatchx(pattern, string, stringstart, flags, recursion) == 0) {
|
||||
return 0;
|
||||
}
|
||||
sc = FOLDCASE(*string, flags);
|
||||
if ((sc == '/') && ((flags & FNM_PATHNAME) != 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
int e = fnmatchx(pattern, string, flags & ~FNM_PERIOD, recursion);
|
||||
|
||||
if (e != FNM_NOMATCH) {
|
||||
return e;
|
||||
}
|
||||
|
||||
if (test == '/' && flags & FNM_PATHNAME) {
|
||||
break;
|
||||
}
|
||||
|
||||
++string;
|
||||
} while (true);
|
||||
|
||||
}
|
||||
return FNM_NOMATCH;
|
||||
case '[':
|
||||
if (*string == EOS) {
|
||||
if (sc == EOS) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
if ((sc == '/') && ((flags & FNM_PATHNAME) != 0)) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
if ((sc == '.') && ((flags & FNM_PERIOD) != 0) &&
|
||||
((string == stringstart) ||
|
||||
(((flags & FNM_PATHNAME) != 0) && (*(string - 1) == '/')))) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
if (*string == '/' && flags & FNM_PATHNAME) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
r = rangematch(pattern, FOLDCASE(*string, flags), flags);
|
||||
|
||||
if (r == NULL) {
|
||||
if (FOLDCASE('[', flags) != FOLDCASE(*string, flags)) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
++string;
|
||||
switch (rangematch(&pattern, sc, flags)) {
|
||||
case RANGE_ERROR:
|
||||
goto norm;
|
||||
case RANGE_MATCH:
|
||||
break;
|
||||
case RANGE_NOMATCH:
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
if (r == (void *)-1) {
|
||||
if (*string != '[') {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
} else {
|
||||
pattern = r;
|
||||
}
|
||||
|
||||
++string;
|
||||
break;
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE)) {
|
||||
c = FOLDCASE(*pattern++, flags);
|
||||
if (c == EOS) {
|
||||
c = '\0';
|
||||
--pattern;
|
||||
}
|
||||
if ((flags & FNM_NOESCAPE) == 0) {
|
||||
pc = FOLDCASE(*pattern++, flags);
|
||||
}
|
||||
__fallthrough;
|
||||
default:
|
||||
if (c != FOLDCASE(*string++, flags)) {
|
||||
norm:
|
||||
if (pc != sc) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
|
||||
int fnmatch(const char *pattern, const char *string, int flags)
|
||||
{
|
||||
return fnmatchx(pattern, string, flags, 64);
|
||||
return fnmatchx(pattern, string, string, flags, 64);
|
||||
}
|
||||
|
||||
27
scripts/utils/west-packages-pip-install.cmd
Normal file
27
scripts/utils/west-packages-pip-install.cmd
Normal file
@@ -0,0 +1,27 @@
|
||||
:: SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors
|
||||
:: SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
@echo off
|
||||
rem Collect packages from west and install them with a single pip call.
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
set "PACKAGES="
|
||||
|
||||
for /f "usebackq delims=" %%p in (`west packages pip`) do (
|
||||
if defined PACKAGES (
|
||||
set "PACKAGES=!PACKAGES! %%p"
|
||||
) else (
|
||||
set "PACKAGES=%%p"
|
||||
)
|
||||
)
|
||||
|
||||
if not defined PACKAGES (
|
||||
echo west packages pip returned no packages to install.
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
echo Installing packages with: python.exe -m pip install %PACKAGES%
|
||||
python.exe -m pip install %PACKAGES%
|
||||
set "RESULT=%ERRORLEVEL%"
|
||||
|
||||
endlocal & exit /b %RESULT%
|
||||
@@ -4,13 +4,15 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from itertools import chain
|
||||
from pathlib import Path
|
||||
from pathlib import Path, PureWindowsPath
|
||||
|
||||
from west.commands import WestCommand
|
||||
from west.util import quote_sh_list
|
||||
from zephyr_ext_common import ZEPHYR_BASE
|
||||
|
||||
sys.path.append(os.fspath(Path(__file__).parent.parent))
|
||||
@@ -157,11 +159,38 @@ class Packages(WestCommand):
|
||||
self.die("Running pip install outside of a virtual environment")
|
||||
|
||||
if len(requirements) > 0:
|
||||
subprocess.check_call(
|
||||
[sys.executable, "-m", "pip", "install"]
|
||||
+ list(chain.from_iterable([("-r", r) for r in requirements]))
|
||||
+ manager_args
|
||||
cmd = [sys.executable, "-m", "pip", "install"]
|
||||
cmd += chain.from_iterable([("-r", str(r)) for r in requirements])
|
||||
cmd += manager_args
|
||||
self.dbg(quote_sh_list(cmd))
|
||||
|
||||
# Use os.execv to execute a new program, replacing the current west process,
|
||||
# this unloads all python modules first and allows for pip to update packages safely
|
||||
if platform.system() != 'Windows':
|
||||
os.execv(cmd[0], cmd)
|
||||
|
||||
# Only reachable on Windows systems
|
||||
# Windows does not really support os.execv:
|
||||
# https://github.com/python/cpython/issues/63323
|
||||
# https://github.com/python/cpython/issues/101191
|
||||
# Warn the users about permission errors as those reported in:
|
||||
# https://github.com/zephyrproject-rtos/zephyr/issues/100296
|
||||
cmdscript = (
|
||||
PureWindowsPath(__file__).parents[1] / "utils" / "west-packages-pip-install.cmd"
|
||||
)
|
||||
self.wrn(
|
||||
"Updating packages on Windows with 'west packages pip --install', that are "
|
||||
"currently in use by west, results in permission errors. Leaving your "
|
||||
"environment with conflicting package versions. Recommended is to start with "
|
||||
"a new environment in that case.\n\n"
|
||||
"To avoid this using powershell run the following command instead:\n"
|
||||
f"{sys.executable} -m pip install @((west packages pip) -split ' ')\n\n"
|
||||
"Using cmd.exe execute the helper script:\n"
|
||||
f"cmd /c {cmdscript}\n\n"
|
||||
"Running 'west packages pip --install -- --dry-run' can provide information "
|
||||
"without actually updating the environment."
|
||||
)
|
||||
subprocess.check_call(cmd)
|
||||
else:
|
||||
self.inf("Nothing to install")
|
||||
return
|
||||
|
||||
@@ -361,15 +361,13 @@ img_mgmt_state_any_pending(void)
|
||||
int
|
||||
img_mgmt_slot_in_use(int slot)
|
||||
{
|
||||
#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER)
|
||||
return 0;
|
||||
#else
|
||||
int image = img_mgmt_slot_to_image(slot);
|
||||
int active_slot = img_mgmt_active_slot(image);
|
||||
|
||||
#if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \
|
||||
!defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD) && \
|
||||
!defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD_WITH_REVERT)
|
||||
!defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD_WITH_REVERT) && \
|
||||
!defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER)
|
||||
enum img_mgmt_next_boot_type type = NEXT_BOOT_TYPE_NORMAL;
|
||||
int nbs = img_mgmt_get_next_boot_slot(image, &type);
|
||||
|
||||
@@ -391,7 +389,6 @@ img_mgmt_slot_in_use(int slot)
|
||||
#endif
|
||||
|
||||
return (active_slot == slot);
|
||||
#endif /* !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER) */
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <zcbor_common.h>
|
||||
#include <zcbor_encode.h>
|
||||
@@ -117,8 +118,6 @@ struct datetime_parser {
|
||||
#define RTC_DATETIME_MINUTE_MAX 59
|
||||
#define RTC_DATETIME_SECOND_MIN 0
|
||||
#define RTC_DATETIME_SECOND_MAX 59
|
||||
#define RTC_DATETIME_MILLISECOND_MIN 0
|
||||
#define RTC_DATETIME_MILLISECOND_MAX 999
|
||||
|
||||
/* Size used for datetime creation buffer */
|
||||
#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS
|
||||
@@ -129,7 +128,7 @@ struct datetime_parser {
|
||||
|
||||
/* Minimum/maximum size of a datetime string that a client can provide */
|
||||
#define RTC_DATETIME_MIN_STRING_SIZE 19
|
||||
#define RTC_DATETIME_MAX_STRING_SIZE 26
|
||||
#define RTC_DATETIME_MAX_STRING_SIZE 31
|
||||
#endif
|
||||
|
||||
/* Specifies what the "all" ('a') of info parameter shows */
|
||||
@@ -969,7 +968,7 @@ static int os_mgmt_datetime_write(struct smp_streamer *ctxt)
|
||||
bool ok = true;
|
||||
char *pos;
|
||||
char *new_pos;
|
||||
char date_string[RTC_DATETIME_MAX_STRING_SIZE];
|
||||
char date_string[RTC_DATETIME_MAX_STRING_SIZE + 1];
|
||||
struct rtc_time new_time = {
|
||||
.tm_wday = -1,
|
||||
.tm_yday = -1,
|
||||
@@ -1024,7 +1023,7 @@ static int os_mgmt_datetime_write(struct smp_streamer *ctxt)
|
||||
if (zcbor_map_decode_bulk(zsd, datetime_decode, ARRAY_SIZE(datetime_decode), &decoded)) {
|
||||
return MGMT_ERR_EINVAL;
|
||||
} else if (datetime.len < RTC_DATETIME_MIN_STRING_SIZE ||
|
||||
datetime.len >= RTC_DATETIME_MAX_STRING_SIZE) {
|
||||
datetime.len > RTC_DATETIME_MAX_STRING_SIZE) {
|
||||
return MGMT_ERR_EINVAL;
|
||||
}
|
||||
|
||||
@@ -1060,16 +1059,20 @@ static int os_mgmt_datetime_write(struct smp_streamer *ctxt)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS
|
||||
if (*(pos - 1) == '.' && *pos != '\0') {
|
||||
/* Provided value has a ms value, extract it */
|
||||
new_time.tm_nsec = strtol(pos, &new_pos, RTC_DATETIME_NUMERIC_BASE);
|
||||
if (*(pos - 1) == '.') {
|
||||
uint32_t msec = 0;
|
||||
uint32_t mul = 100; /* first digit: 10^-1 second = 100 ms */
|
||||
|
||||
if (new_time.tm_nsec < RTC_DATETIME_MILLISECOND_MIN ||
|
||||
new_time.tm_nsec > RTC_DATETIME_MILLISECOND_MAX) {
|
||||
return MGMT_ERR_EINVAL;
|
||||
/* Parse up to 3 fractional digits */
|
||||
while (isdigit((unsigned char)*pos) && mul >= 1) {
|
||||
msec += (uint32_t)(*pos - '0') * mul;
|
||||
mul /= 10;
|
||||
pos++;
|
||||
}
|
||||
|
||||
new_time.tm_nsec *= RTC_DATETIME_MS_TO_NS;
|
||||
/* "." without digits yields 0 µs */
|
||||
|
||||
new_time.tm_nsec = msec * RTC_DATETIME_MS_TO_NS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -465,6 +465,7 @@ error:
|
||||
static void telnet_server_cb(struct net_socket_service_event *evt)
|
||||
{
|
||||
int sock_error;
|
||||
int ret;
|
||||
socklen_t optlen = sizeof(int);
|
||||
|
||||
if (sh_telnet == NULL) {
|
||||
@@ -475,7 +476,14 @@ static void telnet_server_cb(struct net_socket_service_event *evt)
|
||||
(evt->event.revents & ZSOCK_POLLNVAL)) {
|
||||
(void)zsock_getsockopt(evt->event.fd, SOL_SOCKET,
|
||||
SO_ERROR, &sock_error, &optlen);
|
||||
NET_ERR("Telnet socket %d error (%d)", evt->event.fd, sock_error);
|
||||
|
||||
ret = -sock_error;
|
||||
|
||||
if (ret == -ENETDOWN) {
|
||||
LOG_INF("Network is down");
|
||||
} else {
|
||||
LOG_ERR("Telnet socket %d error (%d)", evt->event.fd, ret);
|
||||
}
|
||||
|
||||
if (evt->event.fd == sh_telnet->fds[SOCK_ID_CLIENT].fd) {
|
||||
telnet_end_client_connection();
|
||||
|
||||
@@ -1,20 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Meta
|
||||
* Copyright (c) The Zephyr Project Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <zephyr/posix/fnmatch.h>
|
||||
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
/*
|
||||
* Note: the \x00 control character is specifically excluded below, since testing for it is
|
||||
* equivalent to reading past the end of a '\0'-terminated string (i.e. can fault).
|
||||
*/
|
||||
#define TEST_BLANK_CHARS " \t"
|
||||
#define TEST_CNTRL_CHARS \
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16" \
|
||||
"\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"
|
||||
#define TEST_DIGIT_CHARS "0123456789"
|
||||
#define TEST_LOWER_CHARS "abcdefghijklmnopqrstuvwxyz"
|
||||
#define TEST_PUNCT_CHARS "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
|
||||
#define TEST_SPACE_CHARS " \f\n\r\t\v"
|
||||
#define TEST_UPPER_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
#define TEST_XDIGIT_CHARS "0123456789ABCDEFabcdef"
|
||||
|
||||
/*
|
||||
* Adapted from
|
||||
* https://git.musl-libc.org/cgit/libc-testsuite/tree/fnmatch.c
|
||||
*/
|
||||
ZTEST(posix_c_lib_ext, test_fnmatch)
|
||||
{
|
||||
/* Note: commented out lines indicate known problems to be addressed in #55186 */
|
||||
|
||||
zassert_ok(fnmatch("*.c", "foo.c", 0));
|
||||
zassert_ok(fnmatch("*.c", ".c", 0));
|
||||
zassert_equal(fnmatch("*.a", "foo.c", 0), FNM_NOMATCH);
|
||||
@@ -30,8 +45,31 @@ ZTEST(posix_c_lib_ext, test_fnmatch)
|
||||
zassert_equal(fnmatch("a*.c", "a/x.c", FNM_PATHNAME), FNM_NOMATCH);
|
||||
zassert_ok(fnmatch("*/foo", "/foo", FNM_PATHNAME));
|
||||
zassert_ok(fnmatch("-O[01]", "-O1", 0));
|
||||
zassert_ok(fnmatch("[[?*\\]", "\\", 0));
|
||||
zassert_ok(fnmatch("[]?*\\]", "]", 0));
|
||||
/*
|
||||
* '\' in pattern escapes ']'. bracket expression is incomplete. pattern is interpreted as
|
||||
* literal sequence '[[?*\]'. which does not match input '\'
|
||||
*/
|
||||
zassert_equal(fnmatch("[[?*\\]", "\\", 0), FNM_NOMATCH);
|
||||
/* '\' in pattern does not escape ']'. bracket expression complete. '\' matches input '\' */
|
||||
zassert_ok(fnmatch("[[?*\\]", "\\", FNM_NOESCAPE));
|
||||
/* '\' in pattern escapes '\', match '\' */
|
||||
zassert_ok(fnmatch("[[?*\\\\]", "\\", 0));
|
||||
/*
|
||||
* "[]" (empty bracket expression) is an invalid pattern.
|
||||
* > The ( ']' ) shall lose its special meaning and represent itself in a bracket expression
|
||||
* > if it occurs first in the list (after an initial ( '^' ), if any)
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
|
||||
*
|
||||
* So the next test is (again) and incomplete bracket expression and should return error.
|
||||
* The two tests that follow it also require the ']' to be treated as a literal character to
|
||||
* match within the bracket expression.
|
||||
*/
|
||||
zassert_equal(fnmatch("[]?*\\]", "]", 0), FNM_NOMATCH);
|
||||
/* '\' in pattern does not escape. bracket expression complete. ']' matches input ']' */
|
||||
zassert_ok(fnmatch("[]?*\\]", "]", FNM_NOESCAPE));
|
||||
/* '\' in pattern escapes '\'. bracket expression complete. ']' matches input ']' */
|
||||
zassert_ok(fnmatch("[]?*\\\\]", "]", 0));
|
||||
|
||||
zassert_ok(fnmatch("[!]a-]", "b", 0));
|
||||
zassert_ok(fnmatch("[]-_]", "^", 0));
|
||||
zassert_ok(fnmatch("[!]-_]", "X", 0));
|
||||
@@ -73,11 +111,58 @@ ZTEST(posix_c_lib_ext, test_fnmatch)
|
||||
zassert_equal(fnmatch("*/*", "a/.b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH);
|
||||
zassert_ok(fnmatch("*?*/*", "a/.b", FNM_PERIOD));
|
||||
zassert_ok(fnmatch("*[.]/b", "a./b", FNM_PATHNAME | FNM_PERIOD));
|
||||
/* zassert_ok(fnmatch("*[[:alpha:]]/""*[[:alnum:]]", "a/b", FNM_PATHNAME)); */
|
||||
zassert_not_equal(fnmatch("*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME), 0);
|
||||
zassert_not_equal(fnmatch("*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME), 0);
|
||||
zassert_not_equal(fnmatch("*[![:digit:]]*/[![:d-d]", "a/[", FNM_PATHNAME), 0);
|
||||
zassert_ok(fnmatch("*[[:alpha:]]/*[[:alnum:]]", "a/b", FNM_PATHNAME));
|
||||
zassert_ok(fnmatch("*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME), 0);
|
||||
zassert_ok(fnmatch("*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME), 0);
|
||||
zassert_equal(fnmatch("*[![:digit:]]*/[![:d-d]", "a/[", FNM_PATHNAME), FNM_NOMATCH);
|
||||
zassert_ok(fnmatch("a?b", "a.b", FNM_PATHNAME | FNM_PERIOD));
|
||||
zassert_ok(fnmatch("a*b", "a.b", FNM_PATHNAME | FNM_PERIOD));
|
||||
zassert_ok(fnmatch("a[.]b", "a.b", FNM_PATHNAME | FNM_PERIOD));
|
||||
|
||||
/* Additional test cases for POSIX character classes (C-locale only) */
|
||||
static const struct test_data_s {
|
||||
const char *pattern;
|
||||
const char *match;
|
||||
const char *nomatch;
|
||||
} test_data[] = {
|
||||
{"[[:alnum:]]", TEST_DIGIT_CHARS TEST_UPPER_CHARS TEST_LOWER_CHARS, " "},
|
||||
{"[[:alpha:]]", TEST_UPPER_CHARS TEST_LOWER_CHARS, "0"},
|
||||
{"[[:blank:]]", TEST_BLANK_CHARS, "x"},
|
||||
{"[[:cntrl:]]", TEST_CNTRL_CHARS, "x"},
|
||||
{"[[:digit:]]", TEST_DIGIT_CHARS, "a"},
|
||||
{"[[:graph:]]", TEST_DIGIT_CHARS TEST_UPPER_CHARS TEST_LOWER_CHARS TEST_PUNCT_CHARS,
|
||||
" "},
|
||||
{"[[:lower:]]", TEST_LOWER_CHARS, "X"},
|
||||
{"[[:print:]]",
|
||||
TEST_DIGIT_CHARS TEST_UPPER_CHARS TEST_LOWER_CHARS TEST_PUNCT_CHARS " ", "\t"},
|
||||
{"[[:punct:]]", TEST_PUNCT_CHARS, "x"},
|
||||
{"[[:space:]]", TEST_SPACE_CHARS, "x"},
|
||||
{"[[:upper:]]", TEST_UPPER_CHARS, "x"},
|
||||
{"[[:xdigit:]]", TEST_XDIGIT_CHARS, "h"},
|
||||
};
|
||||
|
||||
ARRAY_FOR_EACH_PTR(test_data, data) {
|
||||
/* ensure that characters in "nomatch" do not match "pattern" */
|
||||
for (size_t j = 0; j < strlen(data->nomatch); j++) {
|
||||
char c = data->nomatch[j];
|
||||
char input[] = {c, '\0'};
|
||||
|
||||
zexpect_equal(fnmatch(data->pattern, input, 0), FNM_NOMATCH,
|
||||
"pattern \"%s\" unexpectedly matched char 0x%02x (%c)",
|
||||
data->pattern, c, isprint(c) ? c : '.');
|
||||
}
|
||||
|
||||
/* ensure that characters in "match" do match "pattern" */
|
||||
for (size_t j = 0; j < strlen(data->match); j++) {
|
||||
char c = data->match[j];
|
||||
char input[] = {c, '\0'};
|
||||
|
||||
zexpect_ok(fnmatch(data->pattern, input, 0),
|
||||
"pattern \"%s\" did not match char 0x%02x (%c)", data->pattern,
|
||||
c, isprint(c) ? c : '.');
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure that an invalid character class generates an error */
|
||||
zassert_equal(fnmatch("[[:foobarbaz:]]", "Z", 0), FNM_NOMATCH);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user