Freeciv-3.3
Loading...
Searching...
No Matches
cityhand.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22/* utility */
23#include "fcintl.h"
24#include "log.h"
25#include "mem.h"
26#include "rand.h"
27#include "support.h"
28
29/* common */
30#include "city.h"
31#include "events.h"
32#include "game.h"
33#include "idex.h"
34#include "map.h"
35#include "player.h"
36#include "specialist.h"
37#include "unit.h"
38#include "worklist.h"
39
40/* common/aicore */
41#include "cm.h"
42
43/* server */
44#include "citytools.h"
45#include "cityturn.h"
46#include "notify.h"
47#include "plrhand.h"
48#include "sanitycheck.h"
49#include "unithand.h"
50#include "unittools.h"
51
52#include "cityhand.h"
53
54/**********************************************************************/
59void handle_city_name_suggestion_req(struct player *pplayer, int unit_id)
60{
61 struct unit *punit = player_unit_by_number(pplayer, unit_id);
62
63 if (NULL == punit) {
64 /* Probably died or bribed. */
65 log_verbose("handle_city_name_suggestion_req() invalid unit %d",
66 unit_id);
67 return;
68 }
69
71 unit_tile(punit), NULL))) {
72 log_verbose("handle_city_name_suggest_req(unit_pos (%d, %d))",
76
77 /* The rest of this function is error handling. */
78 return;
79 }
80
81 log_verbose("handle_city_name_suggest_req(unit_pos (%d, %d)): "
82 "cannot build there.", TILE_XY(unit_tile(punit)));
83
86}
87
88/**********************************************************************/
91void handle_city_change_specialist(struct player *pplayer, int city_id,
94{
95 struct city *pcity = player_city_by_number(pplayer, city_id);
96
97 if (!pcity) {
98 return;
99 }
100
103 || !city_can_use_specialist(pcity, to)
104 || pcity->specialists[from] == 0) {
105 /* This could easily just be due to clicking faster on the specialist
106 * than the server can cope with. */
107 log_verbose("Error in specialist change request from client.");
108 return;
109 }
110
111 pcity->specialists[from]--;
112 pcity->specialists[to]++;
113
114 city_refresh(pcity);
115 sanity_check_city(pcity);
116 send_city_info(pplayer, pcity);
117}
118
119/**********************************************************************/
123 int city_id, int tile_id)
124{
125 struct tile *ptile = index_to_tile(&(wld.map), tile_id);
126 struct city *pcity = player_city_by_number(pplayer, city_id);
127
128 if (NULL == pcity) {
129 /* Probably lost. */
130 log_verbose("handle_city_make_specialist() bad city number %d.",
131 city_id);
132 return;
133 }
134
135 if (NULL == ptile) {
136 log_error("handle_city_make_specialist() bad tile number %d.", tile_id);
137 return;
138 }
139
140 if (!city_map_includes_tile(pcity, ptile)) {
141 log_error("handle_city_make_specialist() tile (%d, %d) not in the "
142 "city map of \"%s\".", TILE_XY(ptile), city_name_get(pcity));
143 return;
144 }
145
146 /* Disable server side governor being overridden */
147 handle_web_cma_clear(pplayer, pcity->id);
148
149 if (is_free_worked(pcity, ptile)) {
151 } else if (tile_worked(ptile) == pcity) {
152 city_map_update_empty(pcity, ptile);
154 } else {
155 log_verbose("handle_city_make_specialist() not working (%d, %d) "
156 "\"%s\".", TILE_XY(ptile), city_name_get(pcity));
157 }
158
159 city_refresh(pcity);
160 sanity_check_city(pcity);
161 sync_cities();
162}
163
164/**********************************************************************/
169void handle_city_make_worker(struct player *pplayer,
170 int city_id, int tile_id)
171{
172 struct tile *ptile = index_to_tile(&(wld.map), tile_id);
173 struct city *pcity = player_city_by_number(pplayer, city_id);
174
175 if (NULL == pcity) {
176 /* Probably lost. */
177 log_verbose("handle_city_make_worker() bad city number %d.",city_id);
178 return;
179 }
180
181 if (NULL == ptile) {
182 log_error("handle_city_make_worker() bad tile number %d.", tile_id);
183 return;
184 }
185
186 if (!city_map_includes_tile(pcity, ptile)) {
187 log_error("handle_city_make_worker() tile (%d, %d) not in the "
188 "city map of \"%s\".", TILE_XY(ptile), city_name_get(pcity));
189 return;
190 }
191
192 if (is_free_worked(pcity, ptile)) {
193 /* Disable server side governor being overridden */
194 handle_web_cma_clear(pplayer, pcity->id);
195
197 sync_cities();
198 return;
199 }
200
201 if (tile_worked(ptile) == pcity) {
202 log_verbose("handle_city_make_worker() already working (%d, %d) \"%s\".",
203 TILE_XY(ptile), city_name_get(pcity));
204 return;
205 }
206
207 if (0 == city_specialists(pcity)) {
208 log_verbose("handle_city_make_worker() no specialists (%d, %d) \"%s\".",
209 TILE_XY(ptile), city_name_get(pcity));
210 return;
211 }
212
213 if (!city_can_work_tile(pcity, ptile)) {
214 log_verbose("handle_city_make_worker() cannot work here (%d, %d) \"%s\".",
215 TILE_XY(ptile), city_name_get(pcity));
216 return;
217 }
218
219 /* Disable server side governor being overridden */
220 handle_web_cma_clear(pplayer, pcity->id);
221
222 city_map_update_worker(pcity, ptile);
223
225 if (pcity->specialists[i] > 0) {
226 pcity->specialists[i]--;
227 break;
228 }
230
231 city_refresh(pcity);
232 sanity_check_city(pcity);
233 sync_cities();
234}
235
236/**********************************************************************/
240void really_handle_city_sell(struct player *pplayer, struct city *pcity,
241 struct impr_type *pimprove)
242{
244 int price;
245
246 sell_result = test_player_sell_building_now(pplayer, pcity, pimprove);
247
249 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
250 _("You have already sold something here this turn."));
251 return;
252 }
253
254 if (sell_result != TR_SUCCESS) {
255 return;
256 }
257
258 pcity->did_sell = TRUE;
259 price = impr_sell_gold(pimprove);
260 notify_player(pplayer, pcity->tile, E_IMP_SOLD, ftc_server,
261 PL_("You sell %s in %s for %d gold.",
262 "You sell %s in %s for %d gold.", price),
264 city_link(pcity), price);
265 do_sell_building(pplayer, pcity, pimprove, "sold");
266
267 city_refresh(pcity);
268
269 /* If we sold the walls the other players should see it */
270 send_city_info(NULL, pcity);
271 send_player_info_c(pplayer, pplayer->connections);
272}
273
274/**********************************************************************/
278void handle_city_sell(struct player *pplayer, int city_id, int build_id)
279{
280 struct city *pcity = player_city_by_number(pplayer, city_id);
281 struct impr_type *pimprove = improvement_by_number(build_id);
282
283 if (!pcity || !pimprove) {
284 return;
285 }
286 really_handle_city_sell(pplayer, pcity, pimprove);
287}
288
289/**********************************************************************/
293void really_handle_city_buy(struct player *pplayer, struct city *pcity)
294{
295 int cost, total;
296
297 /* This function corresponds to city_can_buy() in the client. */
298
299 fc_assert_ret(pcity && player_owns_city(pplayer, pcity));
300
301 if (pcity->turn_founded == game.info.turn) {
302 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
303 _("Cannot buy in city created this turn."));
304 return;
305 }
306
307 if (pcity->did_buy) {
308 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
309 _("You have already bought this turn."));
310 return;
311 }
312
314 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
315 _("You don't buy %s!"),
317 return;
318 }
319
320 if (VUT_UTYPE == pcity->production.kind && pcity->anarchy != 0) {
321 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
322 _("Can't buy units when city is in disorder."));
323 return;
324 }
325
328 if (cost <= 0) {
329 return; /* sanity */
330 }
331 if (cost > pplayer->economic.gold) {
332 /* In case something changed while player tried to buy, or player
333 * tried to cheat! */
334 /* Split into two to allow localization of two pluralisations. */
335 char buf[MAX_LEN_MSG];
336 /* TRANS: This whole string is only ever used when included in one
337 * other string (search for this string to find it). */
338 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("%d gold required.",
339 "%d gold required.",
340 cost), cost);
341 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
342 /* TRANS: %s is a pre-pluralised string:
343 * "%d gold required." */
344 PL_("%s You only have %d gold.",
345 "%s You only have %d gold.", pplayer->economic.gold),
346 buf, pplayer->economic.gold);
347 return;
348 }
349
350 pplayer->economic.gold -= cost;
351 if (pcity->shield_stock < total) {
352 /* As we never put penalty on disbanded_shields, we can
353 * fully well add the missing shields there. */
354 pcity->disbanded_shields += total - pcity->shield_stock;
355 pcity->shield_stock = total; /* AI wants this -- Syela */
356 pcity->did_buy = TRUE; /* !PS: no need to set buy flag otherwise */
357 }
358 city_refresh(pcity);
359
360 if (VUT_UTYPE == pcity->production.kind) {
361 notify_player(pplayer, pcity->tile, E_UNIT_BUY, ftc_server,
362 /* TRANS: bought an unit. */
363 Q_("?unit:You bought %s in %s."),
365 city_name_get(pcity));
366 } else if (VUT_IMPROVEMENT == pcity->production.kind) {
367 notify_player(pplayer, pcity->tile, E_IMP_BUY, ftc_server,
368 /* TRANS: bought an improvement .*/
369 Q_("?improvement:You bought %s in %s."),
371 city_name_get(pcity));
372 }
373
375 send_city_info(pplayer, pcity);
376 send_player_info_c(pplayer, pplayer->connections);
378}
379
380/**********************************************************************/
383void handle_city_worklist(struct player *pplayer, int city_id,
384 const struct worklist *worklist)
385{
386 struct city *pcity = player_city_by_number(pplayer, city_id);
387
388 if (!pcity) {
389 return;
390 }
391
393
394 send_city_info(pplayer, pcity);
395}
396
397/**********************************************************************/
401void handle_city_buy(struct player *pplayer, int city_id)
402{
403 struct city *pcity = player_city_by_number(pplayer, city_id);
404
405 if (!pcity) {
406 return;
407 }
408
409 really_handle_city_buy(pplayer, pcity);
410}
411
412/**********************************************************************/
415void handle_city_refresh(struct player *pplayer, int city_id)
416{
417 if (city_id != 0) {
418 struct city *pcity = player_city_by_number(pplayer, city_id);
419
420 if (!pcity) {
421 return;
422 }
423
424 city_refresh(pcity);
425 send_city_info(pplayer, pcity);
426 } else {
428 }
429}
430
431/**********************************************************************/
434void handle_city_change(struct player *pplayer, int city_id,
435 int production_kind, int production_value)
436{
437 struct universal prod;
438 struct city *pcity = player_city_by_number(pplayer, city_id);
439
440 if (!universals_n_is_valid(production_kind)) {
441 log_error("[%s] bad production_kind %d.", __FUNCTION__,
442 production_kind);
443 prod.kind = VUT_NONE;
444 return;
445 } else {
446 prod = universal_by_number(production_kind, production_value);
447 if (!universals_n_is_valid(prod.kind)) {
448 log_error("[%s] production_kind %d with bad production_value %d.",
449 __FUNCTION__, production_kind, production_value);
450 prod.kind = VUT_NONE;
451 return;
452 }
453 }
454
455 if (!pcity) {
456 return;
457 }
458
459 if (are_universals_equal(&pcity->production, &prod)) {
460 /* The client probably shouldn't send such a packet. */
461 return;
462 }
463
464 if (!can_city_build_now(pcity, &prod)) {
465 return;
466 }
467 if (!city_can_change_build(pcity)) {
468 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
469 _("You have bought this turn, can't change."));
470 return;
471 }
472
474
475 city_refresh(pcity);
476 sanity_check_city(pcity);
477 send_city_info(pplayer, pcity);
478}
479
480/**********************************************************************/
483void handle_city_rename(struct player *pplayer, int city_id,
484 const char *name)
485{
486 struct city *pcity = player_city_by_number(pplayer, city_id);
487 char message[1024];
488
489 if (pcity == NULL) {
490 return;
491 }
492
493 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
494 notify_player(pplayer, pcity->tile, E_BAD_COMMAND,
495 ftc_server, "%s", message);
496 return;
497 }
498
499 city_name_set(pcity, name);
500 city_refresh(pcity);
501 send_city_info(NULL, pcity);
502}
503
504/**********************************************************************/
508void handle_city_options_req(struct player *pplayer, int city_id,
509 bv_city_options options)
510{
511 struct city *pcity = player_city_by_number(pplayer, city_id);
512
513 if (!pcity) {
514 return;
515 }
516
517 pcity->city_options = options;
518
519 send_city_info(pplayer, pcity);
520}
521
522/**********************************************************************/
525void handle_city_rally_point(struct player *pplayer,
526 const struct packet_city_rally_point *packet)
527{
528 struct city *pcity = player_city_by_number(pplayer, packet->id);
529
530 if (NULL != pcity) {
531 city_rally_point_receive(packet, pcity);
532 send_city_info(pplayer, pcity);
533 }
534}
535
536/**********************************************************************/
539void handle_web_cma_set(struct player *pplayer, int id,
540 const struct cm_parameter *param)
541{
542 /* Supported only in freeciv-web builds for now -
543 * Let's be cautious for now, and not give any chance
544 * of client requests of server side CMA to overload
545 * server from a standard build. */
546#ifdef FREECIV_WEB
547 struct city *pcity = player_city_by_number(pplayer, id);
548
549 if (pcity != NULL) {
550 if (pcity->cm_parameter == NULL) {
551 pcity->cm_parameter = fc_calloc(1, sizeof(struct cm_parameter));
552 }
553
554 cm_copy_parameter(pcity->cm_parameter, param);
555 pcity->server.synced = FALSE;
556
558
559 sync_cities();
560 }
561#endif /* FREECIV_WEB */
562}
563
564/**********************************************************************/
567void handle_web_cma_clear(struct player *pplayer, int id)
568{
569 struct city *pcity = player_city_by_number(pplayer, id);
570
571 if (pcity != NULL && pcity->cm_parameter != NULL) {
572 free(pcity->cm_parameter);
573 pcity->cm_parameter = NULL;
574 send_city_info(pplayer, pcity);
575 }
576}
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5044
struct act_prob action_prob_vs_tile(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4562
bool is_free_worked(const struct city *pcity, const struct tile *ptile)
Definition city.c:3597
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:737
void city_name_set(struct city *pcity, const char *new_name)
Definition city.c:1141
bool can_city_build_now(const struct city *pcity, const struct universal *target)
Definition city.c:1011
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Definition city.c:1061
bool city_map_includes_tile(const struct city *const pcity, const struct tile *map_tile)
Definition city.c:293
citizens city_specialists(const struct city *pcity)
Definition city.c:3313
void city_rally_point_receive(const struct packet_city_rally_point *packet, struct city *pcity)
Definition city.c:3637
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1452
bool city_production_is_genus(const struct city *pcity, enum impr_genus_id genus)
Definition city.c:717
bool city_can_change_build(const struct city *pcity)
Definition city.c:1075
void handle_city_change(struct player *pplayer, int city_id, int production_kind, int production_value)
Definition cityhand.c:434
void handle_city_options_req(struct player *pplayer, int city_id, bv_city_options options)
Definition cityhand.c:508
void handle_city_rally_point(struct player *pplayer, const struct packet_city_rally_point *packet)
Definition cityhand.c:525
void handle_city_name_suggestion_req(struct player *pplayer, int unit_id)
Definition cityhand.c:59
void handle_city_worklist(struct player *pplayer, int city_id, const struct worklist *worklist)
Definition cityhand.c:383
void handle_city_buy(struct player *pplayer, int city_id)
Definition cityhand.c:401
void handle_city_change_specialist(struct player *pplayer, int city_id, Specialist_type_id from, Specialist_type_id to)
Definition cityhand.c:91
void really_handle_city_buy(struct player *pplayer, struct city *pcity)
Definition cityhand.c:293
void handle_web_cma_set(struct player *pplayer, int id, const struct cm_parameter *param)
Definition cityhand.c:539
void handle_city_sell(struct player *pplayer, int city_id, int build_id)
Definition cityhand.c:278
void handle_city_make_worker(struct player *pplayer, int city_id, int tile_id)
Definition cityhand.c:169
void handle_city_refresh(struct player *pplayer, int city_id)
Definition cityhand.c:415
void handle_city_make_specialist(struct player *pplayer, int city_id, int tile_id)
Definition cityhand.c:122
void handle_city_rename(struct player *pplayer, int city_id, const char *name)
Definition cityhand.c:483
void really_handle_city_sell(struct player *pplayer, struct city *pcity, struct impr_type *pimprove)
Definition cityhand.c:240
void handle_web_cma_clear(struct player *pplayer, int id)
Definition cityhand.c:567
void city_map_update_empty(struct city *pcity, struct tile *ptile)
Definition citytools.c:3252
const char * city_name_suggestion(struct player *pplayer, struct tile *ptile)
Definition citytools.c:453
int city_production_buy_gold_cost(const struct city *pcity)
Definition citytools.c:3623
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2351
void sync_cities(void)
Definition citytools.c:3326
void change_build_target(struct player *pplayer, struct city *pcity, struct universal *target, enum event_type event)
Definition citytools.c:3163
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:369
void do_sell_building(struct player *pplayer, struct city *pcity, struct impr_type *pimprove, const char *reason)
Definition citytools.c:2980
void city_map_update_worker(struct city *pcity, struct tile *ptile)
Definition citytools.c:3266
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:365
bool city_refresh(struct city *pcity)
Definition cityturn.c:158
void city_refresh_for_player(struct player *pplayer)
Definition cityturn.c:181
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Definition cm.c:2171
char * incite_cost
Definition comments.c:74
#define MAX_LEN_MSG
Definition conn_types.h:37
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:366
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:356
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
int Specialist_type_id
Definition fc_types.h:379
test_result
Definition fc_types.h:1225
@ TR_ALREADY_SOLD
Definition fc_types.h:1228
@ TR_SUCCESS
Definition fc_types.h:1226
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
struct impr_type * improvement_by_number(const Impr_type_id id)
int impr_sell_gold(const struct impr_type *pimprove)
enum test_result test_player_sell_building_now(struct player *pplayer, struct city *pcity, const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define log_error(message,...)
Definition log.h:103
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:462
#define fc_calloc(n, esz)
Definition mem.h:38
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:292
void dlsend_packet_city_name_suggestion_info(struct conn_list *dest, int unit_id, const char *name)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
bool player_owns_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:261
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1146
struct universal universal_by_number(const enum universals_n kind, const int value)
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
#define sanity_check_city(x)
Definition sanitycheck.h:41
#define ARRAY_SIZE(x)
Definition shared.h:85
Specialist_type_id specialist_count(void)
Definition specialist.c:71
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
#define DEFAULT_SPECIALIST
Definition specialist.h:43
Definition city.h:320
bool did_sell
Definition city.h:380
int id
Definition city.h:326
int disbanded_shields
Definition city.h:391
bv_city_options city_options
Definition city.h:403
int turn_founded
Definition city.h:386
bool did_buy
Definition city.h:379
int anarchy
Definition city.h:384
struct worklist worklist
Definition city.h:401
struct universal production
Definition city.h:396
bool synced
Definition city.h:448
citizens specialists[SP_MAX]
Definition city.h:336
struct tile * tile
Definition city.h:322
int shield_stock
Definition city.h:368
int prod[O_LAST]
Definition city.h:358
struct city::@17::@19 server
struct cm_parameter * cm_parameter
Definition city.h:425
struct packet_game_info info
Definition game.h:89
struct conn_list * connections
Definition player.h:298
struct player_economic economic
Definition player.h:284
Definition tile.h:50
Definition unit.h:140
enum universals_n kind
Definition fc_types.h:880
universals_u value
Definition fc_types.h:879
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define tile_worked(_tile)
Definition tile.h:115
#define TILE_XY(ptile)
Definition tile.h:43
const struct unit_type * utype
Definition fc_types.h:698
const struct impr_type * building
Definition fc_types.h:691
#define unit_tile(_pu)
Definition unit.h:397
void illegal_action_msg(struct player *pplayer, const enum event_type event, struct unit *actor, const action_id stopped_action, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Definition unithand.c:2514
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
void worklist_copy(struct worklist *dst, const struct worklist *src)
Definition worklist.c:112