static c_type createKeyType( const c_char *name, c_array keyList) { c_base base; c_type foundType; c_char *typeName; c_char keyName[16]; c_long i, length, sres; c_array members; c_metaObject o; c_field field; if (keyList == NULL) { return NULL; } base = c_getBase(keyList); length = c_arraySize(keyList); if (length == 0) { return NULL; } o = c_metaDefine(c_metaObject(base),M_STRUCTURE); members = c_arrayNew(c_member_t(base),length); for (i=0;i<length;i++) { field = keyList[i]; assert(field != NULL); members[i] = (c_voidp)c_metaDefine(c_metaObject(base),M_MEMBER); sprintf(keyName,"field%d",i); c_specifier(members[i])->name = c_stringNew(base,keyName); c_specifier(members[i])->type = c_keep(c_fieldType(field)); } c_structure(o)->members = members; c_metaObject(o)->definedIn = c_metaObject(base); c_metaFinalize(o); #define KEY_NAME "<Key>" #define KEY_FORMAT "%s<Key>" if (name != NULL) { length = sizeof(KEY_NAME) + strlen(name); typeName = os_malloc(length); sres = snprintf(typeName,length,KEY_FORMAT,name); assert(sres == (length-1)); } else { assert(FALSE); length = 100; typeName = os_malloc(length); os_sprintf(typeName,PA_ADDRFMT KEY_NAME,(c_address)o); } #undef KEY_NAME #undef KEY_FORMAT foundType = c_type(c_metaBind(c_metaObject(base),typeName,o)); c_free(o); os_free(typeName); return foundType; }
struct v_messageExtCdrInfo * v_messageExtCdrInfoNew( c_type topicMessageType, const struct sd_cdrControl *control) { static const char headerTypeName[] = "kernelModule::v_messageExt"; c_base base = c_getBase (topicMessageType); c_property userDataProperty = c_property(c_metaResolve(c_metaObject(topicMessageType),"userData")); c_type topicDataType = userDataProperty->type; c_type headerClass = c_resolve (base, headerTypeName); c_type dataClass; c_type type; c_object o; c_array members; struct v_messageExtCdrInfo *xci; struct c_type_s const *tstk[2]; c_free(userDataProperty); /* Wrap user data in a class, so that we can make a struct with a pointer to it */ dataClass = c_type(c_metaDefine(c_metaObject(base), M_CLASS)); c_class(dataClass)->extends = NULL; o = c_metaDeclare(c_metaObject(dataClass), "userData", M_ATTRIBUTE); c_property(o)->type = c_keep(topicDataType); c_metaObject(dataClass)->definedIn = c_keep(base); c_metaFinalize(c_metaObject(dataClass)); c_free(o); /* Make a struct containing two pointers, one to the v_messageExt class, and one to the just-created anonymous dataClass type, corresponding to struct v_messageExtCdrTmp */ type = c_type(c_metaDefine(c_metaObject(base),M_STRUCTURE)); members = c_arrayNew(c_member_t(base),2); members[0] = (c_voidp)c_metaDefine(c_metaObject(base),M_MEMBER); c_specifier(members[0])->name = c_stringNew(base,"h"); c_specifier(members[0])->type = c_keep(headerClass); members[1] = (c_voidp)c_metaDefine(c_metaObject(base),M_MEMBER); c_specifier(members[1])->name = c_stringNew(base,"d"); c_specifier(members[1])->type = c_keep(dataClass); c_structure(type)->members = members; c_metaObject(type)->definedIn = c_keep(base); c_metaFinalize(c_metaObject(type)); c_free(dataClass); c_free(headerClass); xci = os_malloc(sizeof(*xci)); xci->ci = sd_cdrInfoNewControl(type, control); /* Note: current simplistic annotation processing requires the annotations to be made in the order in which they are encountered when walking the type */ tstk[0] = type; tstk[1] = headerClass; if (sd_cdrNoteQuietRef(xci->ci, 2, tstk) < 0) { goto err_note; } tstk[1] = dataClass; if (sd_cdrNoteQuietRef(xci->ci, 2, tstk) < 0) { goto err_note; } if (sd_cdrCompile(xci->ci) < 0) { goto err_compile; } xci->vmsgType = c_keep(topicMessageType); c_free(type); return xci; err_compile: err_note: os_free(xci); c_free(type); return NULL; }