struct message *msg_feedback(const struct unit *u, struct order *ord, const char *name, const char *sig, ...) { va_list marker; const message_type *mtype = mt_find(name); char paramname[64]; const char *ic = sig; variant args[16]; variant var; memset(args, 0, sizeof(args)); if (ord == NULL) ord = u->thisorder; if (!mtype) { log_error("trying to create message of unknown type \"%s\"\n", name); return msg_message("missing_feedback", "unit region command name", u, u->region, ord, name); } var.v = (void *)u; arg_set(args, mtype, "unit", var); var.v = (void *)u->region; arg_set(args, mtype, "region", var); var.v = (void *)ord; arg_set(args, mtype, "command", var); va_start(marker, sig); while (*ic && !isalnum(*ic)) ic++; while (*ic) { char *oc = paramname; int i; while (isalnum(*ic)) *oc++ = *ic++; *oc = '\0'; for (i = 0; i != mtype->nparameters; ++i) { if (!strcmp(paramname, mtype->pnames[i])) break; } if (i != mtype->nparameters) { if (mtype->types[i]->vtype == VAR_VOIDPTR) { args[i].v = va_arg(marker, void *); } else if (mtype->types[i]->vtype == VAR_INT) { args[i].i = va_arg(marker, int); } else {
void test_message(CuTest *tc) { message *msg; message_type *mtype; test_setup(); mtype = mt_create(mt_new("custom", NULL), NULL, 0); CuAssertPtrEquals(tc, mtype, (void *)mt_find("custom")); CuAssertIntEquals(tc, 0, mtype->nparameters); CuAssertPtrEquals(tc, NULL, (void *)mtype->pnames); CuAssertPtrEquals(tc, NULL, (void *)mtype->types); msg = msg_message("custom", ""); CuAssertPtrNotNull(tc, msg); CuAssertIntEquals(tc, 1, msg->refcount); CuAssertPtrEquals(tc, NULL, msg->parameters); CuAssertPtrEquals(tc, mtype, (void *)msg->type); CuAssertPtrEquals(tc, msg, msg_addref(msg)); CuAssertIntEquals(tc, 2, msg->refcount); msg_release(msg); CuAssertIntEquals(tc, 1, msg->refcount); msg_release(msg); test_teardown(); }