Merge pull request #26678 from yuwata/foreach_array

macro: introduce FOREACH_ARRAY() macro
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2023-03-08 19:06:20 +01:00
committed by GitHub
3 changed files with 70 additions and 13 deletions
+7
View File
@@ -297,6 +297,13 @@ static inline int __coverity_check_and_return__(int condition) {
p != (typeof(p)) POINTER_MAX; \
p = *(++_l))
#define _FOREACH_ARRAY(i, array, num, m, s) \
for (typeof(num) m = (num); m > 0; m = 0) \
for (typeof(array[0]) *s = (array), *i = s; s && i < s + m; i++)
#define FOREACH_ARRAY(i, array, num) \
_FOREACH_ARRAY(i, array, num, UNIQ_T(m, UNIQ), UNIQ_T(s, UNIQ))
#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \
static inline void name(type *p) { \
func(p); \
+13 -13
View File
@@ -126,7 +126,7 @@ static int output_units_list(const UnitInfo *unit_infos, size_t c) {
table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
for (const UnitInfo *u = unit_infos; unit_infos && (size_t) (u - unit_infos) < c; u++) {
FOREACH_ARRAY(u, unit_infos, c) {
_cleanup_free_ char *id = NULL;
const char *on_underline = "", *on_loaded = "", *on_active = "", *on_circle = "";
bool circle = false, underline = false;
@@ -292,7 +292,7 @@ typedef struct SocketInfo {
static void socket_info_array_free(SocketInfo *sockets, size_t n_sockets) {
assert(sockets || n_sockets == 0);
for (SocketInfo *s = sockets; s < sockets + n_sockets; s++) {
FOREACH_ARRAY(s, sockets, n_sockets) {
free(s->type);
free(s->path);
strv_free(s->triggered);
@@ -422,7 +422,7 @@ static int output_sockets_list(const SocketInfo *sockets, size_t n_sockets) {
table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
for (const SocketInfo *s = sockets; s < sockets + n_sockets; s++) {
FOREACH_ARRAY(s, sockets, n_sockets) {
_cleanup_free_ char *unit = NULL;
unit = format_unit_id(s->id, s->machine);
@@ -479,7 +479,7 @@ int verb_list_sockets(int argc, char *argv[], void *userdata) {
if (n < 0)
return n;
for (const UnitInfo *u = unit_infos; u < unit_infos + n; u++) {
FOREACH_ARRAY(u, unit_infos, n) {
r = socket_info_add(bus, u, &sockets, &n_sockets);
if (r < 0)
return r;
@@ -571,7 +571,7 @@ typedef struct TimerInfo {
static void timer_info_array_free(TimerInfo *timers, size_t n_timers) {
assert(timers || n_timers == 0);
for (TimerInfo *t = timers; t < timers + n_timers; t++)
FOREACH_ARRAY(t, timers, n_timers)
strv_free(t->triggered);
free(timers);
@@ -613,7 +613,7 @@ static int output_timers_list(const TimerInfo *timers, size_t n_timers) {
(void) table_set_align_percent(table, table_get_cell(table, 0, 1), 100);
(void) table_set_align_percent(table, table_get_cell(table, 0, 3), 100);
for (const TimerInfo *t = timers; t < timers + n_timers; t++) {
FOREACH_ARRAY(t, timers, n_timers) {
_cleanup_free_ char *unit = NULL;
unit = format_unit_id(t->id, t->machine);
@@ -749,7 +749,7 @@ int verb_list_timers(int argc, char *argv[], void *userdata) {
dual_timestamp_get(&nw);
for (const UnitInfo *u = unit_infos; u < unit_infos + n; u++) {
FOREACH_ARRAY(u, unit_infos, n) {
r = add_timer_info(bus, u, &nw, &timers, &n_timers);
if (r < 0)
return r;
@@ -774,7 +774,7 @@ typedef struct AutomountInfo {
static void automount_info_array_free(AutomountInfo *automounts, size_t n_automounts) {
assert(automounts || n_automounts == 0);
for (AutomountInfo *i = automounts; i < automounts + n_automounts; i++) {
FOREACH_ARRAY(i, automounts, n_automounts) {
free(i->what);
free(i->where);
}
@@ -881,7 +881,7 @@ static int output_automounts_list(const AutomountInfo *infos, size_t n_infos) {
table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
for (const AutomountInfo *info = infos; info < infos + n_infos; info++) {
FOREACH_ARRAY(info, infos, n_infos) {
_cleanup_free_ char *unit = NULL;
unit = format_unit_id(info->id, info->machine);
@@ -945,7 +945,7 @@ int verb_list_automounts(int argc, char *argv[], void *userdata) {
if (n < 0)
return n;
for (const UnitInfo *u = unit_infos; u < unit_infos + n; u++) {
FOREACH_ARRAY(u, unit_infos, n) {
r = automount_info_add(bus, u, &automounts, &n_automounts);
if (r < 0)
return r;
@@ -995,7 +995,7 @@ static int path_info_compare(const PathInfo *a, const PathInfo *b) {
static void path_info_array_free(PathInfo *paths, size_t n_paths) {
assert(paths || n_paths == 0);
for (PathInfo *p = paths; p < paths + n_paths; p++) {
FOREACH_ARRAY(p, paths, n_paths) {
free(p->condition);
free(p->path);
strv_free(p->triggered);
@@ -1096,7 +1096,7 @@ static int output_paths_list(const PathInfo *paths, size_t n_paths) {
table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
for (const PathInfo *p = paths; p < paths + n_paths; p++) {
FOREACH_ARRAY(p, paths, n_paths) {
_cleanup_free_ char *unit = NULL;
unit = format_unit_id(p->id, p->machine);
@@ -1153,7 +1153,7 @@ int verb_list_paths(int argc, char *argv[], void *userdata) {
if (n < 0)
return n;
for (const UnitInfo *u = unit_infos; u < unit_infos + n; u++) {
FOREACH_ARRAY(u, unit_infos, n) {
r = path_info_add(bus, u, &paths, &n_paths);
if (r < 0)
return r;
+50
View File
@@ -584,4 +584,54 @@ TEST(ALIGNED) {
#endif
}
TEST(FOREACH_ARRAY) {
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int b[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int x, n;
x = n = 0;
FOREACH_ARRAY(i, a, 10) {
x += *i;
n++;
}
assert_se(x == 45);
assert_se(n == 10);
x = n = 0;
FOREACH_ARRAY(i, a, 10)
FOREACH_ARRAY(j, b, 10) {
x += (*i) * (*j);
n++;
}
assert_se(x == 45 * 45);
assert_se(n == 10 * 10);
x = n = 0;
FOREACH_ARRAY(i, a, 5)
FOREACH_ARRAY(j, b, 5) {
x += (*i) * (*j);
n++;
}
assert_se(x == 10 * 35);
assert_se(n == 5 * 5);
x = n = 0;
FOREACH_ARRAY(i, a, 0)
FOREACH_ARRAY(j, b, 0) {
x += (*i) * (*j);
n++;
}
assert_se(x == 0);
assert_se(n == 0);
x = n = 0;
FOREACH_ARRAY(i, a, -1)
FOREACH_ARRAY(j, b, -1) {
x += (*i) * (*j);
n++;
}
assert_se(x == 0);
assert_se(n == 0);
}
DEFINE_TEST_MAIN(LOG_INFO);