Skip to content

Commit e1f1482

Browse files
committed
improve foreach(fix #960)
1 parent 49ec4d7 commit e1f1482

File tree

7 files changed

+51
-65
lines changed

7 files changed

+51
-65
lines changed

docs/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
2025/08/28
44
* 完善tree_node_feature_segment(感谢兆坤提供补丁)
5+
* 统一foreach visit返回值处理逻辑(感谢兆坤提供补丁)
56

67
2025/08/23
78
* 完善 dlist_remove_ex

src/base/widget.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3601,12 +3601,12 @@ ret_t widget_foreach(widget_t* widget, tk_visit_t visit, void* ctx) {
36013601

36023602
WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i)
36033603
ret = widget_foreach(iter, visit, ctx);
3604-
if (ret == RET_STOP || ret == RET_DONE) {
3605-
return ret;
3606-
}
3604+
3605+
TK_FOREACH_VISIT_RESULT_PROCESSING(
3606+
ret, log_warn("%s: result type REMOVE is not supported!\n", __FUNCTION__));
36073607
WIDGET_FOR_EACH_CHILD_END()
36083608

3609-
return RET_OK;
3609+
return ret;
36103610
}
36113611

36123612
widget_t* widget_get_window(widget_t* widget) {

src/tkc/darray.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ int32_t darray_count(darray_t* darray, void* data) {
345345
}
346346

347347
ret_t darray_foreach(darray_t* darray, tk_visit_t visit, void* ctx) {
348+
ret_t ret = RET_OK;
348349
return_value_if_fail(darray != NULL && visit != NULL, RET_BAD_PARAMS);
349350

350351
if (darray->elms != NULL) {
@@ -353,14 +354,12 @@ ret_t darray_foreach(darray_t* darray, tk_visit_t visit, void* ctx) {
353354

354355
for (i = 0; i < darray->size; i++) {
355356
void* iter = elms[i];
356-
ret_t ret = visit(ctx, iter);
357-
if (ret != RET_OK) {
358-
return ret;
359-
}
357+
ret = visit(ctx, iter);
358+
TK_FOREACH_VISIT_RESULT_PROCESSING(ret, darray_remove_index(darray, i));
360359
}
361360
}
362361

363-
return RET_OK;
362+
return ret;
364363
}
365364

366365
ret_t darray_clear(darray_t* darray) {

src/tkc/dlist.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -244,19 +244,13 @@ ret_t dlist_foreach(dlist_t* dlist, tk_visit_t visit, void* ctx) {
244244
iter = dlist->first;
245245
while (iter != NULL) {
246246
ret = visit(ctx, iter->data);
247-
if (ret == RET_REMOVE) {
248-
dlist_node_t* next = iter->next;
249-
dlist_remove_node(dlist, iter);
250-
dlist_destroy_node(dlist, iter);
251-
iter = next;
252-
continue;
253-
} else if (ret != RET_OK) {
254-
break;
255-
}
247+
TK_FOREACH_VISIT_RESULT_PROCESSING(ret, dlist_node_t* next = iter->next;
248+
dlist_remove_node(dlist, iter);
249+
dlist_destroy_node(dlist, iter); iter = next);
256250
iter = iter->next;
257251
}
258252

259-
return RET_OK;
253+
return ret;
260254
}
261255

262256
ret_t dlist_foreach_reverse(dlist_t* dlist, tk_visit_t visit, void* ctx) {
@@ -267,19 +261,13 @@ ret_t dlist_foreach_reverse(dlist_t* dlist, tk_visit_t visit, void* ctx) {
267261
iter = dlist->last;
268262
while (iter != NULL) {
269263
ret = visit(ctx, iter->data);
270-
if (ret == RET_REMOVE) {
271-
dlist_node_t* prev = iter->prev;
272-
dlist_remove_node(dlist, iter);
273-
dlist_destroy_node(dlist, iter);
274-
iter = prev;
275-
continue;
276-
} else if (ret != RET_OK) {
277-
break;
278-
}
264+
TK_FOREACH_VISIT_RESULT_PROCESSING(ret, dlist_node_t* prev = iter->prev;
265+
dlist_remove_node(dlist, iter);
266+
dlist_destroy_node(dlist, iter); iter = prev);
279267
iter = iter->prev;
280268
}
281269

282-
return RET_OK;
270+
return ret;
283271
}
284272

285273
static void* dlist_pop(dlist_t* dlist, bool_t head) {

src/tkc/slist.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,20 +202,14 @@ ret_t slist_foreach(slist_t* slist, tk_visit_t visit, void* ctx) {
202202
iter = slist->first;
203203
while (iter != NULL) {
204204
ret = visit(ctx, iter->data);
205-
if (ret == RET_REMOVE) {
206-
slist_node_t* next = iter->next;
207-
slist_remove_node(slist, iter, prev);
208-
slist_destroy_node(slist, iter);
209-
iter = next;
210-
continue;
211-
} else if (ret != RET_OK) {
212-
break;
213-
}
205+
TK_FOREACH_VISIT_RESULT_PROCESSING(ret, slist_node_t* next = iter->next;
206+
slist_remove_node(slist, iter, prev);
207+
slist_destroy_node(slist, iter); iter = next);
214208
prev = iter;
215209
iter = iter->next;
216210
}
217211

218-
return RET_OK;
212+
return ret;
219213
}
220214

221215
void* slist_tail_pop(slist_t* slist) {

src/tkc/tree.c

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -196,21 +196,16 @@ static ret_t tree_node_link_sibling(tree_node_t* node, tree_node_t* prev_sibling
196196
static ret_t tree_node_foreach_breadth_first(tree_node_t* node, tk_visit_t visit,
197197
tk_destroy_t destroy, tree_node_mem_context_t* mem_ctx,
198198
void* ctx) {
199+
ret_t ret = RET_OK;
199200
uint32_t i = 0;
200201
darray_t queue;
201202
darray_init(&queue, 64, NULL, NULL);
202203
darray_push(&queue, node);
203204

204205
for (i = 0; i < queue.size; i++) {
205206
tree_node_t* iter = (tree_node_t*)darray_get(&queue, i);
206-
ret_t ret = visit(ctx, iter);
207-
208-
if (ret == RET_REMOVE) {
209-
tree_node_destroy(node, destroy, mem_ctx);
210-
continue;
211-
} else if (ret != RET_OK) {
212-
break;
213-
}
207+
ret = visit(ctx, iter);
208+
TK_FOREACH_VISIT_RESULT_PROCESSING(ret, tree_node_destroy(node, destroy, mem_ctx));
214209

215210
for (iter = tree_node_get_first_sibling(iter->child); iter != NULL; iter = iter->next_sibling) {
216211
darray_push(&queue, iter);
@@ -219,29 +214,25 @@ static ret_t tree_node_foreach_breadth_first(tree_node_t* node, tk_visit_t visit
219214

220215
darray_deinit(&queue);
221216

222-
return RET_OK;
217+
return ret;
223218
}
224219

225220
static ret_t tree_node_foreach_preorder(tree_node_t* node, tk_visit_t visit, tk_destroy_t destroy,
226221
tree_node_mem_context_t* mem_ctx, void* ctx) {
222+
ret_t ret = RET_OK;
227223
darray_t stack;
228224
darray_init(&stack, 16, NULL, NULL);
229225
darray_push(&stack, node);
230226

231227
while (stack.size > 0) {
232228
tree_node_t* iter = (tree_node_t*)darray_pop(&stack);
233-
ret_t ret = visit(ctx, iter);
229+
ret = visit(ctx, iter);
234230

235231
if (iter != node && iter->next_sibling != NULL) {
236232
darray_push(&stack, iter->next_sibling);
237233
}
238234

239-
if (ret == RET_REMOVE) {
240-
tree_node_destroy(node, destroy, mem_ctx);
241-
continue;
242-
} else if (ret != RET_OK) {
243-
break;
244-
}
235+
TK_FOREACH_VISIT_RESULT_PROCESSING(ret, tree_node_destroy(node, destroy, mem_ctx));
245236

246237
iter = tree_node_get_first_sibling(iter->child);
247238
if (iter != NULL) {
@@ -251,11 +242,12 @@ static ret_t tree_node_foreach_preorder(tree_node_t* node, tk_visit_t visit, tk_
251242

252243
darray_deinit(&stack);
253244

254-
return RET_OK;
245+
return ret;
255246
}
256247

257248
static ret_t tree_node_foreach_postorder(tree_node_t* node, tk_visit_t visit, tk_destroy_t destroy,
258249
tree_node_mem_context_t* mem_ctx, void* ctx) {
250+
ret_t ret = RET_OK;
259251
darray_t result_stack;
260252
darray_t process_stack;
261253
darray_init(&result_stack, 128, NULL, NULL);
@@ -273,20 +265,14 @@ static ret_t tree_node_foreach_postorder(tree_node_t* node, tk_visit_t visit, tk
273265

274266
while (result_stack.size > 0) {
275267
tree_node_t* iter = (tree_node_t*)darray_pop(&result_stack);
276-
ret_t ret = visit(ctx, iter);
277-
278-
if (ret == RET_REMOVE) {
279-
tree_node_destroy(node, destroy, mem_ctx);
280-
continue;
281-
} else if (ret != RET_OK) {
282-
break;
283-
}
268+
ret = visit(ctx, iter);
269+
TK_FOREACH_VISIT_RESULT_PROCESSING(ret, tree_node_destroy(node, destroy, mem_ctx));
284270
}
285271

286272
darray_deinit(&process_stack);
287273
darray_deinit(&result_stack);
288274

289-
return RET_OK;
275+
return ret;
290276
}
291277

292278
inline static ret_t tree_node_foreach(tree_node_t* node, tree_foreach_type_t foreach_type,
@@ -525,6 +511,9 @@ ret_t tree_remove_ex(tree_t* tree, tree_node_t* node, tree_foreach_type_t foreac
525511
darray_init(&remove_list, actx.remove_size, NULL, NULL);
526512

527513
ret = tree_foreach(tree, node, foreach_type, tree_remove_on_visit, &actx);
514+
if (RET_STOP == ret) {
515+
ret = RET_OK;
516+
}
528517

529518
while (remove_list.size > 0) {
530519
tree_node_t* iter = darray_pop(&remove_list);

src/tkc/types_def.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,4 +659,19 @@ typedef struct _key_type_value_t {
659659
uint32_t value;
660660
} key_type_value_t;
661661

662+
#define TK_FOREACH_VISIT_RESULT_PROCESSING(result, remove_sentence) \
663+
{ \
664+
if (RET_CONTINUE == result || RET_SKIP == result) { \
665+
result = RET_OK; \
666+
} else if (RET_REMOVE == result) { \
667+
remove_sentence; \
668+
result = RET_OK; \
669+
continue; \
670+
} else if (RET_REPEAT == result) { \
671+
log_warn("%s: result type REPEAT is not supported!\n", __FUNCTION__); \
672+
} else if (result != RET_OK) { \
673+
break; \
674+
} \
675+
}
676+
662677
#endif /*TYPES_DEF_H*/

0 commit comments

Comments
 (0)