int jsc_notify_status_obj (flux_t h, jsc_handler_obj_f func, void *d) { int rc = -1; cb_pair_t *c = NULL; jscctx_t *ctx = NULL; if (!func) goto done; if (reg_newjob_hdlr (h, new_job_cb) == -1) { flux_log (h, LOG_ERR, "jsc_notify_status: reg_newjob_hdlr failed"); goto done; } ctx = getctx (h); c = (cb_pair_t *) xzmalloc (sizeof(*c)); c->cb = func; c->arg = d; if (zlist_append (ctx->callbacks, c) < 0) goto done; zlist_freefn (ctx->callbacks, c, free, true); rc = 0; done: return rc; }
int allocate_resources (flux_t h, resrc_tree_t *selected_tree, int64_t job_id, int64_t starttime, int64_t endtime) { int rc = -1; if (selected_tree) { rc = resrc_tree_allocate (selected_tree, job_id, starttime, endtime); if (!rc) { int64_t *completion_time = xzmalloc (sizeof(int64_t)); *completion_time = endtime; rc = zlist_append (completion_times, completion_time); zlist_freefn (completion_times, completion_time, free, true); flux_log (h, LOG_DEBUG, "Allocated job %"PRId64" from %"PRId64" to " "%"PRId64"", job_id, starttime, *completion_time); } } return rc; }
static int notify_status_obj (flux_t *h, jsc_handler_obj_f func, void *d) { int rc = -1; cb_pair_t *c = NULL; jscctx_t *ctx = NULL; flux_msg_handler_t **handlers; if (!func) goto done; if (flux_event_subscribe (h, "wreck.state.") < 0) { flux_log_error (h, "subscribing to job event"); rc = -1; goto done; } if (flux_event_subscribe (h, "jsc.state.") < 0) { flux_log_error (h, "subscribing to job event"); rc = -1; goto done; } if (flux_msg_handler_addvec (h, htab, NULL, &handlers) < 0) { flux_log_error (h, "registering resource event handler"); rc = -1; goto done; } ctx = getctx (h); ctx->handlers = handlers; c = (cb_pair_t *) xzmalloc (sizeof(*c)); c->cb = func; c->arg = d; if (zlist_append (ctx->callbacks, c) < 0) goto done; zlist_freefn (ctx->callbacks, c, free, true); rc = 0; done: return rc; }
zlist_t * zinterface_list () { zlist_t *ifaces = zlist_new(); assert(ifaces); #if defined (HAVE_GETIFADDRS) struct ifaddrs *interfaces; if (getifaddrs (&interfaces) == 0) { struct ifaddrs *interface = interfaces; while (interface) { // On Solaris, loopback interfaces have a NULL in ifa_broadaddr if (interface->ifa_broadaddr && s_check_flags(interface->ifa_flags) && interface->ifa_addr && (interface->ifa_addr->sa_family == AF_INET)) { inaddr_t address = *(inaddr_t*) interface->ifa_addr; inaddr_t netmask = *(inaddr_t*) interface->ifa_netmask; inaddr_t broadcast = *(inaddr_t*) interface->ifa_broadaddr; // If the returned broadcast address is the same as source // address, build the broadcast address from the source // address and netmask. if (address.sin_addr.s_addr == broadcast.sin_addr.s_addr) broadcast.sin_addr.s_addr |= ~(netmask.sin_addr.s_addr); zinterface_t* ziface = s_zinterface_new(interface->ifa_name, address, netmask, broadcast); zlist_append(ifaces, ziface); zlist_freefn(ifaces, ziface, s_freefn, true); } interface = interface->ifa_next; } } freeifaddrs (interfaces); # elif defined (__UNIX__) int sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock != -1) { int rc; int num_interfaces = 0; struct ifconf ifconfig; ifconfig.ifc_len = 0; ifconfig.ifc_req = NULL; rc = ioctl (sock, SIOCGIFCONF, (caddr_t) &ifconfig, sizeof (struct ifconf)); if (rc != -1) { ifconfig.ifc_buf = calloc(1, ifconfig.ifc_len); rc = ioctl (sock, SIOCGIFCONF, (caddr_t) &ifconfig, sizeof (struct ifconf)); if (rc != -1) { num_interfaces = ifconfig.ifc_len / sizeof (struct ifreq); } } for (int i=0; i<num_interfaces; i++) { struct ifreq* ifr = &ifconfig.ifc_req[i]; rc = ioctl (sock, SIOCGIFFLAGS, (caddr_t) ifr, sizeof (struct ifreq)); if (rc == -1) continue; if (!s_check_flags(ifr->ifr_flags)) continue; ifr->ifr_addr.sa_family = AF_INET; // Get interface address rc = ioctl (sock, SIOCGIFADDR, (caddr_t) ifr, sizeof (struct ifreq)); if (rc == -1) continue; inaddr_t address = *((inaddr_t*) &ifr->ifr_addr); // Get interface netmask rc = ioctl (sock, SIOCGIFBRDADDR, (caddr_t) ifr, sizeof (struct ifreq)); if (rc == -1) continue; inaddr_t broadcast = *((inaddr_t*) &ifr->ifr_addr); // Get interface broadcast address rc = ioctl (sock, SIOCGIFNETMASK, (caddr_t) ifr, sizeof (struct ifreq)); if (rc == -1) continue; inaddr_t netmask = *((inaddr_t*) &ifr->ifr_addr); zinterface_t* ziface = s_zinterface_new(ifr->ifr_name, address, netmask, broadcast); zlist_append(ifaces, ziface); zlist_freefn(ifaces, ziface, s_freefn, true); } close(sock); } # elif defined (__WINDOWS__) ULONG addr_size = 0; DWORD rc = GetAdaptersAddresses (AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &addr_size); assert (rc == ERROR_BUFFER_OVERFLOW); PIP_ADAPTER_ADDRESSES pip_addresses = (PIP_ADAPTER_ADDRESSES) malloc (addr_size); rc = GetAdaptersAddresses (AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, pip_addresses, &addr_size); assert (rc == NO_ERROR); PIP_ADAPTER_ADDRESSES cur_address = pip_addresses; while (cur_address) { PIP_ADAPTER_UNICAST_ADDRESS pUnicast = cur_address->FirstUnicastAddress; PIP_ADAPTER_PREFIX pPrefix = cur_address->FirstPrefix; PWCHAR friendlyName = cur_address->FriendlyName; size_t friendlyLength = 0; size_t asciiSize = wcstombs(0, friendlyName, 0) + 1; char *asciiFriendlyName = (char*) zmalloc(asciiSize); friendlyLength = wcstombs(asciiFriendlyName, friendlyName, asciiSize); bool valid = (cur_address->OperStatus == IfOperStatusUp) && (pUnicast && pPrefix) && (pUnicast->Address.lpSockaddr->sa_family == AF_INET) && (pPrefix->PrefixLength <= 32); if (valid) { inaddr_t address = *(inaddr_t*) pUnicast->Address.lpSockaddr; inaddr_t netmask; netmask.sin_addr.s_addr = htonl((0xffffffffU) << (32 - pPrefix->PrefixLength)); inaddr_t broadcast = address; broadcast.sin_addr.s_addr |= ~(netmask.sin_addr.s_addr); zinterface_t* ziface = s_zinterface_new(asciiFriendlyName, address, netmask, broadcast); zlist_append(ifaces, ziface); zlist_freefn(ifaces, ziface, s_freefn, true); } free(asciiFriendlyName); cur_address = cur_address->Next; } free (pip_addresses); # else # error "Interface detection TBD on this operating system" # endif return ifaces; }
void ztns_test (bool verbose) { printf (" * ztns: "); // Strings ztns_t *tnetstr = ztns_new (); char *data_str = "Hello World!"; char *tnetstr_str = "12:Hello World!,"; int rc = ztns_append_str (tnetstr, data_str); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_str)); char * index = tnetstr_str; char *result_str = (char *)ztns_parse (&index); assert (streq (index, "")); assert (streq (result_str, data_str)); free (result_str); ztns_destroy (&tnetstr); tnetstr = ztns_new (); char *data_empty_str = ""; char *tnetstr_empty_str = "0:,"; rc = ztns_append_str (tnetstr, data_empty_str); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_empty_str)); index = tnetstr_empty_str; result_str = (char *)ztns_parse (&index); assert (streq (index, "")); assert (streq (result_str, data_empty_str)); free (result_str); ztns_destroy (&tnetstr); tnetstr = ztns_new (); char *data_tnet_str = "12:Hello World!,"; tnetstr_str = "16:12:Hello World!,,"; rc = ztns_append_str (tnetstr, data_tnet_str); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_str)); index = tnetstr_str; result_str = (char *)ztns_parse (&index); assert (streq (index, "")); assert (streq (result_str, data_tnet_str)); free (result_str); ztns_destroy (&tnetstr); // Numbers tnetstr = ztns_new (); long long data_llong = 34; char *tnetstr_llong = "2:34#"; rc = ztns_append_llong (tnetstr, data_llong); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_llong)); index = tnetstr_llong; long long *result_llong = (long long *)ztns_parse (&index); assert (streq (index, "")); assert (data_llong == *result_llong); free (result_llong); ztns_destroy (&tnetstr); tnetstr = ztns_new (); rc = ztns_append_llong (tnetstr, LLONG_MAX); assert (0 == rc); index = ztns_get (tnetstr); result_llong = (long long *)ztns_parse (&index); assert (streq (index, "")); assert (LLONG_MAX == *result_llong); free (result_llong); ztns_destroy (&tnetstr); tnetstr = ztns_new (); rc = ztns_append_llong (tnetstr, LLONG_MIN); assert (0 == rc); index = ztns_get (tnetstr); result_llong = (long long *)ztns_parse (&index); assert (streq (index, "")); assert (LLONG_MIN == *result_llong); free (result_llong); ztns_destroy (&tnetstr); char *tnetstr_llong_max_plus_one = "19:9223372036854775808#"; index = tnetstr_llong_max_plus_one; result_llong = (long long *)ztns_parse (&index); assert (NULL == result_llong); char *tnetstr_llong_min_minus_one = "20:-9223372036854775809#"; index = tnetstr_llong_min_minus_one; result_llong = (long long *)ztns_parse (&index); assert (NULL == result_llong); char *tnetstr_float_not_llong = "8:15.75331#"; index = tnetstr_float_not_llong; result_llong = (long long *)ztns_parse (&index); assert (NULL == result_llong); // Floats // ### These are a bastard to test and until there's a real use // I've got better things to do with my time //tnetstr = ztns_new (); //float data_float = 15.75331; //char *tnetstr_float = "8:15.75331^"; //rc = ztns_append_float (tnetstr, data_float); //assert (0 == rc); //assert (streq (ztns_get (tnetstr), tnetstr_float)); //index = tnetstr_float; //float *result_float = (float *)ztns_parse (&index); //assert (streq (index, "")); //assert (data_float == *result_float); //free (result_float); //ztns_destroy (&tnetstr); // Booleans tnetstr = ztns_new (); bool data_bool = true; char *tnetstr_bool = "4:true!"; rc = ztns_append_bool (tnetstr, data_bool); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_bool)); index = tnetstr_bool; bool *result_bool = (bool *)ztns_parse (&index); assert (streq (index, "")); assert (data_bool == *result_bool); free (result_bool); ztns_destroy (&tnetstr); // NULL tnetstr = ztns_new (); char *tnetstr_null = "0:~"; rc = ztns_append_null (tnetstr); assert (streq (ztns_get (tnetstr), tnetstr_null)); index = tnetstr_null; void *result_null = ztns_parse (&index); assert (streq (index, "")); assert (NULL == result_null); ztns_destroy (&tnetstr); // Dictionaries zhash_t *dict = zhash_new (); zhash_t *empty_hash = zhash_new (); zlist_t *empty_list = zlist_new (); zhash_insert (dict, "STRING", data_str); zhash_insert (dict, "INTEGER", &data_llong); zhash_insert (dict, "BOOLEAN", &data_bool); zhash_insert (dict, "HASH", empty_hash); zhash_freefn (dict, "HASH", &s_zhash_free_fn); zhash_insert (dict, "LIST", empty_list); zhash_freefn (dict, "LIST", &s_zlist_free_fn); tnetstr = ztns_new (); rc = ztns_append_dict (tnetstr, dict, &s_tnetstr_foreach_dict_fn_test); assert (0 == rc); zhash_destroy (&dict); index = ztns_get (tnetstr); zhash_t *result_dict = (zhash_t *)ztns_parse (&index); assert (streq (index, "")); assert (NULL != result_dict); zhash_autofree (result_dict); char *item_str = (char *)zhash_lookup (result_dict, "STRING"); assert (streq (data_str, item_str)); long long *item_llong = (long long *)zhash_lookup (result_dict, "INTEGER"); assert (*item_llong == data_llong); bool *item_bool = (bool *)zhash_lookup (result_dict, "BOOLEAN"); assert (*item_bool == data_bool); zhash_t *item_hash = (zhash_t *)zhash_lookup (result_dict, "HASH"); assert (0 == zhash_size (item_hash)); zlist_t *item_list = (zlist_t *)zhash_lookup (result_dict, "LIST"); assert (0 == zlist_size (item_list)); zhash_destroy (&result_dict); ztns_destroy (&tnetstr); // Lists zlist_t *list = zlist_new (); empty_hash = zhash_new (); empty_list = zlist_new (); zlist_append (list, data_str); zlist_append (list, &data_llong); zlist_append (list, &data_bool); zlist_append (list, empty_hash); zlist_freefn (list, empty_hash, &s_zhash_free_fn, true); zlist_append (list, empty_list); zlist_freefn (list, empty_list, &s_zlist_free_fn, true); tnetstr = ztns_new (); rc = ztns_append_list (tnetstr, list, &s_tnetstr_foreach_list_fn_test); assert (0 == rc); zlist_destroy (&list); index = ztns_get (tnetstr); zlist_t *result_list = (zlist_t *)ztns_parse (&index); assert (streq (index, "")); assert (NULL != result_list); item_str = (char *)zlist_pop (result_list); assert (streq (data_str, item_str)); free (item_str); item_llong = (long long *)zlist_pop (result_list); assert (*item_llong == data_llong); free (item_llong); item_bool = (bool *)zlist_pop (result_list); assert (*item_bool == data_bool); free (item_bool); item_hash = (zhash_t *)zlist_pop (result_list); assert (0 == zhash_size (item_hash)); zhash_destroy (&item_hash); item_list = (zlist_t *)zlist_pop (result_list); assert (0 == zlist_size (item_list)); zlist_destroy (&item_list); zlist_destroy (&result_list); ztns_destroy (&tnetstr); printf ("OK\n"); }
void * ztns_parse (char **p_tnetstr) { assert (p_tnetstr); if (NULL == p_tnetstr) return NULL; char * tnetstr = *p_tnetstr; assert (tnetstr); if (NULL == tnetstr) return NULL; char * colon = NULL; long int length = strtol (tnetstr, &colon, 10); if (0 == length && '0' != *tnetstr) return NULL; char type = *(colon + COLON_LENGTH + length); void * result = NULL; switch (type) { case ',': { char *str = (char *)malloc ((length + NULL_LENGTH) * sizeof(char)); assert (str); if (!str) { free (result); return NULL; } memcpy(str, colon + COLON_LENGTH, length); *(str + length) = '\0'; result = str; break; } case '#': { long long *number = malloc (sizeof(long long)); assert (number); if (!number) return NULL; char * check; *number = strtoll (colon + COLON_LENGTH, &check, 10); if (*check != type) { free (number); return NULL; } if (LLONG_MAX == *number) { uint llong_max_str_len = s_get_str_len (LLONG_MAX); char llong_max_str[llong_max_str_len + NULL_LENGTH]; snprintf (llong_max_str, llong_max_str_len + NULL_LENGTH, "%lld", LLONG_MAX); uint index = 0; while (*(colon + COLON_LENGTH + index) == *(llong_max_str + index)) { ++index; } if (('#' != *(colon + COLON_LENGTH + index)) || ('\0' != *(llong_max_str + index))) { free (number); return NULL; } } else if (LLONG_MIN == *number) { uint llong_min_str_len = s_get_str_len (LLONG_MIN); char llong_min_str[llong_min_str_len + NULL_LENGTH]; snprintf (llong_min_str, llong_min_str_len + NULL_LENGTH, "%lld", LLONG_MIN); uint index = 0; while (*(colon + COLON_LENGTH + index) == *(llong_min_str + index)) ++index; if (('#' != *(colon + COLON_LENGTH + index)) || ('\0' != *(llong_min_str + index))) { free (number); return NULL; } } result = number; break; } case '^': { float * flt = malloc (sizeof(float)); *flt = strtof (colon + COLON_LENGTH, NULL); result = flt; break; } case '!': { bool *boolean = malloc (sizeof(bool)); char first_char = *(colon + COLON_LENGTH); switch (first_char) { case 't': *boolean = true; break; case 'f': *boolean = false; break; default: free (boolean); return NULL; } result = boolean; break; } case '~': { // Nothing to do break; } case '}': { zhash_t *dict = zhash_new (); char * index = colon + COLON_LENGTH; while ('}' != *index) { if (index > (colon + COLON_LENGTH + length)) { zhash_destroy(&dict); return NULL; } char * key = ztns_parse (&index); if (!key) { zhash_destroy (&dict); return NULL; } void * item = ztns_parse (&index); if (!item) { zhash_destroy (&dict); return NULL; } int rc = zhash_insert (dict, key, item); // Apply the correct free function char item_type = *(index - TYPE_CHAR_LENGTH); switch (item_type) { case '}': if (NULL == zhash_freefn (dict, key, &s_free_dict)) { zhash_t *item_as_dict = (zhash_t *)item; zhash_destroy (&item_as_dict); zhash_destroy (&dict); return NULL; } break; case ']': if (NULL == zhash_freefn (dict, key, &s_free_list)) { zlist_t *item_as_list = (zlist_t *)item; zlist_destroy (&item_as_list); zhash_destroy (&dict); return NULL; } break; default: if (NULL == zhash_freefn (dict, key, &free)) { free (item); zhash_destroy (&dict); return NULL; } break; } // Free the key as we've taken a copy free (key); } result = dict; break; } case ']': { zlist_t *list = zlist_new (); char * index = colon + COLON_LENGTH; while (']' != *index) { if (index > (colon + COLON_LENGTH + length)) { zlist_destroy(&list); return NULL; } void * item = ztns_parse (&index); int rc = zlist_append (list, item); // Apply the correct free function char item_type = *(index - 1); switch (item_type) { case '}': if (NULL == zlist_freefn (list, item, &s_free_dict, true)) { zhash_t *item_as_dict = (zhash_t *)item; zhash_destroy (&item_as_dict); zlist_destroy (&list); return NULL; } break; case ']': if (NULL == zlist_freefn (list, item, &s_free_list, true)) { zlist_t *item_as_list = (zlist_t *)item; zlist_destroy (&item_as_list); zlist_destroy (&list); return NULL; } break; default: if (NULL == zlist_freefn (list, item, &free, true)) { free (item); zlist_destroy (&list); return NULL; } break; } } result = list; break; } default: return NULL; } *p_tnetstr = colon + COLON_LENGTH + length + TYPE_CHAR_LENGTH; return result; }
JNIEXPORT jlong JNICALL Java_zlist__1_1freefn (JNIEnv *env, jclass c, jlong self, jlong item, jlong fn, jboolean at_tail) { jlong freefn_ = (jlong) zlist_freefn ((zlist_t *) self, (void *) item, (zlist_free_fn *) fn, (bool) at_tail); return freefn_; }
void zlist_test (int verbose) { printf (" * zlist: "); // @selftest zlist_t *list = zlist_new (); assert (list); assert (zlist_size (list) == 0); // Three items we'll use as test data // List items are void *, not particularly strings char *cheese = "boursin"; char *bread = "baguette"; char *wine = "bordeaux"; zlist_append (list, cheese); assert (zlist_size (list) == 1); zlist_append (list, bread); assert (zlist_size (list) == 2); zlist_append (list, wine); assert (zlist_size (list) == 3); assert (zlist_head (list) == cheese); assert (zlist_next (list) == cheese); assert (zlist_first (list) == cheese); assert (zlist_tail (list) == wine); assert (zlist_next (list) == bread); assert (zlist_first (list) == cheese); assert (zlist_next (list) == bread); assert (zlist_next (list) == wine); assert (zlist_next (list) == NULL); // After we reach end of list, next wraps around assert (zlist_next (list) == cheese); assert (zlist_size (list) == 3); zlist_remove (list, wine); assert (zlist_size (list) == 2); assert (zlist_first (list) == cheese); zlist_remove (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == bread); zlist_remove (list, bread); assert (zlist_size (list) == 0); zlist_append (list, cheese); zlist_append (list, bread); assert (zlist_last (list) == bread); zlist_remove (list, bread); assert (zlist_last (list) == cheese); zlist_remove (list, cheese); assert (zlist_last (list) == NULL); zlist_push (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == cheese); zlist_push (list, bread); assert (zlist_size (list) == 2); assert (zlist_first (list) == bread); assert (zlist_item (list) == bread); zlist_append (list, wine); assert (zlist_size (list) == 3); assert (zlist_first (list) == bread); zlist_t *sub_list = zlist_dup (list); assert (sub_list); assert (zlist_size (sub_list) == 3); zlist_sort (list, s_compare); char *item; item = (char *) zlist_pop (list); assert (item == bread); item = (char *) zlist_pop (list); assert (item == wine); item = (char *) zlist_pop (list); assert (item == cheese); assert (zlist_size (list) == 0); assert (zlist_size (sub_list) == 3); zlist_push (list, sub_list); zlist_t *sub_list_2 = zlist_dup (sub_list); zlist_append (list, sub_list_2); assert (zlist_freefn (list, sub_list, &s_zlist_free, false) == sub_list); assert (zlist_freefn (list, sub_list_2, &s_zlist_free, true) == sub_list_2); // Destructor should be safe to call twice zlist_destroy (&list); zlist_destroy (&list); assert (list == NULL); // @end printf ("OK\n"); }
void zlist_test (bool verbose) { printf (" * zlist: "); // @selftest zlist_t *list = zlist_new (); assert (list); assert (zlist_size (list) == 0); // Three items we'll use as test data // List items are void *, not particularly strings char *cheese = "boursin"; char *bread = "baguette"; char *wine = "bordeaux"; zlist_append (list, cheese); assert (zlist_size (list) == 1); assert ( zlist_exists (list, cheese)); assert (!zlist_exists (list, bread)); assert (!zlist_exists (list, wine)); zlist_append (list, bread); assert (zlist_size (list) == 2); assert ( zlist_exists (list, cheese)); assert ( zlist_exists (list, bread)); assert (!zlist_exists (list, wine)); zlist_append (list, wine); assert (zlist_size (list) == 3); assert ( zlist_exists (list, cheese)); assert ( zlist_exists (list, bread)); assert ( zlist_exists (list, wine)); assert (zlist_head (list) == cheese); assert (zlist_next (list) == cheese); assert (zlist_first (list) == cheese); assert (zlist_tail (list) == wine); assert (zlist_next (list) == bread); assert (zlist_first (list) == cheese); assert (zlist_next (list) == bread); assert (zlist_next (list) == wine); assert (zlist_next (list) == NULL); // After we reach end of list, next wraps around assert (zlist_next (list) == cheese); assert (zlist_size (list) == 3); zlist_remove (list, wine); assert (zlist_size (list) == 2); assert (zlist_first (list) == cheese); zlist_remove (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == bread); zlist_remove (list, bread); assert (zlist_size (list) == 0); zlist_append (list, cheese); zlist_append (list, bread); assert (zlist_last (list) == bread); zlist_remove (list, bread); assert (zlist_last (list) == cheese); zlist_remove (list, cheese); assert (zlist_last (list) == NULL); zlist_push (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == cheese); zlist_push (list, bread); assert (zlist_size (list) == 2); assert (zlist_first (list) == bread); assert (zlist_item (list) == bread); zlist_append (list, wine); assert (zlist_size (list) == 3); assert (zlist_first (list) == bread); zlist_t *sub_list = zlist_dup (list); assert (sub_list); assert (zlist_size (sub_list) == 3); zlist_sort (list, s_compare); char *item; item = (char *) zlist_pop (list); assert (item == bread); item = (char *) zlist_pop (list); assert (item == wine); item = (char *) zlist_pop (list); assert (item == cheese); assert (zlist_size (list) == 0); assert (zlist_size (sub_list) == 3); zlist_push (list, sub_list); zlist_t *sub_list_2 = zlist_dup (sub_list); zlist_append (list, sub_list_2); assert (zlist_freefn (list, sub_list, &s_zlist_free, false) == sub_list); assert (zlist_freefn (list, sub_list_2, &s_zlist_free, true) == sub_list_2); zlist_destroy (&list); // Test autofree functionality list = zlist_new (); assert (list); zlist_autofree (list); // Set equals function otherwise equals will not work as autofree copies strings zlist_comparefn (list, s_compare); zlist_push (list, bread); zlist_append (list, cheese); assert (zlist_size (list) == 2); zlist_append (list, wine); assert (zlist_exists (list, wine)); zlist_remove (list, wine); assert (!zlist_exists (list, wine)); assert (streq ((const char *) zlist_first (list), bread)); item = (char *) zlist_pop (list); assert (streq (item, bread)); free (item); item = (char *) zlist_pop (list); assert (streq (item, cheese)); free (item); zlist_destroy (&list); assert (list == NULL); // @end printf ("OK\n"); }
/// // Set a free function for the specified list item. When the item is // destroyed, the free function, if any, is called on that item. // Use this when list items are dynamically allocated, to ensure that // you don't have memory leaks. You can pass 'free' or NULL as a free_fn. // Returns the item, or NULL if there is no such item. void * QZlist::freefn (void *item, zlist_free_fn fn, bool atTail) { void * rv = zlist_freefn (self, item, fn, atTail); return rv; }
/// // Set a free function for the specified list item. When the item is // destroyed, the free function, if any, is called on that item. // Use this when list items are dynamically allocated, to ensure that // you don't have memory leaks. You can pass 'free' or NULL as a free_fn. // Returns the item, or NULL if there is no such item. void *QmlZlist::freefn (void *item, zlist_free_fn fn, bool atTail) { return zlist_freefn (self, item, fn, atTail); };