/* * return the real type (typedef are resoved) for a key (from a keylist). * scope should be the data type. */ static c_type idl_getTypeOfKey( c_type scope, os_char* keyName) { c_iter fields = NULL; c_specifier sp; char *fieldName; /* Key field name consists of [<field>.]*<field> */ fields = c_splitString(keyName, "."); fieldName = c_iterTakeFirst(fields); /* find specificer (sp) corresponding to keylist field name */ while (fieldName != NULL) { if (scope) { sp = c_specifier(c_metaFindByName(c_metaObject(scope), fieldName, CQ_FIXEDSCOPE | CQ_MEMBER | CQ_CASEINSENSITIVE)); assert(sp && (strcmp(sp->name, fieldName) == 0)); scope = sp->type; } fieldName = c_iterTakeFirst(fields); } /* now scope is type of key. But it can be typedef. Determine the actual type. */ return c_typeActualType(scope); }
os_boolean idl_stacListItemIsMemberLocated( const c_char* list, const char* itemName) { os_boolean isDefined = OS_FALSE; if(list) { c_iter items; c_char* item; items = c_splitString(list, ","); while(c_iterLength(items) > 0 && !isDefined) { item = c_iterTakeFirst(items); if(item && 0 == strcmp(item, itemName)) { isDefined = OS_TRUE; } } } return isDefined; }
/* Check if there is a stac applied to the given key. */ c_bool idl_isStacDefFor( c_metaObject scope, c_char *typeName, c_char *key) { idl_stacDef stacDef = idl_stacDefDefGet(); idl_stacMap stacMap; c_ulong stacMapIdx; c_iter stacList; os_uint32 stacListSize; os_uint32 stacIdx; os_boolean stacDefFor = OS_FALSE; if (stacDef != NULL) { /* check all stac definition list elements */ for (stacMapIdx = 0; stacMapIdx < c_iterLength(stacDef->stacList) && !stacDefFor; stacMapIdx++) { stacMap = c_iterObject(stacDef->stacList, stacMapIdx); if (c_metaCompare(scope, stacMap->scope) == E_EQUAL && strcmp(typeName, stacMap->typeName) == 0) { /* for each stac in stacList, check if it's equal to key */ stacList = c_splitString(stacMap->stacList, ","); stacListSize = c_iterLength(stacList); if (stacListSize == 0) { stacDefFor = OS_TRUE; } else if(idl_stacDefOnlyExclusionsDefined(stacMap->stacList)) { if(!idl_stacDefIsFieldExcluded(stacMap->stacList, key)) { stacDefFor = OS_TRUE; } } else { for(stacIdx = 0; stacIdx < stacListSize; stacIdx++) { if (strcmp(c_iterTakeFirst(stacList), key) == 0) { stacDefFor = OS_TRUE; } } } } } } return stacDefFor; }
os_boolean idl_stacDefOnlyExclusionsDefined( os_char* stacList) { os_boolean onlyExclusions = OS_TRUE; c_iter memberNames; os_char* memberName; memberNames = c_splitString(stacList, ","); memberName = c_iterTakeFirst(memberNames); while(memberName) { if(strlen(memberName) > 0 && memberName[0] != '!') { onlyExclusions = OS_FALSE; } memberName = c_iterTakeFirst(memberNames); } return onlyExclusions; }
static void checkTopicKeyList ( v_entity e, c_voidp arg) { c_array keyList = v_topicMessageKeyList(e); checkTopicKeyListArg *info = (checkTopicKeyListArg *) arg; c_long i; gapi_char *name; c_long size; c_iter iter; gapi_boolean equal = TRUE; iter = c_splitString(info->keyList, " \t,"); if ( iter ) { size = c_arraySize(keyList); for ( i = 0; equal && (i < size); i++ ) { name = (gapi_char *)c_iterResolve(iter, topicKeyCompare, keyNameFromField(keyList[i])); if ( !name ) { equal = FALSE; OS_REPORT_2(OS_API_INFO, "gapi::kernelCheckTopicKeyList", 0, "incompatible key <%s> found for topic <%s>", keyNameFromField(keyList[i]), v_entityName(e)); } } name = c_iterTakeFirst(iter); while ( name ) { os_free(name); name = c_iterTakeFirst(iter); } c_iterFree(iter); } info->equal = equal; }
os_boolean idl_stacDefIsFieldExcluded( const os_char* stacList, const os_char* member) { os_boolean isExcluded = OS_FALSE; c_iter memberNames; os_char* memberName; memberNames = c_splitString(stacList, ","); memberName = c_iterTakeFirst(memberNames); while(memberName) { if(strlen(memberName) > 1 && memberName[0] == '!') { if(0 == strcmp(member, &(memberName[1]))) { isExcluded = OS_TRUE; } } memberName = c_iterTakeFirst(memberNames); } return isExcluded; }
c_field c_fieldNew ( c_type type, const c_char *fieldName) { c_array path; c_field field; c_metaObject o; c_long n,length; c_address offset; c_iter nameList, refsList; c_string name; c_base base; if ((fieldName == NULL) || (type == NULL)) { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "illegal parameter"); return NULL; } base = c__getBase(type); if (base == NULL) { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "failed to retreive base"); return NULL; } nameList = c_splitString(fieldName,"."); length = c_iterLength(nameList); field = NULL; if (length > 0) { o = NULL; offset = 0; refsList = NULL; path = c_newArray(c_fieldPath_t(base),length); if (path) { for (n=0;n<length;n++) { name = c_iterTakeFirst(nameList); o = c_metaResolve(c_metaObject(type),name); os_free(name); if (o == NULL) { c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL); c_iterFree(nameList); c_iterFree(refsList); c_free(path); return NULL; } path[n] = o; switch (c_baseObject(o)->kind) { case M_ATTRIBUTE: case M_RELATION: type = c_property(o)->type; offset += c_property(o)->offset; break; case M_MEMBER: type = c_specifier(o)->type; offset += c_member(o)->offset; break; default: c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL); c_iterFree(nameList); c_iterFree(refsList); c_free(path); return NULL; } switch (c_baseObject(type)->kind) { case M_INTERFACE: case M_CLASS: case M_COLLECTION: /*Longs are inserted in an iterator? Explanation please...*/ refsList = c_iterInsert(refsList,(c_voidp)offset); offset = 0; break; default: break; } } if (offset > 0) { refsList = c_iterInsert(refsList,(c_voidp)offset); } field = c_new(c_field_t(base)); field->name = c_stringNew(base,fieldName); field->path = path; field->type = c_keep(type); field->kind = c_metaValueKind(o); field->refs = NULL; if (refsList) { length = c_iterLength(refsList); field->offset = 0; if (length > 0) { field->refs = c_newArray(c_fieldRefs_t(base),length); if (field->refs) { for (n=(length-1);n>=0;n--) { field->refs[n] = c_iterTakeFirst(refsList); } } else { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "failed to allocate field->refs array"); c_free(field); field = NULL; } } c_iterFree(refsList); } else { field->offset = offset; } } else { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "failed to allocate field->path array"); c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL); c_iterFree(nameList); } c_iterFree(nameList); } else { OS_REPORT_1(OS_ERROR, "c_fieldNew failed",0, "failed to process field name <%s>", fieldName); } return field; }
static c_bool createMessageKeyList( c_type messageType, const c_char *topicKeyExpr, c_array *keyListRef) { c_array keyList; c_type fieldType; c_field field; c_iter splitNames, newNames; c_char *name, *newName; c_long i,length,sres; assert(keyListRef != NULL); *keyListRef = NULL; if (topicKeyExpr == NULL) { return TRUE; } newNames = NULL; splitNames = c_splitString(topicKeyExpr,", \t"); while ((name = c_iterTakeFirst(splitNames)) != NULL) { #define PATH_SEPARATOR "." #define PREFIX "userData" length = strlen(PREFIX) + sizeof(PATH_SEPARATOR) + strlen(name); newName = (char *)os_malloc(length); sres = snprintf(newName,length,"%s"PATH_SEPARATOR"%s",PREFIX, name); assert(sres == (length-1)); #undef PREFIX #undef PATH_SEPARATOR os_free(name); newNames = c_iterAppend(newNames,newName); } c_iterFree(splitNames); length = c_iterLength(newNames); if (length == 0) { return TRUE; } fieldType = c_field_t(c_getBase(messageType)); keyList = c_arrayNew(fieldType,length); c_free(fieldType); i=0; while ((name = c_iterTakeFirst(newNames)) != NULL) { field = c_fieldNew(messageType,name); if (field == NULL) { OS_REPORT_1(OS_API_INFO, "create message key list failed", 21, "specified key field name %s not found", name); os_free(name); c_iterFree(newNames); c_free(keyList); return FALSE; } keyList[i++] = field; os_free(name); } c_iterFree(newNames); *keyListRef = keyList; return TRUE; }
/* This operation scans through the list of items within the 'stac' pragma. * For each structure that is identified it will locate the corresponding * meta structure. It will then locate each member mentioned in the 'stac' * pragma within the member list of said meta structure. It will verify the * located member is indeed a character array. * It will then proceed to replace the meta data describing the located member * with new meta data with as goal to have the new meta data identify the member * as a string instead of as a character array. * All replaced meta data is stored in out variables to facilitate restore the * member list of the meta structure back into it's original configuration. * This operation is needed then the meta data of the found structure is * converted to XML. As the XML generation code is located in the database and * we do not want the database to get knowledge of the 'stac' pragma. */ c_iter idl_stacDefConvertAll( idl_stacDef stacDef) { os_uint32 size; os_uint32 i; idl_stacMap stacMapItem; c_structure structure; c_iter memberNames; os_uint32 memberNamesSize; os_uint32 j; os_char* memberName; os_int32 memberIndex; c_member member; c_member newMember; os_uint32* replacedIndex; idl_stacDefReplaceInfo replaceData; c_iter replaceInfo = NULL; c_base base; c_iter boundedStringToBeConverted; os_boolean stacCanBeApplied = OS_TRUE; os_boolean onlyExclusionlistings; if(stacDef) { /* Create collections to hold the original members and their respective * indexes in the member collection so we can easily restore the meta * structure to it's original configuration at a later time. */ replaceInfo = c_iterNew(NULL); size = c_iterLength (stacDef->stacList); for(i = 0; i < size; i++) { stacMapItem = c_iterObject (stacDef->stacList, i); /* find the matching structure in the meta data */ structure = idl_stacDefFindMetaStructureResolved( stacMapItem->scope, stacMapItem->typeName); assert(structure); replaceData = os_malloc(C_SIZEOF(idl_stacDefReplaceInfo)); replaceData->structure = structure; replaceData->replacedIndexes = c_iterNew(NULL); replaceData->replacedMembers = c_iterNew(NULL); memberNames = c_splitString(stacMapItem->stacList, ","); onlyExclusionlistings = idl_stacDefOnlyExclusionsDefined(stacMapItem->stacList); memberNamesSize = c_iterLength(memberNames); boundedStringToBeConverted = c_iterNew(NULL); if(memberNamesSize == 0 || onlyExclusionlistings) { os_uint32 membersSize; membersSize = c_arraySize(structure->members); for(j = 0; j < membersSize; j++) { member = c_member(structure->members[j]); memberName = c_specifier(member)->name; /* check if this member is in the list of member names when * the member names list contains exclusion listings */ if((onlyExclusionlistings && c_iterResolve(memberNames, idl_stacDefNamesAreEqual, memberName) == NULL) || memberNamesSize == 0) { stacCanBeApplied = idl_stacDefCanStacBeAppliedToMember(c_specifier(member)->type); if(stacCanBeApplied) { /* this is a bounded string, so we want to convert */ c_iterInsert(boundedStringToBeConverted, member); } } } } else { for(j = 0; j < memberNamesSize; j++) { memberName = c_iterTakeFirst(memberNames); if(memberName[0] == '!') { printf("FATAL ERROR | #pragma stac: Illegal syntax combination detected. " "The pragma stac definition for structure %s contains both normal " "member listings (without the '!' character in front of them) as " "well as exclusion member listings (with the '!' character in front " "of them). This has no relevant meaning, please see the deployment manual " "for information on usage of pragma stac.\n" "Ignoring the following member defintion: '%s'\n", c_metaScopedName(c_metaObject(structure)), memberName); exit(-2); } memberIndex = idl_stacDefFindMemberIndexByName( structure->members, memberName); if(memberIndex == -1) { printf("FATAL ERROR | #pragma stac: Unable to locate member %s " "within structure %s.\n", memberName, c_metaScopedName(c_metaObject(structure))); exit(-2); } member = structure->members[memberIndex]; /* Verify the member is a bounded string as required */ stacCanBeApplied = idl_stacDefCanStacBeAppliedToMember(c_specifier(member)->type); if(!stacCanBeApplied) { printf("FATAL ERROR | #pragma stac: Member %s within structure " "%s is not a bounded string (note: may be embedded within an array or sequence) as required.\n", memberName, c_metaScopedName(c_metaObject(structure))); assert(0); exit(-2); } /* this is a bounded string, so we want to convert */ c_iterInsert(boundedStringToBeConverted, member); } } while(c_iterLength(boundedStringToBeConverted) > 0) { member = c_iterTakeFirst(boundedStringToBeConverted); memberIndex = idl_stacDefFindMemberIndexByName( structure->members, c_specifier(member)->name); assert(memberIndex != -1); newMember = c_metaDefine(c_metaObject(structure), M_MEMBER); base = c_getBase(member); c_specifier(newMember)->name = c_stringNew(base, c_specifier(member)->name); c_specifier(newMember)->type = idl_stacDefConvertStacApprovedMember(structure, c_specifier(member)->type); if(!c_specifier(newMember)->type) { printf("FATAL ERROR | #pragma stac: An internal error occured. Member %s within structure " "%s failed to convert from a bounded string to a character array.\n", c_specifier(newMember)->name, c_metaScopedName(c_metaObject(structure))); assert(0); exit(-2); } structure->members[memberIndex] = newMember; c_iterInsert(replaceData->replacedMembers, member); replacedIndex = os_malloc(sizeof(os_uint32)); *replacedIndex = (os_uint32)memberIndex; c_iterInsert(replaceData->replacedIndexes, replacedIndex); } c_iterInsert(replaceInfo, replaceData); } } return replaceInfo; }
/* * Check if each usage of a char array as a key has a corresponding * "#pragma cats" declaration. */ static c_bool idl_checkCatsUsage( c_base base, const char* filename) { char errorBuffer [IDL_MAX_ERRORSIZE]; idl_keyDef keyDef = idl_keyDefDefGet(); c_long keyMapIdx; idl_keyMap keyMap; c_type type; c_structure structure; c_iter keysList; os_uint32 keysListSize; os_uint32 keyIdx; c_char* keyName; os_uint32 i; c_iter keyNameList; os_uint32 keyNameListSize; c_structure tmpStructure; c_specifier sp; c_type subType; c_string typeName; c_type spType; if (keyDef != NULL) { /* check all key definition list elements */ for (keyMapIdx = 0; keyMapIdx < c_iterLength(keyDef->keyList); keyMapIdx++) { keyMap = c_iterObject(keyDef->keyList, keyMapIdx); /* if a keylist is defined for the type */ if (keyMap->keyList && strlen(keyMap->keyList) > 0) { /* find meteobject for the type */ type = c_type(c_metaResolveType(keyMap->scope, keyMap->typeName)); if (!type) { snprintf(errorBuffer, IDL_MAX_ERRORSIZE-1, errorText[idl_UndeclaredIdentifier], keyMap->typeName); idl_printError(filename, errorBuffer); return OS_FALSE; } /* type can be a typedef. Determine the actual type. */ type = c_typeActualType(type); /* type should be a structure */ if (c_baseObject(type)->kind != M_STRUCTURE) { snprintf(errorBuffer, IDL_MAX_ERRORSIZE-1, errorText[idl_IllegalKeyFields]); idl_printError(filename, errorBuffer); return OS_FALSE; } structure = c_structure(type); /* for each key in keyList, check if type is a char array */ keysList = c_splitString(keyMap->keyList, ","); keysListSize = c_iterLength(keysList); for(keyIdx = 0; keyIdx < keysListSize; keyIdx++) { keyName = c_iterTakeFirst(keysList); /* We might be dealing with a field of a field definition in * the keylist, so let's split this up */ keyNameList = c_splitString(keyName, "."); keyNameListSize = c_iterLength(keyNameList); tmpStructure = structure; for(i = 0; i < keyNameListSize; i++) { keyName = c_iterTakeFirst(keyNameList); /* Now get the actual member defined by the name */ sp = c_specifier(c_metaFindByName( c_metaObject(tmpStructure), keyName, CQ_FIXEDSCOPE | CQ_MEMBER | CQ_CASEINSENSITIVE)); if(sp) { spType = c_typeActualType(sp->type); /* If the member is a structure, we need to * recurse deeper. */ if(c_baseObject(spType)->kind == M_STRUCTURE) { tmpStructure = c_structure(spType); } /* If the member is a collection then we need to * ensure it is not a character array, but if it * is we need to ensure a corresponding CATS pragma * can be located */ else if(c_baseObject(spType)->kind == M_COLLECTION && c_collectionType(spType)->kind == C_ARRAY) { subType = c_typeActualType(c_collectionType(spType)->subType); if(c_baseObject(subType)->kind == M_PRIMITIVE && c_primitive(subType)->kind == P_CHAR) { typeName = c_metaName(c_metaObject(tmpStructure)); /* check if there is corresponding catsDef */ if (!idl_isCatsDefFor(c_metaObject(tmpStructure)->definedIn, typeName, keyName)) { snprintf( errorBuffer, IDL_MAX_ERRORSIZE-1, errorText[idl_NoCorrespondingCats], c_metaObject(structure)->name, keyName); idl_printError(filename, errorBuffer); return OS_FALSE; } c_free(typeName); } } } } } } } } return OS_TRUE; }